让 AI 编程助手改代码、装依赖、跑测试,效率确实高。但只要它能在你的机器上执行命令,一个必须回答的问题就摆在那里:它执行了 rm -rf ~/ 怎么办?更糟的场景是提示词注入——Agent 读到一个藏了恶意指令的文件,把里面的内容错当成操作指令来执行,悄悄翻你的 SSH 私钥往外发。Agent 的能力边界和权限边界完全是两回事,沙箱就是给后者兜底的工程手段。
沙箱解决的不是"不听话",是"越界"
一个常见误区是用权限弹窗代替沙箱:每条命令都问用户。Agent 一次任务跑几十条命令,用户点"允许"点到麻木,之后不再细看直接放行——这叫审批疲劳,安全机制反而被习惯性点击架空了。
沙箱换了个思路:提前划定活动范围,范围内自动执行,越界才拦截。范围通常由两个维度构成:
文件系统隔离——允许读什么、允许写什么,分开授权。Agent 可以读项目代码和系统依赖库,但写权限只给项目目录;SSH 私钥、shell 配置文件这类敏感路径直接禁访。
网络隔离——文件管得再死,数据还是能从网络漏出去。常见实现是代理加域名白名单:npm install 走官方源放行,其他出网请求一律拦下。
两个维度必须同时上。只做文件隔离,读到的敏感信息照样能 POST 出去;只做网络隔离,本地文件照样能被翻。
靠提示词说"不许"没有用
沙箱的可靠性分两个层次,混起来会出事故。提示词层面的约束是"你不应该这么做"——模型可以不遵守,注入攻击专门绕这个。操作系统层面的隔离是"你即使想这么做,系统也不允许"——这才是安全边界。
主流工具的实现印证了这个分层:macOS 上用 Seatbelt 限制进程的文件系统访问,Linux 上用 bubblewrap 借 Namespace 造隔离环境。再往上还有两个档位:gVisor 在用户空间拦下大部分系统调用,减少不可信代码直接触碰宿主机内核;Firecracker 这类微虚拟机干脆给独立内核,面向执行陌生用户代码的多租户云端场景。
选型没有越强越好,只有匹配:本地个人 Agent 用轻量沙箱顺手就行;云端跑陌生代码,微虚拟机起步。
用 bubblewrap 画一个最小围栏
Linux 上手搭一个能跑的最小沙箱,感受一下"围栏"长什么样:
bwrap --unshare-all \
--ro-bind /usr /usr \
--bind /home/user/project /workspace \
--dev /dev --proc /proc \
/bin/bash
--unshare-all 切断全部共享(含网络),--ro-bind 把系统目录只读挂进来,--bind 只把项目目录映射为可写。此时沙箱内的进程根本"看不见"你的主目录——不是它不敢访问,是文件系统视图里就没有。
四种翻车方式,每一个都见过真实案例
沙箱不是装上就安全,这些缺口都能让围栏形同虚设:
- Docker socket 挂载:把
/var/run/docker.sock映射进容器,等于把宿主机的 root 权限双手奉上——容器内可以拉起特权容器反控宿主机。Agent 环境里这个挂载必须默认禁止; - 网络白名单开太宽:允许了某个中转域名,恶意程序借它二次转发,数据照样出去;
- 范围内作恶:围栏内 Agent 依然可以删光项目目录。沙箱管边界不管质量,代码仓库的版本控制、备份照旧不能省;
- 降级静默放行:最阴险的一种——沙箱组件启动失败,程序"贴心地"降级为无沙箱继续跑,隔离凭空消失还无人知晓。
对第四条,工程上的对策是失败即拒绝:Agent 启动流程里先放一个探针(尝试写一个越界路径),确认写入被拦截后才放行业务执行;探针失败了直接终止启动,绝不带病运行。再配合三条原则——最小权限、默认拒绝、纵深防御(沙箱之外仍有审批、审计、备份)——才算把安全链补齐。
一句话总结:沙箱的目标不是让 Agent 什么都不能干,而是让它只能干分内的事。能力给足,边界焊死,这两件事由不同的机制负责,缺一不可。

评论0