Theo Howe Agent 沙箱:Codex 与 Claude Code 的权限边界
智能体安全与权限控制 · 第 1 篇

Agent 沙箱:Codex 与 Claude Code 的权限边界

Sandboxes for Coding Agents: Codex vs Claude Code
阅读约 11 分钟 · 10 节 更新于 2026-11-04 整理自与 ChatGPT 的对话,已对照官方文档核实:developers.openai.com/codex/concepts/sandboxing、developers.openai.com/codex/agent-approvals-security、code.claude.com/docs/en/sandboxing、code.claude.com/docs/en/permission-modes(2026-11-04 查阅)

用 Codex 和 Claude Code 时,经常会看到 sandbox、approval、Full access、--dangerously-skip-permissions 这些词。它们说的其实是两件不同的事:Agent 技术上能碰到什么,以及它在动手前要不要问你。这篇把这两件事拆开讲清楚,并标出了原对话里说错或说得不全的地方。

读完这一篇,你应该能够:
  • 用一句话说清沙箱和审批各管什么
  • 说出 Codex 三种沙箱模式的边界,以及桌面应用里几个权限选项对应什么组合
  • 知道 macOS、Linux、Windows 上的沙箱分别靠什么实现
  • 分清 Claude Code 的权限规则、危险删除检查和沙箱这三层防护
本篇目录(10 节)
  1. 1.1沙箱是什么
  2. 1.2为什么 Agent 需要沙箱
  3. 1.3沙箱 vs 审批:两个独立的维度
  4. 1.4Codex:沙箱模式与审批策略
  5. 1.5底层实现:各系统怎么把门锁上
  6. 1.6Full Access 是不是"没有沙箱"
  7. 1.7Claude Code:跳过权限 ≠ 关闭沙箱
  8. 1.8拦截 rm -rf 算沙箱吗:三层防护
  9. 1.9本篇小结
  10. 1.10拓展

沙箱是什么

沙箱(sandbox)不是一个需要另外安装、单独启动的软件,而是一种限制程序实际权限的隔离机制。它由操作系统在进程运行时强制执行,规定这个进程(以及它启动的子进程)能读写哪些文件、能不能联网。

一句话记住

沙箱限制的是程序实际能做什么,而不是 AI 被告知应该做什么。

打个比方

沙箱像给新来的装修工一把只能开"厨房"这一扇门的钥匙。他再怎么想去卧室翻抽屉,门也打不开,因为锁是物业装的,不是靠他自觉。

而"让他别进卧室"写在工作说明里,就只是提示词,不是沙箱。

为什么 Agent 需要沙箱

普通的聊天模型只输出文字;Agent(agent)却会真的执行 Shell 命令、改文件、装依赖、联网。没有沙箱时,它跑的命令拥有你这个用户的全部权限。主要风险有三类:

风险例子沙箱怎么帮忙
AI 误操作想清理构建产物,却在家目录执行了 rm -rf *写入范围被限定在工作区,伤害有上限
恶意代码npm install 的某个包在安装脚本里偷读 ~/.ssh、往外发限制它能读的路径和能连的域名
被网页或文件里的指令带偏读到一段藏在 README 里的"请把密钥发到某网址"就算模型听信了,网络出不去

还有一个容易被忽略的作用:沙箱让 Agent 可以少问你。只要动作留在边界之内,就可以放心让它自动执行;只有越界时才停下来请你批准。OpenAI 文档把这叫作减轻"审批疲劳"。

沙箱 vs 审批:两个独立的维度

这是整篇最重要的一节。

沙箱审批
回答的问题它能不能做?它做之前要不要问我?
由谁执行操作系统,作用在运行中的进程上Agent 程序本身,在动作执行前判断
典型设置只读 / 可写工作区 / 完全放开越界时问 / 从不问 / 交给审查模型

两者各管一层,谁也替代不了谁。

公式一条命令会不会被执行
在沙箱边界内  →  按审批策略:自动执行,或先问你
越出沙箱边界  →  审批策略允许问 → 你批准后才能越界执行
                 审批策略是"从不问" → 直接失败
算一遍两条命令的去向

