Skip to content

来源:Claude Code 技术文档 - v2.1.88 源码分析

权限与安全系统

7.1 权限模式

7.1.1 模式定义

// 外部可访问的权限模式(用户可配置)
type ExternalPermissionMode =
  | 'acceptEdits'       // 接受所有编辑操作
  | 'bypassPermissions' // 跳过所有权限检查
  | 'default'           // 默认模式(按需提示)
  | 'dontAsk'           // 不询问(静默拒绝不安全操作)
  | 'plan'              // 规划模式(仅只读操作)

// 内部权限模式(含运行时特殊模式)
type InternalPermissionMode = ExternalPermissionMode
  | 'auto'              // 自动分类器判断
  | 'bubble'            // 冒泡到父级决策

type PermissionMode = InternalPermissionMode

7.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)
      └─ 服务不可用 → 降级为 ask

7.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 (最高)

每一层都可以定义 allowdenyask 规则,按优先级合并后形成最终的 ToolPermissionContext

MIT