DeepDojo.AI发布 2026-11-12English
Claude Code 明明允许了,为什么还拒绝?
你想让 Claude Code 能直接列出 S3 桶,于是在权限里加了一条 allow: Bash(aws s3 ls)。可它一跑这条命令,还是被拒绝了。翻遍配置,才在另一份文件里看到一条更早写下的 deny: Bash(aws *)。
很多人会以为,写得更具体的规则应该更优先,就像 CSS 里选择器越具体越优先那样。Claude Code 的权限规则不是这样算的。它先看规则属于哪一类,再看有没有命中:
- 先查
deny,命中就拒绝; - 再查
ask,命中就请求确认; - 最后查
allow,命中才直接执行; - 三类都没命中,交给当前权限模式决定。
再加上规则可以来自用户、项目、本地和组织好几份配置,还会合并在一起,单看一份 JSON 就更难判断结果。办法是把常用命令逐条代入这个顺序算一遍,再用 /permissions 看合并后的规则和来源,最后拿无害样本实际跑一次,确认允许、询问、拒绝三种结果都和预期一致。
01 按操作的实际影响设权限
按操作的实际影响设置权限。已经核对、范围清楚的低风险操作可以直接放行;合理但会改变状态的操作保留确认;明确禁止的动作写入拒绝规则。
检查时要看涉及的文件、脚本、依赖、网络和外部系统。命令名称相同,背后的行为也可能变化。
权限规则写在 Settings 的 permissions 对象中:
{
"permissions": {
"allow": [],
"ask": [],
"deny": []
}
}三类规则分别代表:
| 结果 | 行为 | 适合场景 |
|---|---|---|
allow | 匹配后直接执行,不再弹出确认 | 高频、低风险、范围清楚的操作 |
ask | 每次匹配时都请求你确认 | 合法但会改变环境或外部状态的操作 |
deny | 直接阻止,不能通过本次确认放行 | 密钥、生产操作和明确禁区 |
02 规则按固定顺序检查
Claude Code 按固定顺序检查:
deny
↓ 未匹配
ask
↓ 未匹配
allow
↓ 未匹配
使用当前权限模式的默认行为规则等级优先于具体程度。命中 deny 就拒绝;没有命中,再依次检查 ask 和 allow。更具体的 allow 不能越过已命中的 deny 或 ask。
Claude Code 的权限文档原文就是这样写的:规则按 deny、ask、allow 的顺序评估,按这个顺序第一个命中的规则决定结果,规则写得多具体不会改变顺序。官方举的正是开头这个例子:宽泛的 Bash(aws *) 拒绝规则会挡住所有匹配的调用,包括同样命中 Bash(aws s3 ls) 允许规则的调用,允许规则没法在拒绝规则里挖出例外。
代入 aws s3 ls,第一条就命中了,所以仍被拒绝。要只放行列表查询,就不能保留这条整类拒绝。调整为只允许该命令,其他 AWS 动作按默认方式询问。若要求其余操作直接失败,再用 Hook、沙箱或凭证策略建立更强限制。

03 把常用命令代入算一遍
假设当前模式为 default,规则如下:
deny: [Bash(rm *)]
ask: [Bash(git push *)]
allow: [Bash(git status), Bash(pnpm test *)]四条命令的匹配结果分别如下:
| 命令 | 匹配过程 | 结果 |
|---|---|---|
git status | deny、ask 均未匹配,allow 命中 | 直接执行 |
git push origin main | deny 未匹配,ask 命中 | 请求确认 |
pnpm vitest run | 三类规则均未匹配 | 交给 default 模式,这类命令请求确认 |
rm -rf build | deny 首先命中 | 拒绝,不提供本次确认放行 |

先把常用命令代入规则算一遍。上表允许 pnpm test *,实际跑的却是 pnpm vitest run。用途相似,字符串仍不同,要按实际调用检查。通配符、空格和复合命令怎样影响匹配范围,见Claude Code 权限白名单的五个常见漏洞。
04 多份配置里的规则会合并
权限可以来自用户、项目、本地和 Managed Settings。allow、ask、deny 会跨范围合并,项目中的配置文件不会整体替换其他来源。
拒绝可能在另一份文件里。用户的 deny 能挡住项目 allow,项目的拒绝也能挡住用户放行,本地加 allow 仍无法解除它。组织还可以用 Managed Settings 建立个人和项目都不能绕过的限制。列表为什么会合并,和标量字段的覆盖有什么不同,在Claude Code 多份配置冲突时,哪个生效里有完整推算。
一个常见的情形:你在权限弹窗里选了“是,不再询问”,下次还是被问。设置文档解释了原因:这个选择会把一条 allow 规则存进你的本地文件,而本地的 allow 压不过项目或托管文件里的 ask 规则。
项目里的 allow 会增加仓库可用的能力,要等你信任工作区后才应用。deny 和 ask 收紧能力,不需要同样的信任步骤。权限文档的说法是:项目 .claude/settings.json 里的 permissions.allow 会授予能力,所以只有接受了该文件夹的工作区信任对话框后才会应用;deny 和 ask 只做限制,不受影响。
打开 /permissions,看合并后的规则和各自来源。单个 JSON 只能告诉你其中一部分。
05 用无害样本验证三种结果
写完配置,打开 /permissions 查来源和合并结果。接着准备三种无害样本:应允许、应询问、应拒绝,每种至少一个。
- 跑已允许的检查命令,看是否直接执行。
- 给无害命令临时加
ask,看到完整确认提示后就取消。 - 准备一个没有秘密的测试文件,看读取时是否命中路径拒绝。
- 用
&&或管道组合命令,核对每一段的结果。 - 再用
/doctor查拼写、工具名和 Settings 语法。
无害样本足够检验这套匹配关系。真实秘密、生产数据库和不可恢复文件都留在范围外。结果不对,就查来源、命令字符串、模式和资源限制。先查清原因,再决定是否需要调整授权。
回到开头的 aws s3 ls:把它代入顺序,第一步就撞上了 Bash(aws *)。先算再测,权限结果就不再靠猜。