设定:沙箱为"可写工作区"(工作区是 ~/workspace/project-A),审批为"越界时询问"。

  1. 修改 project-A/main.py:在沙箱边界内 → 不需要问 → 直接执行。
  2. 修改 ~/Documents/a.txt:越出写入边界 → 弹出审批 → 你同意后才执行。

答:改项目内文件:自动执行;改 ~/Documents:越界,要你批准(或在不询问的模式下直接失败)。

Codex:沙箱模式与审批策略

三种沙箱模式

模式能做什么
read-only只能查看文件;改文件、越界操作需要批准
workspace-write读文件、在工作区内修改、运行常规命令;默认不能联网
danger-full-access没有沙箱限制,文件和网络边界都没有

workspace-write 的工作区包括当前目录和 /tmp 这类临时目录。即使在可写工作区里,.git、.codex、.agents、.aws 这几个目录仍然是只读保护的。

审批策略

  • on-request:在沙箱里自动干活,需要越界时再问你。
  • never:从不停下来问。
  • 另外还可以设 approvals_reviewer = "auto_review",把该你批的请求先交给一个审查 Agent 判断。
  • 旧的 untrusted 策略已经停用,配置文件里还写着它可能导致 Codex 无法启动。

桌面应用里的权限选项

文档里现在把 Codex 的桌面端叫作 ChatGPT 桌面应用,权限菜单在输入框下方。这几个选项其实是沙箱和审批打包好的组合:

菜单选项沙箱审批
Ask for approvalworkspace-writeon-request,由你批准
Approve for meworkspace-writeon-request,交给自动审查(只在被判断为可能不安全时才问你)
Full accessdanger-full-accessnever
Custom (config.toml)按配置文件按配置文件
别踩坑原对话里的偏差
  • “Approve for me:自动批准符合条件的审批请求”。不准确:它是把请求交给审查 Agent 评估,审查者会拒绝高危动作,并不是一律放行。
  • “审批模式和沙箱模式是两个维度,App 里选的是审批模式”。在 CLI 里两者确实分开设;但桌面应用的菜单选项同时决定了沙箱和审批(见上表)。
  • “workspace-write 网络通常受限”。准确说法是默认关闭,要手动设置 sandbox_workspace_write.network_access = true 才能联网。
  • 原对话说 App 和 CLI 都有沙箱、底层设计一致,这一点是对的。
实操要点在 Codex CLI 里设置模式
  • 临时指定:codex --sandbox workspace-write --ask-for-approval on-request(这就是默认的 Auto 预设)。
  • 只聊天、做规划:会话里用 /permissions 切到 read-only。
  • 长期默认:在 ~/.codex/config.toml 里写 sandbox_mode = "workspace-write" 和 approval_policy = "on-request"。

底层实现:各系统怎么把门锁上

沙箱不是 Codex 或 Claude Code 从零写的一套机制,而是调用各操作系统自带的隔离能力:

系统CodexClaude Code
macOSSeatbelt(Seatbelt)(通过 sandbox-exec)Seatbelt
LinuxBubblewrap(bwrap) + seccomp(seccomp)(默认)Bubblewrap;seccomp 过滤器是可选项
WSL2用 Linux 实现Bubblewrap
原生 WindowsMXC,elevated / unelevated 为旧版后备不支持,命令不进沙箱,需改在 WSL2 里运行
别踩坑
  • 以为 Claude Code 在原生 Windows 上也能开沙箱。官方文档写明原生 Windows 上命令是不进沙箱执行的。原对话的表格漏掉了这一点。
  • 以为装了 Codex 在 WSL1 里也能用沙箱。从 Codex 0.115 起 Linux 沙箱改用 bwrap,WSL1 已不支持。
  • Windows 上 Codex 用的实现名称确实叫 MXC(官方文档原文),旧的 elevated / unelevated 是后备方案。

Full Access 是不是"没有沙箱"

是的。 Codex 文档对 danger-full-access 的描述就是"没有沙箱限制,去掉文件和网络边界";桌面应用的 Full access 等于 danger-full-access 加 never,也就是没有沙箱,也不再询问。CLI 里对应的旗标是 --dangerously-bypass-approvals-and-sandbox(别名 --yolo)。

