🔐

权限与安全

Claude Code 的权限模型、评估管道与沙箱机制

安全

权限模式

六种运行模式,从严格到宽松

🛡️

Default

标准权限模式,所有工具调用都需要用户确认

ask

每个工具调用都会弹出确认提示,用户手动决定 Allow、Deny 或 Allow Always。适用于对安全性要求最高的场景。

📋

Plan

计划模式,只读操作自动允许,写操作需要确认

ask (reads: allow)

文件读取、搜索等只读操作自动放行,文件写入、命令执行等修改操作仍需确认。适合代码审查和探索阶段。

✏️

Auto Edit

自动接受文件编辑,但命令执行仍需确认

edits: allow, commands: ask

FileEdit、FileWrite 等文件编辑工具自动批准,BashTool 等命令执行工具仍需确认。平衡效率与安全。

📁

Accept Edits

自动接受文件系统操作(mkdir, touch, rm, mv, cp, sed)

fs ops: allow

在 BashTool 中,文件系统相关命令(mkdir、touch、rm、rmdir、mv、cp、sed)自动允许,其他命令仍走标准权限流程。

Don't Ask (Auto-Approve)

自动批准所有工具调用,无需确认

allow (all)

所有工具调用自动批准,不弹出任何确认提示。最高效率但最低安全性,适合受信任的自动化流水线。

🔓

Bypass Permissions

完全绕过权限系统,所有操作直接执行

bypass

跳过所有权限检查和分类器评估。仅用于高度受控的环境(如 CI/CD),普通开发中不建议使用。

模式对比

不同模式下的权限行为一览

模式文件读取文件编辑Bash 命令安全级别
DefaultAsk ✋Ask ✋Ask ✋🟢 最高
PlanAllow ✅Ask ✋Ask ✋🟢 高
Auto EditAllow ✅Allow ✅Ask ✋🟡 中
Accept EditsAllow ✅Allow ✅Ask ✋🟡 中
Don't AskAllow ✅Allow ✅Allow ✅🔴 低
BypassAllow ✅Allow ✅Allow ✅⚪ 无

权限评估管道

每个工具调用经过的多阶段权限检查

请求传递未匹配allow/ask最终决策工具调用模式检查规则匹配分类器沙箱决策Allow/Deny/Ask

① 模式检查

首先检查当前权限模式(default/plan/acceptEdits 等)。模式可以 直接决定某些操作的行为,例如 Plan 模式自动放行只读操作, Accept Edits 模式自动放行文件系统命令。

② 规则匹配

检查用户自定义的权限规则(Permission Rules)。支持精确匹配、前缀匹配和通配符模式。 匹配到的规则直接决定 allow 或 deny,未匹配则传递给分类器。

③ 分类器评估

Bash Classifier 对 shell 命令进行语义分析,区分只读命令(ls、cat、grep) 和潜在危险命令(rm、curl、npm install),自动做出安全决策。

核心类型定义

来自 claude-code 源码的真实类型

// types/permissions.ts — 权限模式定义

// 外部可见的权限模式(用户可配置)
export const EXTERNAL_PERMISSION_MODES = [
  'acceptEdits',      // 自动接受文件系统操作
  'bypassPermissions', // 完全绕过权限系统
  'default',           // 标准模式,所有操作需确认
  'dontAsk',           // 自动批准所有操作
  'plan',              // 计划模式,只读自动放行
] as const

// 内部扩展模式
export type InternalPermissionMode =
  | ExternalPermissionMode
  | 'auto'    // 智能自动决策(Transcript Classifier)
  | 'bubble'  // 权限决策冒泡给上层

// 权限行为
export type PermissionBehavior = 'allow' | 'deny' | 'ask'

// 权限决策结果
export type PermissionResult = {
  behavior: PermissionBehavior
  message?: string
  decisionReason?: {
    type: 'mode' | 'rule' | 'classifier' | 'sandbox'
    mode?: PermissionMode
  }
}

沙箱机制

隔离执行不可信命令的安全容器

YesYesNo用户命令shouldUseSandbox沙箱已启用?排除列表?容器执行本地执行结果返回

🔒 沙箱决策逻辑

  • 1.检查 SandboxManager.isSandboxingEnabled() — 全局开关
  • 2.检查 dangerouslyDisableSandbox — 显式覆盖
  • 3.检查排除列表 — 用户配置的排除命令(支持前缀/通配符)
  • 4.通过所有检查 → 在容器中执行;否则 → 本地执行

