你的 AI 代理连 rm -rf / 都敢执行,把它关进沙箱
Docker Sandboxes 是 Docker 推出的工具,用来在本机的隔离 microVM(微型虚拟机)里运行 AI 编程 agent,由独立的命令行工具 sbx 管理。它之所以存在,源于一个让人不太舒服的默认设定:你在沙箱里启动 Claude Code 时,启动命令就是 claude --dangerously-skip-permissions。这不是谁粗心大意,而是因为沙箱本身就是为了让这种模式安全才建的(见 Docker 文档的 Claude Code agent 页面)。这个参数,正是本文要讲的问题所在。每个编程 agent 都有对应的开关:Codex 叫绕过审批,Cursor、Copilot 和 Gemini 则用厂商口中的 YOLO 模式。官方教程说得很直白——内置的沙箱集成会以「完全自主模式」启动 agent,你不需要自己再加那些参数。
完全自主确实有用。但与此同时,这也意味着一个巨大的破坏半径,你绝不会把它交给一个听大模型指挥的 shell 提示符。Docker 在 microVM 版本的发布文章里,一句话点明了这笔交易:「既然它们伤害不了你的电脑,那就让它们随便跑」(Docker 博客,2026 年 1 月)。
本文内容:
- 为什么光有容器已经不够了
- 真正跨越信任边界的是什么?
- 10 分钟完成配置
- 怎么控制 agent 能访问什么?
- 哪种沙箱模式适合你的工作流?
- 常见问题
关键要点
- Docker Sandboxes(
sbx)把每个编程 agent 跑在各自独立的 microVM 里,有独立的内核、文件系统和 Docker daemon。 - agent 在 VM 内部拥有 sudo 权限,但除了你明确共享的文件之外,它碰不到宿主机(见安全模型)。
- 你的工作目录是例外:直接挂载是读写的,所以 agent 仍然能删掉你的工作树。在意这点的话,用
--clone。 sbx命令行工具和本地算力免费,商用也免费,并且不依赖 Docker Desktop(见定价)。- 网络策略的默认值比 VM 本身更关键:在 Locked Down 预设下,连你的模型厂商 API 都会被挡住,除非你放行。
为什么容器已经不够用了
面对「我的智能体很危险」这个问题,常见回答是「把它塞进容器里」。如果危险的东西只是构建脚本,这个回答还算合理。但编码智能体完全是另一回事,原因很简单:它会跟你对话,自己决定下一步跑什么,而且在你起身去倒咖啡的时候还在继续干活。
容器时代的两个假设在这里都不成立了。
第一,容器共享宿主机的内核。命名空间(namespace)和控制组(cgroup)能提供很多隔离,但内核级别的隔离边界不等于硬件级别的隔离。微虚拟机(microVM)是一种轻量虚拟机,有自己独立的内核,由 hypervisor 启动,从而给智能体一道由硬件强制的边界。Docker 在其安全模型里把微虚拟机称为「主要的信任边界」。智能体在虚拟机内部拥有完全控制权,包括 sudo,而虚拟机边界正是阻止它触及其他东西的那道墙。
第二,一个能构建容器的智能体,必然想要访问 Docker socket(套接字)。这一点常常被人忽略。我在关于 Compose 健康检查的那篇文章里谈过这类问题:能访问宿主机 Docker 的工具,就等于能在宿主机上拿到 root,因为 docker run -v /:/host 这条命令永远摆在那里。
沙箱用一种不那么常见的方式解决了这个问题。每个沙箱都在虚拟机内部运行一个私有的 Docker 守护进程(daemon),于是智能体可以尽情构建镜像、拉取、运行容器,同时对宿主机的守护进程没有任何访问权限。Docker 声称这在各种沙箱方案里是独一份的,我目前也没找到反例(Docker 博客、架构文档)。
与此同时,一个沙箱就是一个真实的 Linux 环境。智能体可以安装软件包、编辑文件、启动服务。当某次运行跑偏了,你把整个沙箱删掉,几秒钟就能启动一个新的。这个「用完即弃」的循环,比任何单项功能都更能改变你愿意放手给予多少自主权。
究竟有哪些东西会越过信任边界?
这部分值得好好消化,因为在大多数讨论里,「它已经沙箱化了」这句话承担了太多含糊的含义。安全模型那一页倒是把什么进得来、什么出得去、什么永远不跨越,讲得异常具体。
我发现它是整套文档里最有用的一页,也是这篇文章的由来。
进入虚拟机的内容
- 你的工作区目录:在项目文件夹中执行
sbx run,或传入一个路径时,这个目录会被带进沙箱。直接挂载是读写模式,Agent 的修改会实时落到你的工作树里。加上--clone后,仓库以只读方式挂载,Agent 在沙箱内的私有克隆上工作。无挂载沙箱则完全不共享任何主机目录。 - 凭证——其实不算真正带进去:主机侧的代理会向出站请求注入认证头。原始凭证值从未进入虚拟机。这是一个很巧妙的设计:Agent 能用你的 GitHub 或 Anthropic 认证,却从不持有 token 本身。
- 到允许目的地的出站 TCP,经由主机代理转发。
- 共享技能库:默认以只读方式挂载在 Agent 的技能目录下。
回到主机的内容
- 工作区文件变更(直接挂载时即时生效)。
- 你放行的出站连接。
- 技能库写入——仅当你把技能挂载改为读写模式时才会发生。
永远不会发生的事
- 工作区和技能库之外的主机文件系统。
- 主机的 Docker 守护进程。
- 直接接触主机的网络接口。沙箱之间也无法通过网络互相通信。
- 出站 UDP 默认被阻断,除非你开启一个实验性开关;ICMP 则完全禁止。
唯一需要老实说明的注意事项,也是 clone 模式存在的原因
直接挂载是读写模式。文档写得很直白:你的项目目录是沙箱边界之外的例外,Agent 可以修改或删除它的文件(教程)。Andrew Lock 亲手用这种方式跑 Claude Code 后,也得出同样结论。用他的话说,沙箱只能访问你的工作目录,“所以是的,它可以把你的 git 仓库删掉”,而这基本上就是它能造成的全部破坏(andrewlock.net)。因此,要么把工作纳入版本控制,要么用 clone 模式,或者两者都做。
10 分钟完成安装
sbx 是负责创建和管理沙箱的独立 CLI。主机上不需要 Docker Desktop 或 Docker Engine,本地沙箱算力免费,商业用途也免费(安装文档,定价)。按你的操作系统安装即可。
macOS 用 Homebrew,Windows 用 winget,Ubuntu 则从 Docker 的 apt 仓库安装 docker-sbx:
$ brew trust docker/tap && brew install docker/tap/sbx # macOS
$ winget install -h Docker.sbx # Windows
$ curl -fsSL https://get.docker.com | sudo REPO_ONLY=1 sh # Ubuntu,仅添加仓库
$ sudo apt install docker-sbx
然后用 Docker OAuth 登录一次:
$ sbx login
接着在项目目录里启动一个 agent:
$ cd ~/my-project
$ sbx run --name my-sandbox claude
首次运行会拉取 agent 模板(docker/sandbox-templates:claude-code),需要等一会儿。之后,它会让你为所有沙箱选一个默认网络策略:Open(全部放行)、Balanced(默认拒绝,只放行常见开发目标)或 Locked Down(除非你手动放行,否则一律拒绝)。入门指南建议从 Balanced 起步。
Claude Code 随后在沙箱内启动。如果你有 Claude 订阅,在会话里输入 /login。OAuth 令牌留在宿主机上,绝不会存进沙箱。如果你改用 API key,sbx secret set anthropic 会把它存在宿主机一侧,代理可以直接使用,不会暴露给 agent。
给 agent 派个真实任务。趁它跑着,打开第二个终端看看情况:
$ sbx ls
SANDBOX AGENT STATUS PORTS WORKSPACE CREATED
my-sandbox claude ● running ~/my-project 2m
工作区(workspace)那一列,就是 agent 能看到的你机器上的全部文件系统。想自己进到 VM 里敲个 shell:
$ sbx exec -it my-sandbox bash
你会落进主工作区,也就是一台 agent 拥有 sudo 权限的 Linux 机器。随便逛逛,跑跑 ps,看看 agent 都装了什么。到这一步,模型才真正明白:它面对的是一台完整的计算机,而不是一个 chroot。玩完之后,几个生命周期命令的用途跟名字一样直白。sbx stop 暂停沙箱,里面的一切保留,重启后照旧;sbx rm 删掉沙箱和里面所有东西,而你宿主机上的工作目录不受影响。另外,不带参数直接运行 sbx,会打开一个交互式面板,能看到每个沙箱实时的 CPU 和内存占用、网络面板,还有快捷键用来接入(attach)、进 shell、停止或删除。
把 claude 换成 codex、copilot、cursor、gemini、opencode、kiro 或 droid,用法完全一样。完整支持列表在 agents 页面,那里还有一个不带任何 agent 的 shell 模板,供你手动搭建环境。
怎么控制 agent 能访问什么?
文件系统隔离只是一半,另一半是网络出口。这一步,就轮到首次运行时选的那个预设发挥作用了。
网络策略(network policy)是沙箱对出站连接施加的白名单。查看当前生效的规则:
$ sbx policy ls
再放行一个主机:
$ sbx policy allow network registry.npmjs.org
三个预设默认拦截的东西各不相同,而这些差异,就决定了一次运行的整体安全态势:
| 预设 | 出站流量 | 模型提供方 API | 适用场景 |
|---|---|---|---|
| Open | 全部允许 | 允许 | 机器上没什么可保护的可信任务 |
| Balanced | 默认拒绝,常见开发站点放行 | 允许 | 日常开发;文档推荐的起点 |
| Locked Down | 全部阻断 | 在你放行之前一律阻断 | 不可信或无人值守的任务;只放行任务真正需要的 |
入门指南里有个细节我很欣赏:在 Locked Down 模式下,连你的模型提供方 API 都是被拦住的,除非你明确放行。这个小细节,其实就是整套安全模型的缩影。
锁定模式(Locked Down)意味着:如果一个 Agent 失控了,它没法偷偷对外发起连接、没法把工作区的东西传到粘贴站上、也没法悄悄下载二阶段载荷——除非那个目的地是你放行的。对于你不太放心的任务,流程是这样的:先锁定,然后只放行 api.anthropic.com(或者你所用的模型服务商的接口地址),再加上任务需要的软件包仓库,别的都不放。一份你能用一条命令读完的白名单,胜过你早已习惯顺手点过去的权限弹窗。
还有两个相关的控制项值得了解。第一,密钥不要用环境变量:sbx run 上的 -e VAR=value 是能用的,但文档提示环境变量对沙箱内的进程可见,所以对于 API key,用 sbx secret set 把值留在宿主机上,由代理把它注入到对外请求里。第二,给构建用的镜像仓库凭据:沙箱里的 Docker 守护进程会用你的 sbx 登录会话去拉 Docker Hub 的镜像,但换成别的仓库,你得先把拉取凭据存好。例如 gh auth token | sbx secret set --registry ghcr.io --password-stdin。否则,私有镜像会被当成匿名拉取而失败。
哪种沙箱模式适合你的工作流?默认模式(在项目目录里跑 sbx run claude,读写挂载)是大多数情况下的正确选择:你能看着 Agent 的改动以普通 Git diff 的形式出现在工作区里,想留的再提交。使用指南里记录了其余的用法:--clone 会把你的仓库只读挂载,并给 Agent 一份私有克隆。这是针对同一个仓库同时跑多个 Agent 时该用的模式,也是你哪天不信任 diff 时该用的模式。克隆放在沙箱里,删掉沙箱,克隆也没了。无挂载沙箱(sbx create --name scratch claude,不带路径)完全不共享宿主机目录,Agent 在虚拟机内的 /home/agent/workspace 里干活,文件在多次停机之间会保留,用 sbx cp 进出搬运。适合想彻底用完即弃的实验。--rm 则让整个会话变成一次性:Agent 一退出沙箱就删除,sbx run 返回 Agent 的退出状态。这就是工具的 CI 形态。
分离式沙箱(sbx run -d)在会话结束后仍会继续运行,配合已发布的端口,正好适用于 agent 正在运行你想探查的服务这种情况。sbx move 可以在 Docker 托管的云基础设施上重建沙箱的文件系统,也能反向迁回。这样一来,一次繁重的构建就能从你的笔记本迁移出去,而环境本身完全不变。这份清单也如实反映了该工具的定位:沙箱是面向笔记本和工作站的产品,云功能只是应急出口,不是机群管理平台。本地使用是免费档,而这恰恰是最重要的部分:在“agent 能破坏的东西”和“其他一切”之间划出一道硬边界。
FAQ
使用 sbx 需要 Docker Desktop 吗?
不需要。CLI 可以独立安装,本地沙箱计算免费,商业用途也不例外。云端计算是单独的按量付费订阅,组织范围的策略治理则是另一个付费方案(见定价)。
沙箱里的 agent 还能毁掉我的代码吗?
在直接挂载模式下,能。工作区是读写共享的,agent 可以删掉里面的文件。正因如此,文档才建议你把工作放在版本控制下,而当你希望保护仓库时,可以用 --clone。
这和直接把 agent 跑在容器里有什么区别?
容器共享宿主内核;如果给它 Docker socket,它实际上就掌控了宿主机。沙箱是自带内核和独立 Docker 守护进程的 microVM,所以“构建并运行容器”和“与宿主机隔离”不再互斥。
agent 能上网吗?
只能通过你允许的网络策略上网。沙箱无法直接访问你的宿主网络,彼此之间也不能通信;除非开启实验性功能,否则出站 UDP 被阻断,ICMP 也被阻断。
我的 API 密钥存在哪里?
存在宿主机上。代理会把凭证注入出站请求,原始值永远不会进入 VM。相比之下,环境变量在沙箱内可读,所以敏感内容请用 secrets。
真正重要的五条命令
安装、登录、运行、查看、删除:
brew install docker/tap/sbx(或对应你操作系统的安装方式)
sbx login
sbx run claude
sbx ls
sbx rm my-sandbox
这篇文章剩下的内容,都是围绕这个循环展开的细节。现在,你做的取舍已经摆到明面上,不再是隐含的了。Agent 以完全自主的方式运行,拥有 sudo 权限,运行在一台它无法逃逸的机器上;一旦运行出了问题,你一条命令就能把它删掉。另一种做法是,你训练自己在不细看的情况下就批准权限提示,而那台机器上还存着你的 SSH 密钥。我更愿意让哪个跑一整夜,心里有数。
以上内容已对照 docs.docker.com(Sandboxes 概览、安装、入门、使用、安全模型、架构、Agent、Claude Code Agent 页面)、Docker Sandboxes 产品页和 Docker 发布博客文章核实,均检索于 2026-10-25。每条事实性陈述都链接到其来源。我没有在这台机器上实际运行演练;每条陈述都可追溯到所链接的文档,凡是无法核实的地方,我都会标明。
来源
以上每条陈述都可追溯到以下主要来源。凡是无法亲手核实的地方,文章都有说明。
Docker 文档,Claude Code Agent 页面官方教程
Docker 博客,2026 年 1 月安全模型定价架构文档
microVM 信任边界的剖视图:什么进得去、什么回得来、什么不会
andrewlock.net 安装文档入门指南 Agent 页面使用指南
四种沙箱工作模式的等距示意图:直接挂载、克隆、无挂载和 d
GitHub
关于作者
Kunal Das 边学边写运维工程笔记,始终以一手资料为依据。联系方式:GitHub 和 Dev.to。关注 Docker 标签,阅读本系列的后续文章。
Docker Sandboxes 是 Docker 推出的工具,可以让你在自己机器上的隔离 microVM(微型虚拟机)里运行 AI 编程 Agent,由独立命令行工具 sbx 管理。
它之所以出现,是因为有一个默认设置让人不太舒服:在沙箱里启动 Claude Code 时,启动命令就是 claude --dangerously-skip-permissions。这并不是因为有人鲁莽,而是因为沙箱本身就是为了让这种模式变得安全而设计的(Docker 文档,Claude……)