跑个 Docker 容器,就是 Agent 沙箱了吗?还差关键一层
摘要
把 Coding Agent 放进 Docker,保护的首先是宿主机,不等于限制它能把读到的数据带到哪里。Vercel 与 Docker Sandboxes 的新做法,都把网络访问边界和凭据控制放进了 Agent Sandbox。
我会借 Vercel 的新文章和 Docker Sandboxes 讲清一个很容易混淆的判断:跑个 Docker 容器,算不算 Agent Sandbox?
答案不是“Docker 没用”。容器先解决了进程和文件系统分开的问题;但对一个会读仓库、日志和 Issue,再自己写代码执行的 Agent 来说,这还没有回答“它能连到哪里”。安全工程里常把这一层叫作 egress 或“出网控制”,换成更直白的话,就是网络访问边界。
8 月 11 日,Vercel 用一篇题目很直白的文章提醒了另一半事实:不受信任的代码即使无法逃出 MicroVM,仍可能通过网络访问带走它在里面读到的东西。Docker 的 Docker Sandboxes 则把网络策略、宿主侧代理和凭据注入放到了产品正中央。两者都在说同一件事:隔离不是一个技术名词,而是一组必须逐项回答的边界。期望对大家有所帮助。
容器不是完整的边界
容器、命名空间或 MicroVM 首先回答的是一个很重要的问题:这个程序能访问运行它的那台机器上的什么东西?它们可以把进程、文件系统和宿主隔开。
但网络问的是另一件事:这个程序能够访问或攻击什么?如果 Agent 读到的代码、日志或 Issue 里藏着提示注入,诱导它把私有文件上传到一个外部地址,恶意程序并不需要突破虚拟机。只要它能读到文件,也还能自由发起网络请求,这条路径就已经存在。Vercel 在文章里把这种差别说得很清楚:计算隔离容住了进程,却没有约束进程造成的后果。

上图不是在比较 Docker 与 Vercel 谁的隔离更强,而是把两个问题拆开:容器防止程序横向碰到宿主;网络策略决定它纵向能把数据送到哪里。因此,“没有网络边界”不是指沙箱技术失效了。内核、容器或 MicroVM 可能工作得完全正确;失效的是对完整攻击路径的想象。DNS、代理、私网地址、允许访问的包仓库,以及刻意开放的每一个目的地,都会构成这个边界的一部分。
“出网”真正该管的是什么
把网络彻底断开当然最容易理解,但大多数 Agent 又确实需要联网:拉取仓库、安装依赖、调用模型、读一个数据库,或者提交结果。于是实际可用的方案不是“全开”与“全关”二选一,而是把连接拆成可以授权、收回和审计的能力。
Vercel 给出的工作流很具体:可信的准备阶段可以访问包仓库,开始运行生成代码前收紧规则;只给模型服务一个域名;只让某个对象存储桶作为输出目的地;让沙箱访问一个私有服务,同时拒绝其余私网地址。它的 Sandbox 防火墙在 MicroVM 外部的宿主侧拦截 TCP 和 DNS,请求不需要由 Agent 自己改写代理配置。Vercel 的防火墙文档 也说明了域名规则与 CIDR 规则可以共同约束目的地。

