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
| Mode | Hành vi |
|---|---|
default (Manual) | Hỏi khi dùng mỗi tool lần đầu |
acceptEdits | Tự 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 |
plan | Chỉ đọc và khám phá, không sửa mã nguồn |
auto | Không hỏi thường xuyên; classifier nền kiểm tra hành động rủi ro trước khi chạy |
dontAsk | Tự từ chối mọi thứ lẽ ra phải hỏi; chỉ chạy những gì đã được allow sẵn |
bypassPermissions | Bỏ 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ònBash(git *)cho phép mọi lệnh git. - Read/Edit: theo đường dẫn kiểu gitignore. File
.claudeignorekhông có tác dụng; hãy chuyển sang ruleReaddeny. - WebFetch:
domain:example.comkhông bao gồm subdomain; thêmdomain:*.example.comnếu cần. - MCP:
mcp__server__*cho cả server,mcp__server__toolcho 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ônaws s3 lsdù bạn có allowBash(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ớpgit -C . push; deny theo tên lệnh không khớp khi gọi qua đường dẫn hay trongsh -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
.envvà thư mục secrets ngay từ đầu. - Tech Lead: Commit
.claude/settings.jsonvới bộ allow/deny chung của team; đểgit pushvà 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
- Configure permissions — Claude Code Docs