首页 > 教程攻略 > ai教程 >AI Coding Agent 沙箱的设计原理解析

AI Coding Agent 沙箱的设计原理解析

来源:互联网 时间:2026-07-10 07:23:04

在日常工作中,AI Coding Agent 基本上已经成了离不开的工具。它们生成的代码质量往往比开发者自己写的还要好,这几乎成了行业共识。但在使用过程中会发现,几乎每个工具都有一组权限设置,每个档位对应 Agent 能触达的操作边界。

这套权限功能本质上就是一套运行在客户端的沙箱系统。身为开发者,自然很想搞清楚这背后的实现原理——顺便也琢磨一下,能不能自己动手搓一个专属的 Coding Agent 来干点脏活累活。

为什么需要沙箱

直接给 Agent 完整的真实环境?风险太大。Agent 一旦因为幻觉、误判或者被恶意注入危险指令,就可能执行不可逆的操作——比如把服务器上的关键数据删掉,读取本地的私钥信息,甚至偷偷把 .env 里的密钥发到未知服务器。

想象一下这些场景:让 AI 帮忙写个 Python 脚本导出数据,它顺手来了个 rm -rf,删掉了根本没让改的文件;让它跑项目里的测试代码,它直接把电脑上的各种私钥读走了;你以为写好 prompt 就能安心等结果,结果它暗中把密钥外传了。

当一个 Coding Agent 能够“自己输出命令并且自己跑”的时候,它就像一个黑盒——输出的命令根本没法预先控制。本质上,这就是把一段不可信代码放进你的电脑里直接执行。这种情况下,你敢直接按回车吗?别犹豫,这时候就需要沙箱工具。

沙箱做的事情很朴素:给 Agent 套上一件枷锁,让它带着镣铐去实现需求。它无法触碰没有被授权的事情,也就不会碰你的密钥、不会胡乱删除系统文件、不会在执行恶意脚本时向未知域名发送信息。

六条设计原则

不管是 Codex、Claude Code,还是自己动手实现一个 Coding Agent,沙箱设计都绕不开下面几条原则。理解了这些,后面再看具体实现会轻松很多。

默认拒绝,而不是默认放行


能不开放权限就不开放,用白名单思维而非黑名单。Codex 的 workspace-write 模式,默认只对当前工作目录开放写权限,其他目录默认只读;Claude Code 默认不允许请求任何公网域名,新域名第一次出现时会向用户请求授权。

最小权限


只给工作目录写权限,网络默认关闭,密钥文件(~/.ssh~/.aws.env)对 Agent 不可见。Claude Code 甚至能显式地把某些文件和环境变量设为 deny

隔离要分四个维度


文件系统、网络、进程、系统调用,一层层收束。只锁文件不够——Agent 能读能写,联网照样可以把数据发走;只锁网络也不够——它能改本地的 git config,直接把代码推送到未知仓库。四个维度必须一起限制才有效。

把“策略”和“怎么落地”分开


这一点设计得非常巧妙。写一套“我想要什么隔离级别”的策略描述,背后按客户端所在操作系统映射到不同的原生机制:macOS 用 Seatbelt,Linux 用 bubblewrap 加 seccomp,Windows 用受限令牌加 ACL。上层只管策略,下层管落地。

自治和安全的取舍


沙箱越严格,Agent 越是能连续跑不中断。反过来,如果每一步操作都需要人工审批,按了二十次 Approve 之后基本上就是在无脑点了——这才是真正的安全幻觉。沙箱本质上是用系统级边界来换取使用者有限的注意力。

纵深防御,别神话它


沙箱不是银弹,它只是第一道墙,需要配合权限模型、代码审查、依赖审计一起用。

落地:CodeX 和 Claude Code 沙箱方案探索

Codex:三套原生隔离,藏在统一策略后面

Codex 的沙箱是典型的“策略抽象 + 多平台实现”:

  • macOS 12+

    :用系统自带的 Seatbelt 加 sandbox-exec 工具,能根据 Agent 请求的权限等级动态生成 SBPL(Sandbox Profile Language)权限控制脚本。
  • Linux

    :bubblewrap(bwrap)加 seccomp 的组合。bwrap 用 mount namespace 把根目录设为只读,再把工作目录设为可写;seccomp 在进程内拦掉 connect / bind / ptrace 等系统调用。
  • Windows

    :用受限令牌(restricted token)加 ACL 来修改文件权限,再通过专门的 IPC 提权运行器来执行。

权限分级跨平台通用:ReadOnly(只读挂载)、WorkspaceWrite(工作区可写、敏感目录强制只读),Linux 上网络还有三档 Isolated / ProxyOnly / FullAccess

Claude Code:sandboxed Bash tool

Claude Code 也提供了 OS 级沙箱,而不是仅靠权限审批。它提供的是一个 sandboxed Bash tool,给 Bash 命令做文件系统和网络隔离,底层 macOS 用 Seatbelt、Linux/WSL2 用 bubblewrap(再加 socat 做网络袋里)。原生 Windows 不支持,得跑在 WSL2 里。(根据官方文档描述)