这里还有一个常被忽略的转折:不要把长期 API Key 作为环境变量塞进 Agent 的执行环境。Vercel 的做法是在边界处、仅对匹配的目标请求注入认证头;凭据不进入 MicroVM,也就不会随着文件、环境变量或日志一起被复制出去。被授予的不是“一串以后也能拿走的钥匙”,而是“向这个地址、以这个方法完成这次调用”的能力。
这比“限制 Agent 能执行哪些命令”更贴近风险本身。模型和生成代码可以很强,策略仍应该在它们无法关闭的位置执行。
Docker Sandboxes 把边界搬到本机
Docker 的新产品值得看的地方,不只是它让 Claude Code、Codex 等 Coding Agent 能够在本地无人值守地运行。它明确把每个 Agent 放进独立 MicroVM,配有自己的 Docker daemon、文件系统和网络;Agent 可以在里面安装包、用 sudo,甚至再启动容器,而不是获得宿主 Docker daemon 的控制权。Docker 的架构说明 将这种方案与“把 Docker socket 挂进容器”的做法区分开来。
更关键的是网络路径。Docker 的文档写明,沙箱所有 HTTP 和 HTTPS 网络流量会先经过宿主侧代理;规则是默认拒绝,原始 TCP、UDP 和 ICMP 在网络层被阻断。允许访问的域名由策略决定,认证头也由这个代理注入,原始密钥不进入 VM。安全模型 还特别提示:默认允许域名里可能存在较宽的通配符,需要用 sbx policy ls 检查并移除不需要的规则。
| 已有的隔离 | 仍要核实的边界 |
|---|---|
| 容器内有独立进程与文件系统 | 网络目的地是否默认拒绝 |
Agent 能跑 sudo,但不碰宿主机 | 主机外的 HTTP、DNS 与私网访问是否受限 |
| 把 API Key 放进环境变量 | 是否在代理边界按目标请求注入短权限 |
| 挂载当前工作区方便协作 | 挂载本身是否成了回到宿主的写入通道 |
最后一行尤其不能略过。Docker Sandboxes 的默认 direct mount 会让 Agent 对当前工作树的改动实时反映到宿主;要获得工作区边界,应使用 --clone,让仓库以只读方式进入 VM,Agent 在私有副本中工作。Docker 也提醒,MCP server 是明确的跨边界集成点:本地 stdio MCP server 实际跑在宿主侧,不能自动继承 VM 的隔离。这里的好消息不是“MicroVM 万能”,而是产品把哪些东西穿过了边界写出来了。
启动 Agent 前,逐项问清楚
如果你只是想在本机试一次 Agent,隔离环境已经比直接给 --dangerously-skip-permissions 好很多。但当 Agent 会接触私有仓库、生产数据或长期凭据时,我会在启用前逐项问:
- 它能读到哪些目录?工作区是直接挂载,还是私有 clone?
- 它到底能连接哪些域名和地址段?没有命中的请求是否默认被拒绝?
- DNS、非 HTTP 协议、私网和 localhost 是否也在规则里?
- 安装依赖的联网阶段,能否在生成代码运行前结束?
- 凭据是否留在沙箱外,并且只匹配到必要的路径、方法与操作?
- MCP、Git hook、IDE task 和共享技能目录,有没有成为另一条宿主侧通道?
这份清单比“我用了容器吗?”要难一点,因为它要求把一次 Agent 任务看成不断变化的权限集合。但这也是今天 Vercel 与 Docker 的共同信号:隔离并不等于容器化。一个更完整的 Sandbox,必须同时定义计算能在哪里跑、文件能在哪里读写、网络能到哪里,以及凭据究竟在什么时候、为哪一个请求生效。
当这些答案能被策略固定在执行环境外,Agent 才可以少一点确认弹窗,多一点真正可控的自主性。
相关文章
2026年9月6日
【DSH插件开发笔记】为新版本 DSH 升级了我的 dsh-lark 插件
从 settingsNamespace 导出变化导致启动失败,到旧 workspace 配置在消息处理阶段暴露问题,这是一次发生在 DSH RC 版本升级中的兼容性调试记录。
2026年9月6日
我给 DeepSeek DSH 做了个 zvec-grep 插件
从一次代码语义搜索实验,到一个自动索引、可见状态、后台增量更新的 DeepSeek DSH 插件,我在 dsh-zvec-grep 开发中做了哪些取舍。
2026年8月27日
34.7k stars 的科研 Skill,开始长成一个本地研究工作台
Scientific Agent Skills 登上 GitHub Trending 的背后,是 163 个科研流程与一款本地 AI co-scientist 的组合。它把 Agent 从“回答问题”推进到可检查的研究过程。
最近一封 · Sample
Codex 怎样用 apply_patch 编辑文件?
“Codex 的 apply_patch 不只是把几行文本写回文件。本文从 Patch、diff 和 hunk 讲起,逐层拆解它的语法、解析、上下文匹配、预验证、权限评估、文件系统执行与部分失败边界。”
—— william
来信
里面装的是
- 新文章 — 写完一篇就寄一封,不攒货
- 这周读到的、看到的、好用的工具
- 正在折腾的实验,附带翻车记录
约莫 1–2 周一封 · 随时退订
合作伙伴
CompeteMap — 英国及爱尔兰学生竞赛一站式搜索
数学、编程、科学、写作等各类竞赛信息汇总,支持按年龄和科目筛选,再也不错过报名截止日。