Skip to content
源码分析手册

权限与沙箱:Claude Code 的双层防御体系

在 Claude Code 的安全哲学中,任何可能影响用户系统的操作都必须经过严密的合规性审查。这一审查并非单一的逻辑开关,而是由应用层的“权限引擎(Permissions)”与系统层的“物理沙箱(Sandboxing)”共同构建的双层纵深防御体系。

从定义开始

这套体系本质上是 “意图审计”与“物理隔离”的深度耦合

  • 权限引擎(第一层防线):回答的是“应不应该做”。它运行在 Claude 进程内部,像一个守门员,根据当前的运行模式(Default/Auto/Plan)、用户历史授权记录以及内置的安全策略,判断模型发起的工具调用请求是否合法。它不是简单的黑白名单,而是一个具备上下文感知能力的决策中心。
  • 物理沙箱(第二层防线):回答的是“能不能做到”。它是底层的最后一道防线。即使权限引擎由于某种极端情况被绕过,沙箱也会通过操作系统内核特性(如 macOS 的 Sandbox 框架或 Linux 的 Namespace/Cgroups),为执行过程划定物理边界。

理解这两者的区别至关重要:权限系统管的是“不问你”,而沙箱管的是“不让动”。

运行时的真相

两层的协同工作流主要由权限裁决与环境装配两个阶段组成:

  1. 裁决阶段(Permission Decision Flow): 当模型发起工具请求(例如 BashTool)时,系统首先进入 claude-code-opensource/src/utils/permissions/permissions.ts

    • 上下文提取:系统提取 ToolPermissionContext,包括当前的 CWD、已添加的目录、以及用户通过 /permissions 配置的规则。
    • 分流逻辑:如果命中白名单(只读工具)则放行;如果命中黑名单则拒绝;如果属于未知区域,则根据 PermissionMode(如 default 模式下弹窗,auto 模式下查分类器)产生裁决结果。
  2. 装配与隔离阶段(Sandbox Execution Flow): 一旦权限系统批准执行,且该操作被判定为“有副作用”或“不可信”,系统会通过 claude-code-opensource/src/utils/sandbox/sandbox-adapter.ts 启动沙箱装配。

    • 配置动态生成:沙箱不是静态的。它会根据当前工作区、用户通过 /add-dir 手动放行的路径,动态生成一份临时的配置文件(如 macOS 上的 .sb 文件)。
    • 进程包裹:原始命令被包裹在沙箱启动器(如 sandbox-exec)中运行。此时,该进程只能看到被明确允许的文件路径,且默认无法访问网络。
    • 异常捕获:如果进程尝试越界(Violation),操作系统会强制终止该操作,并将错误信息回传给 SandboxViolationStore 记录。
  3. 双层同步逻辑: 每当用户执行 /add-dir 时,系统会同步更新内存中的 allowedDirectories,还会触发 SandboxManager.refreshConfig()。这确保了应用层的“语义放行”能立即转化为系统层的“物理穿透”。

使用时的关键约束

  • 隔离差异化:沙箱机制目前主要针对 BashTool 产生的外部进程。对于 Claude 进程自身的 Node.js 逻辑(如 FileEditToolFileWriteTool),主要依靠第一层的权限引擎进行精确的路径校验(Path Validation)来防止越界。
  • 物理限制的绝对性:即使你开启了 bypassPermissions 模式(不再弹窗询问),沙箱层依然有效。如果模型尝试访问沙箱配置之外的系统文件,它依然会收到操作系统的 EACCES 错误。
  • 网络默认隔离:除非在设置中显式开启了网络访问,否则沙箱内的所有进程均处于“离线”状态。这意味着 curlwget 等命令在没有用户配置的情况下会默认失败。
  • 性能开销:在 Linux 环境下,由于沙箱依赖命名空间等特性,某些精简内核可能无法完全支持,此时系统会回退到纯权限检查模式并给出显著警告。

继续探索

源码锚点

📄 src/utils/permissions/permissions.ts — 权限系统的核心入口,负责综合各种模式给出 `Approve/Deny/Ask` 裁决。L30-33 of 1487
typescript
  PermissionDenyDecision,
  PermissionResult,
} from './PermissionResult.js'
import type {
📄 src/utils/sandbox/sandbox-adapter.ts — 沙箱适配层,屏蔽了不同操作系统(macOS/Linux)底层沙箱实现的差异。L489-493 of 986
typescript
 * Supports: macOS, Linux, and WSL2+ (WSL1 is not supported)
 */
const isSupportedPlatform = memoize((): boolean => {
  return BaseSandboxManager.isSupportedPlatform()
})
📄 src/tools/BashTool/shouldUseSandbox.ts — 判定逻辑:决定哪些 Bash 命令必须送入沙箱运行。L13-16 of 154
typescript
type SandboxInput = {
  command?: string
  dangerouslyDisableSandbox?: boolean
}

基于 Claude Code v2.1.88 开源快照的深度分析