三种权限行为
每一次工具调用,系统都会做出三种裁决之一:
这些行为由
PermissionResult 类型定义(src/utils/permissions/PermissionResult.ts)。
权限规则的来源
规则从 8 个来源汇聚(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:520)解析命令模式:
readOnlyValidation.ts 使用 tree-sitter bash),提取第一个子命令进行匹配。
3. 路径匹配(文件工具的 checkPermissions())
Read/Edit/Write 工具通过 getPath() 提取文件路径,与 ruleContent 中的 glob 模式匹配:
权限检查的完整流程
每次工具调用的权限检查(canUseTool() → checkPermissions())经过以下步骤:
权限模式
Plan Mode 切换由
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。