DeepDojo.AI发布 2026-11-12English

Claude Code 明明允许了,为什么还拒绝?

Claude CodeAI 编程

你想让 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 statusdeny、ask 均未匹配,allow 命中直接执行
git push origin maindeny 未匹配,ask 命中请求确认
pnpm vitest run三类规则均未匹配交给 default 模式,这类命令请求确认
rm -rf builddeny 首先命中拒绝,不提供本次确认放行

权限规则依次检查 deny、ask、allow 并在均未命中时交给默认模式

先把常用命令代入规则算一遍。上表允许 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 查来源和合并结果。接着准备三种无害样本:应允许、应询问、应拒绝,每种至少一个。

  1. 跑已允许的检查命令,看是否直接执行。
  2. 给无害命令临时加 ask,看到完整确认提示后就取消。
  3. 准备一个没有秘密的测试文件,看读取时是否命中路径拒绝。
  4. 用 && 或管道组合命令,核对每一段的结果。
  5. 再用 /doctor 查拼写、工具名和 Settings 语法。

无害样本足够检验这套匹配关系。真实秘密、生产数据库和不可恢复文件都留在范围外。结果不对,就查来源、命令字符串、模式和资源限制。先查清原因,再决定是否需要调整授权。

回到开头的 aws s3 ls:把它代入顺序,第一步就撞上了 Bash(aws *)。先算再测,权限结果就不再靠猜。