
理解 Claude Code 的两层安全防线——应用层权限管理 + OS 层沙箱隔离。
Claude Code 采用纵深防御(Defense in Depth)策略,有两层独立但互相协作的安全机制:
┌─────────────────────────────────────────────┐
│ Claude Code 安全架构 │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ 第一层:应用级权限管理 │ │
│ │ (Node.js / 工具调用前拦截) │ │
│ │ │ │
│ │ • allow/deny/ask 规则引擎 │ │
│ │ • auto 模式 AI 分类器 │ │
│ │ • 路径安全检查 │ │
│ │ • 敏感目录保护 │ │
│ └───────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ 第二层:OS 级沙箱隔离 │ │
│ │ (macOS sandbox-exec / Linux bwrap) │ │
│ │ │ │
│ │ • 文件系统读写限制 │ │
│ │ • 网络访问控制 │ │
│ │ • 进程隔离 │ │
│ └───────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────┘
当 Claude 要调用一个工具时,权限系统按以下顺序检查:
1a. deny 规则检查 → 命中则直接拒绝 ❌
↓
1b. ask 规则检查 → 命中?
├─ 沙箱开启 + 命令会在沙箱内 → 跳过询问 ✅
└─ 否则 → 弹窗询问用户
↓
1c. 工具自身权限检查(如 Bash 子命令规则)
↓
1d. 工具实现拒绝 → 拒绝 ❌
↓
1e. 工具需要用户交互 → 询问 ❓
↓
1f. 内容特定 ask 规则 → 即使 bypass 模式也生效
↓
1g. 安全检查(.git/, .claude/, .vscode/) → 始终询问 ❓
↓
2a. 权限模式检查
├─ bypassPermissions → 直接允许 ✅
└─ normal → 继续
↓
2b. always-allow 规则 → 命中则允许 ✅
↓
3. 最终结果 → ask(询问用户)
| 模式 | CLI 参数 | 行为 |
|---|---|---|
normal | 默认 | 按规则 allow/deny/ask |
bypassPermissions | --dangerously-skip-permissions | 跳过大部分询问(deny 和安全检查仍生效) |
plan | --plan | 规划模式 |
auto | --auto | AI 分类器自动判断 |
Auto 模式使用 AI 分类器自动判断操作的安全性:
用户操作
↓
AI 分类器 (Classifier)
├─ 安全 → 自动允许 ✅
├─ 危险 → 自动拒绝 ❌(附带原因)
└─ 不可用 → 根据 iron_gate 策略
├─ fail closed → 拒绝 ❌
└─ fail open → 降级到正常模式
分类器还有拒绝限制(Denial Limits),连续被拒太多次会降级到手动审批。
即使开启 bypassPermissions,以下操作仍需确认:
| 保护对象 | 说明 |
|---|---|
.git/ | 防止修改 git 仓库元数据 |
.claude/ | 防止修改 Claude 配置 |
.vscode/ | 防止修改编辑器设置 |
~/.bashrc 等 | 防止修改 shell 配置 |
settings.json | 防止 Claude 修改自己的权限 |
| 平台 | 技术 | 状态 |
|---|---|---|
| macOS | sandbox-exec (seatbelt) | ✅ 完整支持 |
| Linux | bubblewrap (bwrap) | ✅ 完整支持 |
| WSL2 | bubblewrap | ✅ 支持 |
| WSL1 | — | ❌ 不支持 |
| Windows | — | ❌ 不支持 |
沙箱在 OS 内核层面限制 Claude 执行的 Bash 命令:
| 限制类型 | 控制 |
|---|---|
| 文件系统写入 | 只能写当前目录和显式允许的路径 |
| 文件系统读取 | 可以限制读取敏感路径 |
| 网络访问 | 只能访问白名单中的域名 |
| 设置文件 | 始终禁止写入任何 settings.json |
| Skills 目录 | 禁止写入 .claude/skills/ |
| 裸仓库防护 | 防止在 cwd 创建伪装的 git 裸仓库 |
settings.json 中的 permissions
│
├─ Edit(src/**) allow → sandbox filesystem.allowWrite += "src/**"
├─ Edit(/etc/**) deny → sandbox filesystem.denyWrite += "/etc/**"
├─ Read(~/.ssh/**) deny → sandbox filesystem.denyRead += "~/.ssh/**"
└─ WebFetch(domain:github.com) allow → sandbox network.allowedDomains += "github.com"
关键洞察:同一份 permissions 配置同时驱动两层安全机制。
这是最重要的联动逻辑:
Claude 要执行 Bash 命令
↓
沙箱开启? → 否 → 正常权限检查(可能弹窗询问)
↓ 是
命令会在沙箱内运行?
├─ 排除命令 (docker等) → 否 → 正常权限检查
├─ dangerouslyDisableSandbox → 否 → 正常权限检查
└─ 是 → 自动允许 ✅(不弹窗)
原理:OS 级沙箱已经限制了命令能做的事,再让用户逐条审批就是多余的。
通过 MDM 或 /etc/claude-code/managed-settings.json 部署:
{
"permissions": {
"deny": ["Bash(curl *)", "WebFetch(*)"],
"disableBypassPermissionsMode": "disable"
},
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"allowUnsandboxedCommands": false,
"network": {
"allowManagedDomainsOnly": true,
"allowedDomains": ["internal.company.com"]
}
},
"allowManagedPermissionRulesOnly": true,
"allowManagedHooksOnly": true
}
| 配置 | 效果 |
|---|---|
allowManagedPermissionRulesOnly | 忽略用户/项目的权限规则 |
allowManagedHooksOnly | 仅运行管理员定义的 hooks |
allowManagedDomainsOnly | 仅允许管理员白名单的域名 |
allowManagedMcpServersOnly | MCP 白名单仅来自管理员 |
disableBypassPermissionsMode | 禁用 bypass 模式 |
failIfUnavailable | 沙箱不可用则拒绝启动 |
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true
},
"permissions": {
"deny": [
"Bash(rm -rf /)",
"Edit(//.ssh/**)"
],
"allow": [
"Read(*)",
"Bash(npm test)",
"Bash(git *)"
]
}
}
{
"permissions": {
"deny": [
"Bash(npm publish*)",
"Bash(docker push*)",
"Edit(//.env*)"
],
"ask": [
"Bash(git push*)",
"Edit(.github/**)"
],
"allow": [
"Read(*)",
"Bash(npm run *)",
"Bash(git status)",
"Bash(git diff*)"
]
}
}
{
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"allowUnsandboxedCommands": false,
"network": {
"allowedDomains": []
},
"filesystem": {
"denyRead": ["~/.ssh", "~/.aws", "~/.gnupg"]
}
},
"permissions": {
"defaultMode": "normal",
"disableBypassPermissionsMode": "disable"
}
}