Claude Code

Permission rules trong Claude Code: allow, ask, deny và thứ tự đánh giá

Tóm tắt

Permission rules cho Claude Code biết việc gì làm không cần hỏi, phải hỏi hay bị cấm. Deny luôn thắng ask, ask thắng allow ở mọi cấp; rule Bash không phải hàng rào tuyệt đối nên cần sandbox cho việc phải chặn chắc chắn.

Bấm "Yes" cho từng lệnh npm test thì mệt, còn bật chế độ bỏ qua mọi quyền thì đáng sợ. Giải pháp ở giữa là permission rules: viết sẵn quy tắc cho những gì Claude Code được làm không cần hỏi, phải hỏi, hoặc tuyệt đối cấm. Rules có thể commit vào repo cho cả team dùng chung, và mỗi người vẫn tuỳ chỉnh thêm cho riêng mình. Hiểu đúng thứ tự đánh giá là điều quyết định quy tắc của bạn có thật sự chặn được hay không.

Các permission mode

ModeHành vi
default (Manual)Hỏi khi dùng mỗi tool lần đầu
acceptEditsTự chấp nhận sửa file và lệnh filesystem phổ biến (mkdir, mv, cp…) trong thư mục làm việc
planChỉ đọc và khám phá, không sửa mã nguồn
autoKhông hỏi thường xuyên; classifier nền kiểm tra hành động rủi ro trước khi chạy
dontAskTự từ chối mọi thứ lẽ ra phải hỏi; chỉ chạy những gì đã được allow sẵn
bypassPermissionsBỏ qua prompt (trừ vài hành động không mode nào tự duyệt); chỉ dùng trong container/VM cô lập

Cú pháp rule

{
  "permissions": {
    "allow": ["Bash(npm run *)", "Bash(git commit *)", "WebFetch(domain:docs.python.org)"],
    "ask":   ["Bash(git push *)"],
    "deny":  ["Read(./.env)", "Read(./secrets/**)", "Bash(curl *)", "mcp__prod-db__*"]
  }
}
  • Bash: * khớp mọi đoạn văn bản kể cả dấu cách. Đặt * sau subcommand: Bash(git log *) chỉ cho phép git log, còn Bash(git *) cho phép mọi lệnh git.
  • Read/Edit: theo đường dẫn kiểu gitignore. File .claudeignore không có tác dụng; hãy chuyển sang rule Read deny.
  • WebFetch: domain:example.com không bao gồm subdomain; thêm domain:*.example.com nếu cần.
  • MCP: mcp__server__* cho cả server, mcp__server__tool cho một tool.

Thứ tự đánh giá: deny → ask → allow

Đây là điểm hay bị hiểu sai nhất. Theo tài liệu, rule được xét theo thứ tự deny, rồi ask, rồi allow; khớp đầu tiên quyết định, độ cụ thể của rule không làm đổi thứ tự.

  • Deny Bash(aws *) chặn luôn aws s3 ls dù bạn có allow Bash(aws s3 ls). Allow không thể "khoét ngoại lệ" trong deny.
  • Deny ở bất kỳ cấp nào (user, project, managed) đều thắng allow ở cấp khác.
  • Managed settings của tổ chức cao nhất: không cấp nào, kể cả tham số dòng lệnh, ghi đè được.
  • Hook PreToolUse trả "allow" cũng không vượt qua được deny hay ask.

Rủi ro và lưu ý

  • Rule Bash không phải hàng rào tuyệt đối: deny Bash(git push *) không khớp git -C . push; deny theo tên lệnh không khớp khi gọi qua đường dẫn hay trong sh -c. Việc cần chặn chắc chắn, kết hợp với sandbox.
  • Deny Read không chặn mọi đường đọc: một script Python tự mở file sẽ không bị rule chặn. Bảo vệ ở mức hệ điều hành cần sandbox.
  • Allow quá rộng: Bash(python *) gần như cho phép mọi thứ, vì Python chạy được code tuỳ ý.
  • bypassPermissions trên máy thật: chỉ dùng trong môi trường cô lập; tổ chức có thể tắt bằng disableBypassPermissionsMode.

Áp dụng thế nào?

  • Dev: Allow các lệnh test/lint/build bạn chạy hằng ngày; deny đọc .env và thư mục secrets ngay từ đầu.
  • Tech Lead: Commit .claude/settings.json với bộ allow/deny chung của team; để git push và lệnh deploy ở nhóm ask.
  • PM/Admin: Dùng managed settings cho rule bắt buộc toàn công ty (cấm đọc thư mục khách hàng, tắt bypass), vì không ai ghi đè được.

Nguồn & tham khảo

  1. Configure permissions — Claude Code Docs