第17章:权限系统——信任的层级
核心问题:该信任 AI 多少?
如果 AI 可以不受限制地执行任何操作,会发生什么?
- - 它可能误删重要文件
- - 它可能执行有害的命令
- - 它可能泄露敏感信息
- - 它可能做出你不想要的修改
但如果每一步都需要用户确认,AI 就变成了一个不停问"可以吗?可以吗?"的烦人助手。
Claude Code 的权限系统就是在安全和效率之间找平衡。
三种权限模式
Claude Code 提供了三种权限模式,让用户自己选择信任级别:
1. Default 模式(默认)
读文件?→ 自动允许
搜索代码?→ 自动允许
运行 ls?→ 自动允许
修改文件?→ 询问用户
运行 git push?→ 询问用户
删除文件?→ 询问用户
大部分只读操作自动允许,写操作需要确认。适合日常使用。
2. Auto 模式
读文件?→ 自动允许
搜索代码?→ 自动允许
运行 ls?→ 自动允许
修改文件?→ AI 分类器判断是否安全
运行 git push?→ 询问用户(高风险操作)
删除文件?→ 询问用户(高风险操作)
中等风险操作由 AI 分类器自动判断。只有高风险操作才询问用户。更流畅,但需要信任分类器。
3. Bypass 模式
所有操作 → 自动允许
完全信任 AI,不做任何确认。只适合你完全了解 AI 在做什么的情况,比如运行你预先审查过的自动化脚本。
权限检查的流程
每次 AI 想使用一个工具时,都要经过层层检查:
AI 请求使用工具
│
▼
1. 输入验证(Zod Schema)
→ 参数格式正确吗?
│
▼
2. 工具自身的 checkPermissions()
→ 工具认为这个操作安全吗?
│
▼
3. 前置钩子(Pre-tool hooks)
→ 用户定义的脚本允许吗?
│
▼
4. 规则匹配
→ 匹配 alwaysAllow / alwaysDeny / alwaysAsk 规则
│
▼
5. Auto 模式分类器(如果启用)
→ AI 安全分类器怎么说?
│
▼
6. 用户确认(如果需要)
→ 弹出对话框询问用户
│
▼
允许或拒绝
规则匹配详解
权限规则是 Claude Code 最灵活的安全机制。规则的格式是:
工具名(参数模式)
例如:
Bash(git *) 匹配:所有 git 命令
Bash(npm test *) 匹配:npm test 及其参数
FileRead(*.ts) 匹配:读取所有 TypeScript 文件
FileWrite(src/*) 匹配:写入 src/ 目录下的文件
规则来源有优先级,从高到低:
1. CLI 参数 claude --deny "Bash(rm *)"
2. 管理员策略 managed-settings.json(IT 部门配置)
3. 用户设置 ~/.claude/settings.json
4. 项目设置 .claude/settings.json
5. 会话级别 用户在对话中临时授权
高优先级的规则覆盖低优先级。管理员可以强制禁止某些操作,用户无法覆盖。
权限决策的三种结果
type PermissionDecision = {
behavior: "allow" | "deny" | "ask"
reason?: string
updatedInput?: any // 可能修改工具输入
}
- - allow:直接执行,不询问用户
- - deny:拒绝执行,告诉 AI 被拒绝了
- - ask:弹出对话框,等待用户确认
拒绝后会发生什么?
当操作被拒绝时,系统会生成一个"合成的"工具结果:
{
type: "tool_result",
tool_use_id: "tool_1",
content: "权限被拒绝:不允许执行 'rm -rf node_modules'。请尝试其他方法。",
is_error: true,
}
AI 收到这个结果后,会理解它被拒绝了,然后尝试其他方式来完成任务。
权限对话框
当需要用户确认时,Claude Code 显示一个权限请求界面:
┌─ Permission Request ──────────────────────────────┐
│ │
│ Claude wants to execute: │
│ │
│ $ npm install express │
│ │
│ ┌─────────┐ ┌──────┐ ┌──────────────┐ │
│ │ Allow │ │ Deny │ │ Allow Always │ │
│ └─────────┘ └──────┘ └──────────────┘ │
│ │
│ Suggestions: │
│ • Allow all npm commands: Bash(npm *) │
│ │
└─────────────────────────────────────────────────────┘
注意底部的"建议"——系统会智能地建议权限规则。如果你经常允许 npm 命令,它会建议你创建一个 Bash(npm *) 的永久允许规则。
用户的选择有三种:
- - Allow:只允许这一次
- - Deny:拒绝这一次
- - Allow Always:创建永久允许规则
Auto 模式分类器
Auto 模式使用 AI 分类器来自动判断操作是否安全:
async function classifyToolUse(tool, input, context) {
// 构建分类提示
const classifierPrompt = `
用户的意图是:${context.userIntent}
AI 想执行的操作是:${tool.name}(${JSON.stringify(input)})
这个操作安全吗?考虑:
- 操作是否符合用户的意图
- 操作是否有不可逆的副作用
- 操作是否涉及敏感数据
`
const result = await classifier.evaluate(classifierPrompt)
if (result.confidence > 0.9) {
return { behavior: "allow" } // 高置信度,自动允许
} else {
return { behavior: "ask" } // 不确定,还是问用户
}
}
分类器异步运行——它和其他检查并行执行,不增加额外的等待时间。
多层防御
Claude Code 的安全设计遵循纵深防御原则——不依赖单一的安全措施,而是层层设防:
第一层:AI 的自我约束
系统提示词告诉 AI 不要做危险操作
第二层:工具级别的验证
每个工具自己检查输入是否合理
第三层:权限规则
用户定义的 allow/deny/ask 规则
第四层:分类器
AI 安全分类器评估操作风险
第五层:用户确认
最后的把关——用户看到操作并确认
第六层:沙箱
即使前面都通过了,命令仍在受限环境中执行
即使某一层被绕过,其他层仍然可以拦截危险操作。这就像银行的安全系统——有摄像头、保险柜、警报器、保安,每一层都是一道防线。
本章小结
- - 权限系统平衡安全与效率,提供三种模式(Default/Auto/Bypass)
- - 权限检查有六个步骤:验证 → 工具检查 → 钩子 → 规则 → 分类器 → 用户确认
- - 规则支持通配符,按优先级从 CLI 参数到会话级别
- - 拒绝操作时,AI 会收到错误信息并尝试其他方式
- - 权限对话框提供智能建议
- - 纵深防御:六层安全机制,不依赖单一防线
思考题
- 1. 为什么管理员策略的优先级高于用户设置?在什么场景下这很重要?
- 2. Auto 模式分类器的置信度阈值设为 0.9,如果改成 0.5 会怎样?0.99 呢?
- 3. 纵深防御在现实生活中还有什么例子?
现实世界的权限系统
Claude Code 的权限系统并不是凭空发明的——它借鉴了很多现实世界的安全模型。
手机的权限系统
你的手机 App 在使用摄像头、位置、通讯录之前,都会弹出权限请求。这和 Claude Code 的权限对话框几乎一模一样:
手机:
"相机 App 想要使用你的位置"
[允许一次] [使用 App 时允许] [不允许]
Claude Code:
"Claude 想要执行 git push"
[允许] [允许所有 git 命令] [拒绝]
两者都遵循同样的原则:在操作发生前征得用户同意,并提供不同粒度的授权选择。
公司的权限体系
企业中的权限管理也类似:
CEO(最高权限)
→ 可以做任何决策
部门经理
→ 可以管理部门内的事务
→ 不能修改其他部门的预算
普通员工
→ 可以执行日常工作
→ 需要审批才能报销大额费用
实习生
→ 大部分操作需要导师确认
Claude Code 的三种权限模式也是类似的信任层级。
下一章,我们将深入安全防线的技术细节。
本书由 everettjf 使用 Claude Code 分析泄露源码编写 | 保留出处即可自由转载