Claude Code 权限系统:为什么关键决策不交给大模型?

Raed's blog 2026-08-12T12:28:07.621826

Claude Code 的权限控制几乎完全由确定性代码实现,而非大模型判断。本文解析其决策流程、不可绕过的安全检查,以及唯一引入 LLM 的 auto mode 如何兜底。

Claude Code 源码泄露后,人们发现它的绝大多数环节都依赖大语言模型(LLM)调用:工具选择、代码生成、记忆提取、上下文管理。但有一个子系统几乎完全不用 LLM——权限控制

一个工具调用该放行、该拒绝、还是交给用户确认,这套判断逻辑完全由确定性的代码完成:规则匹配、glob 通配符、正则校验、写死的路径检查。在真正要紧的环节,Anthropic 一直没有信任模型,直到最近才有所改变。

权限决策:一条纯代码的优先级链

每个工具调用在执行前都会经过 hasPermissionsToUseToolInner 方法。判断逻辑是一条优先级链:

  1. 检查工具级别的 deny/ask 规则(按设置层级做 glob 通配符匹配)
  2. 运行工具自身的 checkPermissions() 方法(每个工具的独立代码,不是 LLM)
  3. 检查无法绕过(bypass-immune)的安全条件,如敏感路径、内容相关规则
  4. 如果启用了 bypassPermissions 模式,且以上规则都没有命中,就放行
  5. 检查工具级别的 allow 规则
  6. 默认行为:询问用户

这些全是纯代码。没有模型推理,没有分类,没有概率分布。一个工具调用要么命中规则,要么不命中。

仅仅 bash 工具,其 checkPermissions() 这一步就有 6 个子阶段:复合命令拆分、剥离安全包装器、按子命令做规则匹配、23 个独立安全校验器、路径约束检查,以及 sed/模式校验。

bash 工具的六层防护

这些安全校验器值得仔细看看。

系统会预先为每条命令计算四种不同的视图:

这样每个校验器都能直接选用合适的视图,无需重新解析。校验器覆盖的范围包括:命令替换模式、Zsh 特有的危险内置命令、IFS 注入、花括号展开、Unicode 空白字符绕过等。

这个权限系统更像是传统的 RBAC(基于角色的访问控制)层,而不是一段 LLM 提示词。

不可绕过的检查

有些检查无论处于哪种权限模式都无法绕过:对 .git/.claude/.vscode/ 目录以及 shell 配置文件的写入,永远都会提示用户。这是硬编码的。

同理,需要用户交互的工具和基于内容设定的询问规则也不例外。它们在管线中会先于 bypass 检查执行,因此不存在任何模式、标志或设置能够跳过它们。执行顺序本身就构成了保障。

从控制流上就决定了 bypass 不可能跑到免疫检查之前。这是靠代码流程强制的,而不是靠一套策略规定。

auto mode:唯一让 LLM 参与决策的场景

整个权限体系里,只有一个环节会让大语言模型参与决策,那就是 auto mode。这个功能由 TRANSCRIPT_CLASSIFIER 特性开关控制。

Anthropic 在发布时就公开推出了 auto mode,并明确表示它“能降低风险,但不能消除风险”。确定性的代码管线仍然会先执行。

分类器只作为兜底方案运行。只要基于代码的管线能得出允许或拒绝的结论,分类器就不会被调用。只有当管线走到“询问”这一步、且系统处于 auto mode 而非向人工弹窗询问时,分类器才会被激活。

任何异常情况下的回退动作,永远是“询问真人”——分类器接口出错的结果是拒绝。连续三次拒绝会触发回退到人工询问;累计二十次拒绝同样会回退到人工询问并重置计数器。如果对话记录太长,超出分类器的上下文窗口,也会回退到人工询问。系统在任何出错情况下都不会默认放行。

设计哲学

Anthropic 的这套设计透露出一个清晰的理念:权限是安全边界,不是推理题目。模型擅长理解意图、生成内容,但在“该不该执行这条命令”这类问题上,确定性规则永远比概率判断更可靠。把权限决策交给 LLM,等于把安全边界变成了一个概率事件——这在任何一个严肃的工具链里都是不可接受的。

对开发者而言,这意味着在使用 Claude Code 时,权限配置是可预期、可审计的。你可以通过规则文件精确控制哪些命令能跑、哪些路径不能碰,而不用担心模型“自作主张”。auto mode 的引入则是在不牺牲安全性的前提下,减少交互打断的频率——它所做的只是替你点击“允许”,而不是替你判断“是否应该允许”。

关键要点

查看原文