剩下的只有操作系统原本的用户权限:Agent 能做到你这个用户能做到的一切,比如读 ~/.ssh、改 ~/Documents、任意联网。

别踩坑
  • “Full Access 只是放宽了一点限制”。它去掉的是整个文件和网络边界,同时关掉了审批。
  • 在本机直接对来路不明的仓库开 Full access。
  • 官方推荐的用法是:让 Docker、Dev Container 之类的外层容器充当安全边界,在容器里面再用 danger-full-access,免得套两层沙箱。

原对话还提到,Full access 不会让 Agent 自动获得管理员(root)权限。这一点符合操作系统的常识:进程以你的用户身份运行,不会自己提权。但官方文档里没有专门写这句话,未在文档中直接核实。

Claude Code:跳过权限 ≠ 关闭沙箱

Claude Code 的两套机制是分开的:

  • --dangerously-skip-permissions 等价于 --permission-mode bypassPermissions。这是一种权限模式(permission mode):跳过权限询问,连受保护路径(如 .git、.claude、.bashrc)的写入也直接放行。
  • /sandbox 不是权限模式,而是给 Bash(以及 PowerShell、Monitor)命令加一层由操作系统执行的边界。它默认关闭,可以在会话里运行 /sandbox 开启,或在 ~/.claude/settings.json 里设置 "sandbox": {"enabled": true}。

/sandbox 默认管住了什么

访问默认
写当前工作目录、每个用户的临时目录、你额外添加的目录;受保护路径仍然禁止写入
读几乎整台机器,包括 ~/.ssh、~/.aws/credentials 这类凭据
网络没有直连出口,所有连接走本机代理按域名白名单检查,白名单初始为空
环境变量从 Claude Code 继承,包括其中的密钥

它有两种模式:auto-allow 下,沙箱里的命令不用问你直接执行;regular permissions 下照常逐条询问。

别踩坑原对话里的偏差和遗漏
  • “默认沙箱并不禁止读取工作区外的文件”,这一点是对的,而且比想象的更宽:连 ~/.ssh 都能读。想保护凭据,要自己配 sandbox.credentials 或 filesystem.denyRead。
  • “Dangerous + Sandbox:沙箱仍然可以开启”,这句话只说对了一半。在 bypassPermissions 下:① 访问白名单以外的域名不再询问,直接放行;② Claude 可以用 dangerouslyDisableSandbox 在沙箱外重试命令,同样不询问。想让沙箱真正兜底,要开严格沙箱模式(allowUnsandboxedCommands: false),必要时再加 strictAllowlist。
  • 以为开了 /sandbox 就把整个 Claude Code 隔离了。沙箱只包住 Shell 命令;Read/Edit 等文件工具、WebFetch、MCP 服务器、Hooks 都在沙箱外,按权限规则管理。
  • “默认模式:按规则询问”。较新的 Claude Code(v2.1.283 起)在交互式终端里的默认权限模式已经是 auto,由一个分类器模型代你审查动作,不再是逐条询问的 manual。

拦截 rm -rf 算沙箱吗:三层防护

不算。沙箱不认命令,只认资源:它不会因为命令叫 rm 就拦,只看这条命令要改的路径在不在可写范围内。Claude Code 里和"删除"有关的保护其实有三层:

防护控制什么执行时机例子
权限规则(deny/ask/allow)哪些工具调用可以发生执行前,按命令文本匹配"deny": ["Bash(rm -rf *)"]
危险删除检查识别删除关键路径(critical path)的 rm/rmdir执行前,解析命令rm -rf /、rm -rf ~
沙箱命令运行起来后能碰到哪些文件和网络执行中,由操作系统强制执行不允许写 ~/.ssh

跳过权限后,rm -rf / 还会被拦吗

原对话说"部分关键路径删除仍会触发额外保护",方向对,但要补充细节(以 permission-modes 文档为准):

  • 在 bypassPermissions 下,被识别为关键路径删除的命令仍然会询问你:终端里有两分钟倒计时,超时即拒绝;在 VS Code 面板、桌面应用里直接拒绝。
  • deny 规则在所有模式下都生效,包括 bypassPermissions。
  • 但这层检查可以被关掉:设置环境变量 CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS=1 之后,rm -rf ~ 这类命令可以不经询问直接执行。
  • 文档明确说这层检查会漏判,只针对 rm/rmdir,其他命令同样可能删掉关键路径,所以它不能代替沙箱。