⚠️ 安全边界说明

  • 排除命令 ≠ 安全边界:排除列表是用户便利功能, 不是安全控制。绕过排除列表不构成安全漏洞。
  • 真正的安全控制:沙箱权限系统(弹出用户确认) 才是实际的安全边界。
  • 复合命令处理:对 cmd1 && cmd2 格式, 逐个拆分子命令检查,防止通过复合命令逃逸沙箱。

Bash 命令分类器

基于语义分析的自动权限决策

// utils/permissions/bashClassifier.ts

// 分类器行为
type ClassifierBehavior = 'allow' | 'deny' | 'ask'

// 分类结果
type ClassifierResult = {
  matches: boolean
  confidence: number        // 0-1 置信度
  reason: string            // 决策理由
  matchedDescription?: string
}

// 分类器描述 — 定义命令模式与行为映射
getBashPromptAllowDescriptions()  // 自动允许的命令描述
getBashPromptAskDescriptions()    // 需要确认的命令描述
getBashPromptDenyDescriptions()   // 自动拒绝的命令描述

// 示例分类:
// ✅ Allow: ls, cat, grep, head, tail, find, wc, echo ...
// ❌ Deny:  rm -rf /, sudo, chmod 777 ...
// 🤔 Ask:   curl, wget, npm install, docker ...

权限规则系统

用户自定义的细粒度权限控制

规则类型

exact

精确匹配命令字符串,如 ls

prefix

前缀匹配,如 npm * 匹配所有 npm 命令

wildcard

通配符模式,如 git push *

规则值

allowdenyask

Undercover 模式

安全贡献公共仓库时的隐私保护

🕵️

什么是 Undercover 模式?

Undercover 模式是 Claude Code 内部使用的安全机制,当贡献到公共/开源仓库时自动激活。 它会在 commit 和 PR 提示中添加安全指令,并移除所有可能泄露内部信息的归属标记。

🔧 激活方式
  • CLAUDE_CODE_UNDERCOVER=1 — 强制开启
  • 默认 AUTO:仓库 remote 不在内部白名单中时自动激活
  • 没有强制关闭选项(安全设计)
🛡️ 保护内容
  • 模型代号(不告诉模型它是什么模型)
  • 内部项目名称和代号
  • Anthropic 内部信息
  • commit/PR 中的归属标记

💡 了解更多 Undercover 模式的实际应用,请访问 /buddy 页面

远程权限桥接

Remote Permission Bridge

// remote/remotePermissionBridge.ts

// 当工具在远程 CCR 容器中执行时,本地 CLI 需要处理权限请求。
// 由于本地没有真实的 AssistantMessage,需要创建合成消息。

function createSyntheticAssistantMessage(
  request: SDKControlPermissionRequest,
  requestId: string,
): AssistantMessage {
  return {
    type: 'assistant',
    message: {
      role: 'assistant',
      content: [{
        type: 'tool_use',
        id: request.tool_use_id,
        name: request.tool_name,
        input: request.input,
      }],
    },
    // ...
  }
}

// 对于本地未知的远程工具(如 MCP 工具),创建工具存根
function createToolStub(toolName: string): Tool {
  return {
    name: toolName,
    needsPermissions: () => true,
    isReadOnly: () => false,
    // ...
  }
}

Accept Edits 模式验证

modeValidation.ts — 基于模式的命令验证

// tools/BashTool/modeValidation.ts

// Accept Edits 模式下自动允许的文件系统命令
const ACCEPT_EDITS_ALLOWED_COMMANDS = [
  'mkdir', 'touch', 'rm', 'rmdir', 'mv', 'cp', 'sed',
] as const

function validateCommandForMode(
  cmd: string,
  toolPermissionContext: ToolPermissionContext,
): PermissionResult {
  const [baseCmd] = cmd.trim().split(/\s+/)

  // Accept Edits 模式 → 自动允许文件系统操作
  if (
    toolPermissionContext.mode === 'acceptEdits' &&
    isFilesystemCommand(baseCmd)
  ) {
    return {
      behavior: 'allow',
      updatedInput: { command: cmd },
      decisionReason: { type: 'mode', mode: 'acceptEdits' },
    }
  }

  // Bypass 模式在主权限流中处理
  return { behavior: 'passthrough' }
}