课程大纲
权限、沙箱与 Hooks:4 层防线挡住失控的 agent
权限、沙箱与 Hooks:4 层防线挡住失控的 agent
本文基于 Florian BRUNIAUX 的英文原版改编,原文地址:https://cc.bruniaux.com/guide/architecture 许可:CC BY-SA 4.0
这篇你能拿走什么
把"让 AI 写代码"扩到"让 AI 跑命令、改文件、推 git"之后,安全模型就是底线。Claude Code 在这块的设计不是单点,是 4 层防线(交互提示 / 配置规则 / Hooks / 原生沙箱)。这一篇带你逐层看清楚每一层做什么、不做什么,最后你会知道在自己机器上、团队 CI 上、不可信代码上,分别该怎么配。
前置条件
- 已完成本系列前面的章节
- macOS 用户能修改
~/.claude/settings.json;Linux 用户能apt install包
4 层权限模型
可信度:100%(Tier 1 - 官方)
text┌─────────────────────────────────────────────────────────────┐ │ PERMISSION LAYERS │ ├─────────────────────────────────────────────────────────────┤ │ Layer 1: INTERACTIVE PROMPTS │ │ Claude wants to run: rm -rf node_modules │ │ [Allow once] [Allow always] [Deny] [Edit command] │ │ │ │ Layer 2: ALLOW/DENY RULES (settings.json) │ │ { "permissions": { "allow": ["Bash(npm *)", "Read"], │ │ "deny": ["Bash(rm -rf *)"] } } │ │ │ │ Layer 3: HOOKS (Pre/Post execution) │ │ PreToolUse: Validate before execution │ │ PostToolUse: Audit after execution │ │ PermissionRequest: Override permission prompts │ │ │ │ Layer 4: SANDBOX MODE (Optional isolation) │ │ Filesystem isolation + Network restrictions │ └─────────────────────────────────────────────────────────────┘
关键点:4 层是叠加的,不是替代关系。设了 allow rule 不代表绕过 hook;设了 sandbox 不代表 Layer 1 的弹窗不出现。
危险模式检测
可信度:80%(Tier 2 - 已观察但非穷尽)
某些模式会被强制提示,无视你的 allow 列表:
| 模式 | 风险 | 行为 |
|---|---|---|
rm -rf | 破坏性删除 | 始终提示 |
sudo | 权限提升 | 始终提示 |
curl | sh | 远程代码执行 | 始终提示 |
chmod 777 | 不安全权限 | 始终提示 |
git push --force | 破坏历史 | 始终提示 |
DROP TABLE | 数据破坏 | 始终提示 |
注意:这不是完整 blocklist,而且很可能是模型训练时识别出来的,不是显式规则。所以别指望它捕捉所有危险——比如 rm -rf $TMP/* 在 $TMP 是空字符串时同样致命,但可能不会触发提示。真正的安全靠 sandbox + hook,不靠模式检测。
原生沙箱(v2.1.0+)
可信度:100%(Tier 1 - 官方)
Claude Code 内置原生沙箱,使用操作系统级原语进行进程级隔离:
text┌──────────────────────────────────────────────────────┐ │ Native Sandbox Architecture │ ├──────────────────────────────────────────────────────┤ │ Bash Command Request │ │ ▼ │ │ Sandbox Wrapper (Seatbelt/bubblewrap) │ │ ├─ Filesystem: read all, write CWD only │ │ ├─ Network: SOCKS5 proxy + domain filtering │ │ ├─ Process: isolated environment │ │ ▼ │ │ OS Kernel Enforcement │ │ ├─ Allowed: operations within boundaries │ │ ├─ Blocked: violations at system call level │ │ └─ Notify: user receives alert on violation │ └──────────────────────────────────────────────────────┘
平台支持:
| 平台 | 机制 | 说明 |
|---|---|---|
| macOS | Seatbelt(TrustedBSD MAC) | 内置,内核级系统调用过滤 |
| Linux / WSL2 | bubblewrap(namespaces + seccomp) | 需 sudo apt-get install bubblewrap socat |
| WSL1 | 不支持 | bubblewrap 需要 WSL1 不具备的内核特性 |
| Windows | 计划中 | 尚不可用 |
隔离的边界
文件系统:可读全机(除被显式拒绝的路径),写入仅限 CWD(可配置);被阻止:修改 CWD 之外、凭据目录(~/.ssh、~/.aws)。
网络:所有连接经 SOCKS5 proxy 路由;域名过滤(allowlist / denylist);默认阻止:私有 CIDR、localhost 范围。
进程:共享内核(容易受内核漏洞影响,不同于 Docker microVM);子进程继承相同沙箱;逃生口:对不兼容工具用 dangerouslyDisableSandbox 参数。
沙箱模式
- Auto-allow mode:Bash 命令在沙箱中运行就自动批准(推荐用于日常开发)
- Regular permissions mode:所有命令都需要明确批准(高安全性)
原生沙箱 vs Docker 沙箱
| 方面 | 原生沙箱 | Docker(microVM) |
|---|---|---|
| 内核隔离 | 共享内核 | 每个 VM 独立内核 |
| 设置 | macOS 无依赖;Linux 需 2 个包 | Docker Desktop 4.58+ |
| 开销 | 极低(~1-3% CPU) | 中等(~5-10% CPU) |
| 使用场景 | 日常开发、可信代码 | 不可信代码、最高安全性 |
安全限制:
- Domain fronting:CDN(Cloudflare、Akamai)可绕过域名过滤
- Unix sockets:配置错误的
allowUnixSockets会导致权限提升 - 文件系统:过宽的写权限会允许攻击
$PATH目录
Hooks 系统
Hooks 让你以编程方式控制 Claude 的行为:
json{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [{ "type": "command", "command": "/path/to/validate-command.sh" }] } ], "PostToolUse": [ { "matcher": "*", "hooks": [{ "type": "command", "command": "/path/to/audit-log.sh" }] } ] } }
Hook 能力:
| 能力 | 支持 | 方式 |
|---|---|---|
| 阻止执行 | 是 | 退出码 2 |
| 修改参数 | 是 | 返回修改后的 JSON |
| 记录动作 | 是 | 在 hook 中写入文件 |
| 异步处理 | 是 | hook 配置中设 async: true(v2.1.0+) |
Hook 拿到的 JSON payload
通过 stdin 传入,所有事件都有的通用字段 + 事件特定字段:
json{ "session_id": "abc123", "transcript_path": "/home/user/.claude/projects/.../transcript.jsonl", "cwd": "/path/to/project", "permission_mode": "default", "hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": { "command": "npm install lodash" } }
通用字段:session_id、transcript_path、cwd、permission_mode、hook_event_name。
事件特定字段(如 PreToolUse 的 tool_name / tool_input)会在通用字段基础上附加。
实战注解
我自己的安全配置最少长这样:
- macOS 默认开 Seatbelt:不需要额外动作,Claude Code 会自动用
- deny 列表加 4 条硬规则:
Bash(rm -rf /)、Bash(rm -rf ~)、Bash(git push --force *main*)、Bash(curl * | sh) - PreToolUse hook 记录所有 Bash 调用:写到
~/.claude/audit.log,方便事后回溯 - 不信任的代码:单独开 Docker 沙箱跑 Claude Code,原生沙箱我只用在自己的项目
特别提一句:别用 dangerouslyDisableSandbox。这个参数是给"工具实在不兼容沙箱"的逃生口,不是给"我嫌沙箱烦"用的。任何时候你想加这个参数,先停 5 分钟想清楚是不是真的没别的办法。
可信度回顾
- Tier 1(官方 100%):4 层权限模型、原生沙箱(Seatbelt/bubblewrap)、Hooks 系统及 JSON payload
- Tier 2(70-90%):危险模式检测(已观察但非穷尽列表)
- Tier 3(推断):本篇没有 Tier 3 内容
危险模式那张表只是"曾经被观察到",不是"完整的 blocklist"。真正的安全靠 sandbox + hook,不靠模式匹配。
常见问题
Q:Hook 可以阻止 Claude 调用某个工具吗? A:可以。PreToolUse hook 退出码非 0(特别是 2)会阻止工具执行,stdout 内容会作为反馈返回给模型。
Q:原生沙箱被绕过过吗? A:原文记的安全限制里就明确说了 3 种已知绕过方式(Domain fronting、Unix sockets 配错、$PATH 写权限攻击)。所以原生沙箱不是"零信任级别"的隔离,对不可信代码请用 Docker。
Q:异步 hook 怎么用?
A:v2.1.0+ 支持 async: true,hook 不会阻塞工具执行,适合做日志、metrics 这类事后处理。但别把校验逻辑放异步 hook,会被绕过。
来源与许可
- 原作者:Florian BRUNIAUX;Claude(Anthropic)参与贡献
- 英文原版地址:https://cc.bruniaux.com/guide/architecture
- 源文件:
FlorianBruniaux/claude-code-ultimate-guide / guide/core/architecture.md - 本文基于 CC BY-SA 4.0 改编:保留署名、来源链接,衍生作品同样以 CC BY-SA 4.0 公开
- 内容版本:原作 v1.1.0 / Claude Code v2.1.34(2026-02)