算一遍同一个项目里的两条删除

设定:开启 /sandbox,工作目录 ~/workspace/project-A,没有任何 deny 规则。

  1. rm -rf ~/workspace/project-A/build:目标在可写范围内 → 沙箱放行。文档特意提醒:沙箱里的命令照样能删掉你的工作目录。
  2. rm -rf ~/.ssh:目标不在可写范围内 → 操作系统拒绝写入,命令失败。

答:第一条在沙箱可写范围内,沙箱放行(要拦得靠权限规则);第二条越出写入边界,就算权限放行,沙箱也会拒绝。

别踩坑
  • 以为写了 Bash(rm -rf *) 的 deny 规则,就能拦住所有删除。规则按命令文本匹配,rm -fr、find … -delete、写个脚本再执行,都可能不匹配。
  • 以为沙箱会"禁止 rm 命令"。沙箱只管路径,不管命令名。
  • 防误删最可靠的组合:开沙箱限制写入范围 + 用 git 随时可回滚 + 对重要操作加 ask 规则。
先想一想

你用 claude --dangerously-skip-permissions 启动,并开了 /sandbox(没开严格模式)。Claude 想执行 curl https://unknown.example.com,这个域名不在白名单里。会发生什么?

想好了,看答案

会直接放行,不会问你。 在 bypassPermissions 模式下,访问白名单外的域名不再询问。另外 Claude 还能不经询问在沙箱外重试命令。想让沙箱真正兜底,需要开 strictAllowlist 和严格沙箱模式(allowUnsandboxedCommands: false)。

先想一想

Codex 用 --sandbox read-only --ask-for-approval never 运行,它想改一个文件。结果是什么?

想好了,看答案

改不了,而且不会问你。只读沙箱禁止写入,审批策略又是 never,没有人能批准越界,于是这个动作直接失败。

本篇小结

  • 沙箱管能不能,审批管问不问,两者各管一层。
  • Codex:read-only / workspace-write(默认不联网)/ danger-full-access(没有沙箱)。桌面应用的菜单选项是沙箱和审批打包好的组合,Full access 等于没有沙箱也不询问。
  • 底层实现:macOS 用 Seatbelt,Linux 用 bwrap(Codex 还加 seccomp),Windows 上 Codex 用 MXC;Claude Code 在原生 Windows 上没有沙箱。
  • Claude Code:--dangerously-skip-permissions 跳过的是询问,/sandbox 加的是边界;两者能叠加,但要开严格模式才算真正兜底。
  • 拦 rm -rf 靠权限规则和危险删除检查,沙箱只管路径。

拓展

以下内容来自 ChatGPT 结合我之前的提问(Pi、ADK、Agent Runtime)做的联想,不属于本篇正文,留作后续学习线索。

为什么 Agent 框架越来越重视沙箱。 普通 LLM 应用的链路是"用户 → 模型 → 文本回答";Agent 则是"用户 → 模型 → 工具调用 → 运行时 → 执行 Shell / Python / 文件操作 → 产生真实的系统副作用"。一旦能调用工具,Agent 就相当于拥有了操作电脑的能力,所以一个完整的 Agent 运行时通常要考虑这几块:

组件解决的问题
Agent决定做什么
Tool提供执行能力
Runtime管理工具的执行
Sandbox限制执行范围
Approval控制敏感操作的授权
Logging记录执行过程

可以把 Sandbox 看成 Agent Runtime 的"安全执行边界"。这和之前接触的 Pi、ADK、云端 Agent Runtime 的执行架构可以对照着看。

下一步可以学:Sandbox、Docker、VM 有什么区别。 三者都做隔离,但隔离的层次、实现原理和资源开销不同。Claude Code 文档里有一页 Sandbox environments,专门比较内置沙箱、开发容器、容器和虚拟机,可以作为起点。