三种权限行为
每一次工具调用,系统都会做出三种裁决之一:| 行为 | 含义 | 返回类型 | 典型场景 |
|---|---|---|---|
| Allow | 自动放行,用户无感知 | { behavior: 'allow', updatedInput, decisionReason } | Read 读取项目内文件 |
| Ask | 弹出确认对话框 | { behavior: 'ask', message, suggestions, metadata } | Bash 执行未知命令 |
| Deny | 直接拒绝 | { behavior: 'deny', message, decisionReason } | 尝试执行被禁止的命令 |
PermissionResult 类型定义(src/utils/permissions/PermissionResult.ts)。
权限规则的五层来源
规则从 5 个来源汇聚(PERMISSION_RULE_SOURCES,permissions.ts:109),优先级从高到低:
alwaysAllowRules[source]、alwaysAskRules[source]、alwaysDenyRules[source]。
规则数据结构为 PermissionRule:
规则匹配引擎
三维度匹配
permissions.ts 实现了三种匹配维度:
1. 工具名匹配(toolMatchesRule(),第 238 行)
匹配整个工具,仅当规则没有 ruleContent:
getToolNameForPermissionCheck() 获取匹配名称,支持有前缀(mcp__server__tool)和无前缀模式。
2. 命令模式匹配(BashTool 的 checkPermissions())
BashTool 通过 preparePermissionMatcher()(Tool.ts:514)解析命令模式:
readOnlyValidation.ts 使用 tree-sitter bash),提取第一个子命令进行匹配。
3. 路径匹配(文件工具的 checkPermissions())
Read/Edit/Write 工具通过 getPath() 提取文件路径,与 ruleContent 中的 glob 模式匹配:
权限检查的完整流程
每次工具调用的权限检查(canUseTool() → checkPermissions())经过以下步骤:
权限模式
| 模式 | PermissionMode 值 | 适用场景 | 行为 |
|---|---|---|---|
| Default | 'default' | 日常使用 | 敏感操作逐一确认 |
| Plan Mode | 'plan' | 探索阶段 | 只能读不能写(isReadOnly() 检查) |
| Auto | 'auto' | 信任 AI | 通过 transcript classifier 自动决策 |
| Bypass | 'bypassPermissions' | 完全信任 | 所有操作自动放行(需显式 --dangerously-skip-permissions) |
EnterPlanModeTool.call() 触发:
ExitPlanModeV2Tool 恢复为之前的模式。
Denial Tracking:死循环防护
src/utils/permissions/denialTracking.ts 实现了拒绝追踪机制:
recordDenial()记录拒绝,增加计数shouldFallbackToPrompting()检测到连续拒绝,返回 true- 系统向 AI 注入消息:“Your previous tool call was rejected…”
- AI 被迫改变策略,避免”反复请求同一个被拒操作”的死循环
recordSuccess() 重置计数。
规则的运行时更新
权限规则可以在运行时动态更新(applyPermissionUpdate(),PermissionUpdate.ts):
persistPermissionUpdates() 将规则写入对应层级的 settings 文件(project/user/managed),同时更新内存中的 toolPermissionContext。