开启方式很简单:

  • 会话里敲 /sandbox,选 auto-allow 或 regular permissions;
  • 或者在 .claude/settings.local.json / ~/.claude/settings.json 进行配置:
    { "sandbox": { "enabled": true } }

隔离策略:

  • 文件系统

    :当前工作目录和会话临时目录默认可写,但全机可读。需要留意的是,默认情况下它还能读到 ~/.ssh 这类内容,除非开发者显式 deny。
  • 网络

    :默认不预放行任何域名,新域名首次出现会向用户请求放行权限;可以配置 allowedDomains 预放行。
  • 密钥

    :能显式 deny 文件或环境变量,比如把 GITHUB_TOKEN 设成 deny。

权限审批和沙箱是两层互补的关系:权限规则管“工具能不能跑”(所有 tool 通用,运行前生效),沙箱管“Bash 跑的时候 OS 层怎么隔离”(只管 Bash,运行时生效)。/sandbox 不是另一种权限模式,二者是叠在一起的。

对比

AgentCodexClaude Code
隔离层级OS 原生(Seatbelt / bwrap+seccomp)OS 级 Bash 沙箱(Seatbelt / bubblewrap)
策略抽象统一沙箱策略 + 多平台实现权限模型 + Bash 沙箱
默认行为--sandbox 等级(ReadOnly / WorkspaceWrite)配置开启;命令走权限审批
网络策略默认禁止(按等级划分,Linux 有 Isolated/ProxyOnly/FullAccess 不同等级)默认不预放行,新域名向用户请求;可配置预放行列表
平台覆盖macOS / Linux / WindowsmacOS / Linux / WSL2(原生 Win 不支持)
密钥保护敏感目录强制只读(.git/.agents/.codex)需显式配置禁用的文件或变量;默认电脑上所有文件可读

实测

Codex(macOS)选择 workspace-write 模式后,实际生成的 SBPL 大概如下:

(version 1) ; 声明版本号
(deny default); 默认拒绝
(allow process-exec*) ; 允许运行执行程序
(allow file-read* (subpath "/")) ; 全机可读
(allow file-write* (subpath "/path/workspace")) ; 工作区可写
(deny file-write* (subpath "/path/workspace/.git")) ; 敏感目录强制只读
(deny file-write* (subpath "/path/workspace/.agents"))
(deny file-write* (subpath "/path/workspace/.codex"))
(deny network*); 默认禁止通过网络外联

逐行看下来:deny default 是默认拒绝;file-write* 只放开工作区;.git 那三行强制只读,防止它改 git config;最后 deny network* 把外联掐了。

也可以自己在电脑上测试 sandbox-exec 禁止所有网络请求的情况。sandbox-exec 是 macOS 自带的命令,终端里直接使用:

sandbox-exec -p '(version 1)(allow default)(deny network*)' curl https://www.dimples.top/

第一条命令默认允许所有但禁用网络((deny network*)),使用 curl 请求自己的博客地址,发现直接无法解析域名。

去掉网络限制之后,请求恢复正常。命令如下:

sandbox-exec -p '(version 1)(allow default)' curl https://www.dimples.top/

Codex(Linux)的 bwrap 命令行大致是:

bwrap --unshare-user --unshare-pid --unshare-net --ro-bind / / --bind /path/to/workspace /path/to/workspace --bind /path/to/workspace/.git /path/to/workspace/.git --read-only

--unshare-net 直接把网络 namespace 摘掉,--ro-bind / / 把根挂载为只读,再 bind 回工作区可写。配合 seccomp 拦 connect / bind,四个维度就齐了。

Claude Code 开启 /sandbox 后,跑同一条 curl api.github.com,会看到它被袋里拦下、弹 prompt 问是否放行这个域名——这就是网络隔离在运行时生效的证据。

没有绝对的安全

必须认识到:沙箱不等于绝对的安全,不能过度神话。下面这些情况也能绕过沙箱直接提权进行非授权操作:

  • 供应链投毒

    :恶意 npm 包在沙箱内照样能外联、读取项目内自己的 .env(它就在工作区里,沙箱管不着);
  • 0day / 逃逸

    :OS 级沙箱也可能被逃逸(bwrap/seccomp 历史上都有过);
  • 配置错误

    :Codex 容器里主机不支持 Landlock/seccomp 时,沙箱可能静默失效;Claude Code 依赖没装(bubblewrap/socat)时默认只是 warning 然后直接运行,除非设了 failIfUna vailable: true

沙箱的价值不是消灭风险,而是把大概率翻车的事件压到一个可接受的范围。真要拿 Agent 写代码,还是得配合代码审查、依赖审计以及最小权限账号一起上。

总结

以上是关于 Coding Agent 沙箱的学习笔记。下一步打算拿学到的这些思路,自己搓一个专属的 Coding Agent 来干点脏活累活,到时候再写实战篇。如果这篇内容对你有帮助,欢迎在评论区聊聊你踩过 Agent 的坑——真实案例总是最有价值的参考。

相关下载