来源:Claude Code 技术文档 - v2.1.88 源码分析
权限与安全系统
7.1 权限模式
7.1.1 模式定义
// 外部可访问的权限模式(用户可配置)
type ExternalPermissionMode =
| 'acceptEdits' // 接受所有编辑操作
| 'bypassPermissions' // 跳过所有权限检查
| 'default' // 默认模式(按需提示)
| 'dontAsk' // 不询问(静默拒绝不安全操作)
| 'plan' // 规划模式(仅只读操作)
// 内部权限模式(含运行时特殊模式)
type InternalPermissionMode = ExternalPermissionMode
| 'auto' // 自动分类器判断
| 'bubble' // 冒泡到父级决策
type PermissionMode = InternalPermissionMode7.1.2 模式行为矩阵
模式
只读工具
文件编辑
Shell 命令
破坏性操作
default
✅ 直接执行
⚠️ 提示确认
⚠️ 提示确认
⚠️ 提示确认
acceptEdits
✅ 直接执行
✅ 自动接受
⚠️ 提示确认
⚠️ 提示确认
bypassPermissions
✅ 直接执行
✅ 自动接受
✅ 自动接受
✅ 自动接受
plan
✅ 直接执行
❌ 拒绝
❌ 拒绝
❌ 拒绝
dontAsk
✅ 直接执行
❌ 静默拒绝
❌ 静默拒绝
❌ 静默拒绝
auto
✅ 直接执行
🤖 分类器判断
🤖 分类器判断
🤖 分类器判断
bubble
↑ 冒泡
↑ 冒泡
↑ 冒泡
↑ 冒泡
7.2 权限规则系统
7.2.1 规则来源
type PermissionRuleSource =
| 'policySettings' // 企业管理策略(最高优先级)
| 'flagSettings' // Feature Flag 控制
| 'cliArg' // 命令行参数
| 'localSettings' // 本地 .claude/settings.json
| 'projectSettings' // 项目级配置
| 'userSettings' // 用户级 ~/.claude/settings.json
| 'session' // 会话内交互
| 'command' // 命令级覆盖7.2.2 规则结构
type PermissionRuleValue = {
toolName: string // 工具名匹配模式
ruleContent?: string // 规则内容(路径/命令模式)
}
type PermissionRule = {
source: PermissionRuleSource // 来源
ruleBehavior: 'allow' | 'deny' | 'ask' // 行为
ruleValue: PermissionRuleValue // 匹配值
}7.2.3 规则优先级
权限决策流程(从高到低)
│
├─ 1. policySettings (企业策略)
│ └─ 最高优先级,不可被覆盖
│
├─ 2. alwaysDenyRules
│ └─ 匹配则直接拒绝
│
├─ 3. alwaysAllowRules
│ └─ 匹配则直接允许(除非 deny 已匹配)
│
├─ 4. alwaysAskRules
│ └─ 匹配则提示用户确认
│
└─ 5. PermissionMode 默认行为
└─ 按当前模式的默认策略7.2.4 ToolPermissionContext
type ToolPermissionContext = {
readonly mode: PermissionMode
readonly additionalWorkingDirectories: ReadonlyMap<string, AdditionalWorkingDirectory>
readonly alwaysAllowRules: ToolPermissionRulesBySource
readonly alwaysDenyRules: ToolPermissionRulesBySource
readonly alwaysAskRules: ToolPermissionRulesBySource
readonly isBypassPermissionsModeAvailable: boolean
readonly isAutoModeAvailable?: boolean
readonly strippedDangerousRules?: ToolPermissionRulesBySource
readonly shouldAvoidPermissionPrompts?: boolean
readonly awaitAutomatedChecksBeforeDialog?: boolean
readonly prePlanMode?: PermissionMode
}7.3 权限决策
7.3.1 决策类型
type PermissionDecision<Input> =
| PermissionAllowDecision<Input> // 允许
| PermissionAskDecision<Input> // 需要确认
| PermissionDenyDecision // 拒绝
type PermissionResult<Input> =
| PermissionDecision<Input>
| { behavior: 'passthrough' } // 透传(使用默认行为)7.3.2 权限检查流程
工具调用 → tool.checkPermissions(input, context)
│
├─ 工具内置权限逻辑
│ ├─ BashTool: 检查命令危险性
│ ├─ FileEditTool: 检查路径权限
│ ├─ FileWriteTool: 检查目录权限
│ └─ AgentTool: 检查代理权限
│
├─ 返回 PermissionResult
│ ├─ { behavior: 'allow' }
│ │ └─ 直接执行
│ │
│ ├─ { behavior: 'ask', message, ... }
│ │ ├─ 交互式 → 显示确认对话框
│ │ └─ 非交互式 → 根据模式决定
│ │
│ ├─ { behavior: 'deny', message }
│ │ └─ 返回拒绝错误
│ │
│ └─ { behavior: 'passthrough' }
│ └─ 交给外层权限逻辑决定
│
└─ wrappedCanUseTool() 外层包装
└─ 跟踪拒绝次数用于诊断7.4 自动分类器 (YOLO Classifier)
7.4.1 分类器结果
type YoloClassifierResult = {
thinking?: string // AI 推理过程
shouldBlock: boolean // 是否阻止
reason: string // 判断原因
unavailable?: boolean // 分类器不可用
transcriptTooLong?: boolean // 上下文太长无法分析
model: string // 使用的分类模型
usage?: ClassifierUsage // Token 使用量
durationMs?: number // 分析耗时
stage?: 'fast' | 'thinking' // 分析阶段
}7.4.2 分类流程
auto 模式下的工具调用
│
├─ 快速阶段 (fast)
│ ├─ 正则匹配已知安全/危险模式
│ └─ 快速判断 → shouldBlock: true/false
│
├─ 思考阶段 (thinking) - 快速阶段无法确定时
│ ├─ 调用 AI 模型分析
│ ├─ 传入上下文: 工具名、输入、会话历史
│ └─ 返回推理结果
│
└─ 不可用
├─ 上下文太长 (transcriptTooLong)
└─ 服务不可用 → 降级为 ask7.4.3 通用分类器
type ClassifierResult = {
matches: boolean // 是否匹配
matchedDescription?: string // 匹配描述
confidence: 'high' | 'medium' | 'low' // 置信度
reason: string // 原因
}7.5 Hook 安全系统
7.5.1 Hook 类型
Hook 是用户定义的拦截器,在工具执行前后触发:
type HookCallback = {
type: 'callback'
callback: (
input: HookInput, // Hook 输入
toolUseID: string | null, // 工具调用 ID
abort: AbortSignal | undefined,
hookIndex?: number,
context?: HookCallbackContext
) => Promise<HookJSONOutput>
timeout?: number // 超时时间
internal?: boolean // 是否内部 Hook
}7.5.2 Hook 结果
type HookResult = {
message?: Message // 要添加的消息
systemMessage?: Message // 系统消息
blockingError?: HookBlockingError // 阻止性错误
outcome: 'success' | 'blocking' | 'non_blocking_error' | 'cancelled'
// 权限控制
preventContinuation?: boolean // 阻止继续
stopReason?: string // 停止原因
permissionBehavior?: 'ask' | 'deny' | 'allow' | 'passthrough'
hookPermissionDecisionReason?: string
// 上下文修改
additionalContext?: string // 附加上下文
initialUserMessage?: string // 初始用户消息
updatedInput?: Record<string, unknown> // 更新的工具输入
updatedMCPToolOutput?: unknown // 更新的 MCP 输出
// 重试
permissionRequestResult?: PermissionRequestResult
retry?: boolean
}7.5.3 同步 Hook 响应 Schema
const syncHookResponseSchema = z.object({
continue: z.boolean().optional(), // 是否继续
suppressOutput: z.boolean().optional(),// 抑制输出
stopReason: z.string().optional(), // 停止原因
decision: z.enum(['approve', 'block']).optional(), // 决策
reason: z.string().optional(), // 原因
systemMessage: z.string().optional(), // 系统消息
hookSpecificOutput: z.union([...]) // 特定输出
})7.6 企业策略
7.6.1 策略配置
企业策略 (policySettings) 具有最高优先级,覆盖所有其他规则来源:
企业策略 (policySettings)
│
├─ 工具拒绝列表
│ └─ deny: [{ toolName: 'BashTool', ruleContent: 'rm -rf *' }]
│
├─ MCP 服务器限制
│ └─ allowlist/denylist for MCP servers
│
├─ 功能禁用
│ └─ 禁用特定 Feature Flag
│
└─ 审计日志
└─ 所有操作记录到企业审计系统7.6.2 危险规则剥离
// strippedDangerousRules
// 从用户配置中检测并剥离的危险规则
// 例如:过于宽泛的 allow 规则
// 企业管理员可以配置哪些规则模式被视为"危险"7.7 信任对话框
7.7.1 信任模式
Claude Code 实现了分层信任模型:
首次运行
│
├─ 显示信任对话框
│ ├─ 项目目录访问确认
│ ├─ 网络访问确认
│ └─ 工具使用确认
│
├─ 用户确认后
│ ├─ initializeTelemetryAfterTrust()
│ │ └─ 仅在用户同意后启用遥测
│ └─ 保存信任状态到配置
│
└─ 后续运行
└─ 检查已保存的信任状态7.7.2 文件安全
// 文件提取安全措施(bundled skills)
// 使用 O_NOFOLLOW | O_EXCL 标志
// - O_NOFOLLOW: 不跟随符号链接(防止链接注入)
// - O_EXCL: 文件必须不存在才能创建(防止覆盖)7.8 权限配置层次
用户主目录
└─ ~/.claude/
└─ settings.json ← userSettings
│
项目根目录
└─ .claude/
├─ settings.json ← localSettings
└─ settings.local.json ← projectSettings
│
CLAUDE.md ← projectSettings (部分)
│
命令行参数 ← cliArg
│
Feature Flags ← flagSettings
│
企业策略 ← policySettings (最高)每一层都可以定义 allow、deny、ask 规则,按优先级合并后形成最终的 ToolPermissionContext。