claude-code/docs/agentic-design/04-permission-system.md
Claude 808d5a61b3
docs: Add comprehensive agentic design documentation (2.5-hour learning session)
新增 docs/agentic-design/ 教育文档,全中文+英文技术术语,覆盖:

- README.md: 总索引,整体架构图,阅读指南
- 00-codebase-tour.md: 代码库全景,递归覆盖所有重要目录
- 01-agent-loop.md: Query loop 状态机,token budget,compaction
- 02-tool-system.md: Tool interface,权限检查,并发执行,sibling abort
- 03-multi-agent-coordination.md: Agent 类型,coordinator 4 阶段,XML 通信
- 04-permission-system.md: Permission mode,rule system,YOLO 分类器,denial tracking
- 05-context-and-memory.md: System prompt 分层,compaction,auto-dream 后台巩固
- 06-feature-gating.md: Compile-time feature,runtime flags,Bun dead-code elimination

总计 ~2.5 小时阅读,每篇含 Design Decision 专栏和常见误解纠正

https://claude.ai/code/session_017Vdqo9B8eTXiEDcqnv9DxM
2026-03-31 16:07:29 +00:00

317 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Permission 系统Agent 的沙箱
## 为什么需要权限管控?
想象 Claude 可以执行任意 bash 命令。用户说"帮我看看网站"Claude 可能:
- 合法地执行 `curl https://example.com`
- 也可能执行 `rm -rf /` ← 灾难
**权限系统的目标**
1. 阻止意外的危险操作
2. 提示用户"你确定吗?"
3. 在保留便利的同时维护安全
Claude Code 的 permission 系统是一个**多层防线**。
---
## 核心概念Permission Mode
系统支持多种权限模式,用户可以选择:
| Mode | 特点 | 场景 |
|------|------|------|
| `default` | 每次都问用户 | 不信任 agent想完全控制 |
| `auto` | ML 分类器自动审批 | 信任 agent想要流畅体验 |
| `acceptEdits` | 自动接受文件编辑(但仍然问危险操作) | 开发工作流(改代码 OK执行脚本要问 |
| `bypass` | 完全自动,不问(谨慎使用)| 内部测试、自动化流程 |
| `dontAsk` (aka `yolo`) | 拒绝所有非低风险操作 | 沙箱环境,最安全 |
| `plan` | 特殊模式:进入计划编辑阶段 | 用户审核计划后再执行 |
用户在启动时选择(环境变量或配置文件):
```bash
# 每次都问
claude-code --permission-mode default
# 自动审批
claude-code --permission-mode auto
# 最安全
claude-code --permission-mode dontAsk
```
相关文件:`utils/permissions/PermissionMode.ts`
---
## Permission 决策 Pipeline
当 agent 试图执行一个 tool 时,系统会问:"我应该允许吗?"
```
Agent 调用: BashTool { command: "npm test" }
├─ [1] Mode 检查
│ if mode == "bypass" → ✓ 允许,返回
│ if mode == "dontAsk" → ✗ 拒绝 Bash返回
├─ [2] 规则匹配
│ 检查用户配置的规则列表
│ 如: "Bash(git *)" → 允许 git 命令
│ "Bash(npm *)" → 允许 npm 命令
│ "Bash(*)" → 允许任意 bash (太宽)
│ 我们的命令 "npm test" 匹配 "npm *" → ✓
├─ [3] 风险分类
│ rule match → LOW 风险
│ 如果没匹配到规则,分类器决定风险等级
├─ [4] YOLO 分类器
│ 对于 MEDIUM 风险的操作:
│ - 如果被模型认为"明显安全",自动批准
│ - 否则需要用户确认
└─ [5] 最后手段:提示用户
用户选择: ✓ 允许 / ✗ 拒绝 / ⚠️ 改规则
```
相关文件:`utils/permissions/permissions.ts` (52 KB核心决策逻辑)
---
## 规则系统
用户可以配置规则,告诉 agent 什么是自动允许的。规则语法:
```
Bash(git *) # 允许任何 git 命令
Bash(npm install) # 只允许 npm install不允许 npm test
FileEdit(src/*.ts) # 允许编辑 src/ 下的 .ts 文件
FileRead(/*) # 允许读任何文件
```
规则支持 **glob 模式**`*` 通配符)。
### 规则分层
规则可以来自多个地方(优先级从高到低):
1. **CLI 参数**`--approve-file "FileEdit(src/*.ts)"`
2. **项目配置**`.claude/settings.json` 中的 `approvals`
3. **用户设置**`~/.claude/settings.json`
4. **系统默认**Claude Code 内置的基础规则
下层规则会被上层规则覆盖。
相关文件:`utils/permissions/permissionRuleParser.ts`, `utils/permissions/permissionsLoader.ts`
---
## YOLO 分类器ML 自动审批
对于**规则未覆盖的操作**system 用 YOLO 分类器("You Only Live Once")决定:
```
输入:
tool_name: "BashTool"
command: "npm test"
context: 当前任务是"修复 bug"
分类器说: "这个操作很像是开发者会做的正常事,批准"
结论: 自动允许,不问用户
```
分类器基于 ML 训练,考虑:
- Tool 类型BashTool 比 FileReadTool 高风险)
- 具体命令(`npm test``rm -rf` 安全)
- 当前上下文("修复 bug" vs "浏览网页"
相关文件:`utils/permissions/yoloClassifier.ts` (52 KB)
### 分类器的风险等级
```
LOW
→ 自动允许(不问用户)
→ 例FileReadTool, GlobTool, WebFetchTool
MEDIUM
→ 取决于 modeauto mode 用分类器default mode 问用户)
→ 例FileEditTool, BashTool (git 命令)
HIGH
→ 一般不自动允许(需要用户确认)
→ 例BashTool (rm -rf), FileWriteTool (覆盖重要文件)
```
---
## Denial TrackingCircuit Breaker
如果用户连续拒绝 agent 多次system 会自动**降级权限模式**
```
用户拒绝:
1. "BashTool" ← Denial #1
2. "FileEditTool" ← Denial #2
3. "BashTool" ← Denial #3
连续 3 次拒绝触发!
系统切换到 "default" mode后续所有操作都要问用户
这样防止:
- Agent 持续尝试被拒的操作
- 用户一直看到提示烦不胜烦
```
同时,系统还追踪**总拒绝数**
```
同一 session 中总共拒绝了 20 次
系统记录日志:"这个 session 决策质量差,建议用户审视任务"
```
相关文件:`utils/permissions/denialTracking.ts`
---
## 路径安全:防止路径遍历攻击
即使规则写得再好,攻击者也可能用**特殊编码**绕过:
```
规则: FileEdit(src/*.ts) ← 只允许 src/ 目录
攻击尝试:
path: "src/../../../etc/passwd" ← 试图逃逸
path: "src%2f..%2f..%2fetc%2fpasswd" ← URL 编码
path: "src/\u202e../../../etc/passwd" ← Unicode 隐藏字符
```
系统有多层防御:
1. **Path Normalization**
```
"src/../../../etc/passwd"
→ 规范化
→ "/etc/passwd"
→ 检查是否在 src/ 内? 否 → 拒绝
```
2. **URL Decoding**
```
"src%2f..%2f..%2fetc"
→ 解码
→ "src/../../etc"
→ 规范化 → 拒绝
```
3. **Unicode Normalization**
```
Unicode 隐藏字符也会被清理
```
相关文件:`utils/permissions/pathValidation.ts` (62 KB)
---
## Protected Files黑名单
某些文件**永远不会被自动编辑**
```
.gitconfig ← Git 配置,修改可能破坏工作流
.bashrc, .zshrc ← Shell 配置,修改可能卡住终端
.mcp.json ← MCP 配置,影响工具可用性
.claude.json ← Claude Code 自己的配置
```
这些文件即使通过了权限检查,也会再次提示用户确认。
---
## Design Decision 专栏
### 为什么需要 ML 分类器?
如果只用规则:
```
允许所有 Bash 命令?
→ 太宽,不安全(用户可能 rm -rf
只允许 git/npm 命令?
→ 太窄不便利sudo docker pull 被拒)
```
ML 分类器的优势:
```
可以说"这个命令看起来是在开发工作流的一部分,
而不是破坏性操作,所以允许"
如果出错classify 有假阴性),系统还有:
- Denial tracking连续拒绝降级
- Protected files黑名单
- Circuit breaker
```
所以 ML 不是唯一防线,而是**多层防御中的一层**。
### 为什么规则支持 Glob 而不是正则表达式?
Glob`src/*.ts` → 简单直观
正则:`^src/[^/]+\.ts$` → 复杂,容易写错
目标用户是**工程师,但不是安全专家**。Glob 的错误率更低。
---
## 常见误解
**误解 1**"Permission mode 是全局的,改一次就生效?"
实际:可以在 CLI 参数中针对单个命令覆盖:
```bash
claude-code --permission-mode auto /commit # 这个 /commit 用 auto mode
claude-code --permission-mode default /config # 这个 /config 用 default mode
```
**误解 2**"YOLO 分类器是完美的?"
实际:分类器是 **best-effort**,有假阳性和假阴性。假阴性(该拒的通过了)会被 denial tracking 捕捉到。
**误解 3**"Protected files 名单是硬编码的?"
实际:可以通过配置扩展:
```json
{
"protectedFiles": [".gitconfig", ".bashrc", ".my-precious-file"]
}
```
---
## 关键要点
1. **Permission mode**`default`(每次问), `auto`ML 自动), `acceptEdits`, `bypass`, `dontAsk`
2. **决策 pipeline**Mode → Rules → Risk Classification → YOLO → User Prompt
3. **规则系统**Glob 模式分层来源CLI > project > user > default
4. **YOLO 分类器**ML 自动批准 MEDIUM 风险操作,不需要用户每次确认
5. **Denial tracking**:连续 3 次拒绝自动降级权限,防止烦人的重复提示
6. **路径安全**多层防御normalization, URL decode, Unicode clean
7. **Protected files**:黑名单,永远要再次确认
---
## 深入阅读
- `utils/permissions/permissions.ts`:完整决策逻辑
- `utils/permissions/yoloClassifier.ts`:分类器实现
- `utils/permissions/pathValidation.ts`:路径安全
- `utils/permissions/denialTracking.ts`Denial tracking
- `utils/permissions/PermissionMode.ts`Mode 定义
下一步:了解**Context 和 Memory 系统**,看看当 context window 快满时会发生什么。