最近在看 OpenClaw 的文档时,我遇到了一个词:Sandbox(沙箱) 。
文档里提到,当 AI Agent 执行代码时,可以让这些代码运行在 Sandbox 里面,以限制它能够访问的文件、进程和网络。
我以前对 Sandbox 的理解很简单:
Sandbox 不就是一个虚拟环境吗?
后来仔细研究了一下,发现这个理解并不准确。Sandbox 和虚拟机、Docker、Python 的 venv 都不是同一个概念。如果一定要用一句话解释 Sandbox,我现在觉得这样说更好:
Sandbox 是人为划定的一块受限制的代码执行区域。程序可以正常运行,但是它能够做什么,被控制在一个规定的范围之内。
理解了这句话就理解了 Sandbox 的核心。
1. 先从一个生活中的例子说起
假设有一天,你请了一个维修工到家里修水龙头。最简单的做法,是直接把家门钥匙交给他。这样,他当然可以走进厨房修水龙头。但是与此同时,他理论上也可以:
进入卧室
打开你的抽屉
翻看文件
拿走贵重物品
甚至把家具搬走
问题出在哪里? 不是维修工没有能力修水龙头,而是:
为了完成一个很小的任务,我们给了他过大的权限。
有没有一种更安全可靠的做法呢?有的。我们可以专门准备一个工作区域,只把坏掉的水龙头和维修需要的工具放进去:
我的家
┌───────────────────────────────┐
│ │
│ 卧室 私人文件 │
│ │
│ 保险柜 电脑 │
│ │
│ ┌────────────────┐ │
│ │ 工作区域 │ │
│ │ │ │
│ │ 水龙头 │ │
│ │ 扳手 │ │
│ │ 螺丝刀 │ │
│ │ │ │
│ │ 维修工 │ │
│ └────────────────┘ │
│ │
└───────────────────────────────┘
维修工仍然可以工作,但同时他能接触到的东西变少了。这就是 Sandbox 最核心的思想:
不是不让程序运行,而是限制程序能够影响的范围。
这也是为什么它叫 Sandbox。
可以把它想象成儿童玩的沙坑。孩子依然可以挖坑、堆城堡、把沙子弄得到处都是,但是这些活动最好都发生在沙坑里,而不是在整个客厅里。
2. Sandbox 不是"虚拟环境"
这里很容易产生一个误解。有人第一次看到 Sandbox,会把它理解成:
ini
Sandbox = 虚拟环境
这其实并不准确。更准确的关系应该是:
markdown
Sandbox
│
一种安全目标
│
┌───────────┼───────────┐
↓ ↓ ↓
Container VM OS 安全机制
Docker 虚拟机 Namespace
seccomp
权限控制
Sandbox 描述的是"我要限制这段程序能做什么"。
至于怎么做到,则有很多办法。 比如:
- Docker Container
- Linux Namespace
- seccomp
- AppArmor / SELinux
- 虚拟机
- WebAssembly
- 操作系统权限机制
都可以成为实现 Sandbox 的一部分。因此:
Sandbox ≠ Docker
Sandbox ≠ 虚拟机
Docker 可以用来实现 Sandbox,虚拟机也可以用来实现 Sandbox。甚至一个普通进程,如果操作系统对它进行了严格的权限控制,也可以成为某种 Sandbox。
所以 Sandbox 更像一个安全模型,而不是某一种具体技术。
2.1 那"Sandbox是真实环境,只是它的范围受限"这个理解对不对?
这个理解已经比较接近了,但是最好再修正一下:有些 Sandbox 确实直接运行在真实操作系统之上,只不过受到权限限制。
例如:
css
真实 Linux
│
├── Chrome
├── VS Code
├── MySQL
│
└── 被限制的进程
↑
Sandbox
但是还有一些 Sandbox 会使用容器甚至虚拟机:
真实机器
│
↓
虚拟机
│
↓
Container
│
↓
受限制的程序
所以,判断一个东西是不是 Sandbox,关键不是问:
"它是不是真实环境?"
而应该问:
"这个程序的能力是不是被限制在了一个边界之内?"
这才是 Sandbox 的本质。
3. Sandbox 到底限制了什么?
如果以后再看到一个系统宣称自己支持 Sandbox,可以先问它四个问题:
文件能看到多少?
进程能看到多少?
网络能访问哪里?
系统权限有多大?
基本就能判断这个 Sandbox 到底做了什么。
3.1 文件系统
假设我的电脑里面有这些东西:
arduino
/home/me/
│
├── project/
├── Documents/
├── Pictures/
└── .ssh/
└── id_rsa
我现在需要一个程序修改:
project/
最危险的做法是:
arduino
程序
↓
整个 /home/me
这样它理论上既能修改项目,也能读取:
bash
Documents
Pictures
.ssh/id_rsa
Sandbox 可以只暴露这个特定的项目目录:
bash
真实电脑
/home/me/
│
├── Documents ← 看不到
├── Pictures ← 看不到
├── .ssh ← 看不到
│
└── project
│
│ 映射
↓
┌────────────────────┐
│ Sandbox │
│ │
│ /workspace │
│ │
└────────────────────┘
于是程序看到的世界可能只有:
bash
/workspace
这里有一个很有意思的地方。对于 Sandbox 里的程序来说,不一定是:
"我知道
.ssh存在,但是没有权限读取。"
有时候甚至是:
"在我的世界里,根本就没有这个目录。"
它看到的是一个经过裁剪的文件系统视图。这也是"隔离"的含义之一。
3.2 进程
再比如你的电脑正在运行:
css
Chrome
VS Code
MySQL
Redis
Node.js
一个直接运行在宿主机上的程序执行:
ps aux
可能看到大量系统进程。如果权限足够,它甚至可能影响这些进程。但是进入 Sandbox 以后,它看到的可能变成:
Sandbox
│
├── bash
├── node
└── npm
它甚至不知道外面还有 Chrome 和 MySQL。这就是进程隔离。
3.3 网络
Sandbox 还可以限制网络。
例如:
Sandbox
│
├──── example.com ✅
│
├──── api.xxx.com ✅
│
└──── 其他互联网 ❌
甚至可以直接:
Sandbox
│
X
Internet
完全禁止联网。这在运行不可信代码时特别重要。假设程序意外读取到了一个 API Key:
sk-xxxxxxxx
攻击者还希望把它发送出去:
读取密钥
↓
连接网络
↓
上传到服务器
如果前一步文件权限没有拦住它,网络限制还可以继续阻止后一步。安全系统往往不是依靠一道门,而是很多道门。
3.4 系统权限
最后,还有一个更底层的问题:
即使进入 Sandbox,程序能够调用操作系统的哪些能力?
Linux 程序最终很多操作都要经过系统调用:
sql
应用程序
↓
System Call
↓
Linux Kernel
↓
磁盘 / 网络 / 进程 / 内存
Sandbox 可以继续限制这些能力。例如限制:
挂载文件系统
修改系统时间
加载内核模块
访问某些设备
创建特殊网络 Socket
操作其他进程
Docker 里面常见的 capabilities、seccomp 等机制,就是在继续收紧这一层权限。于是一个比较完整的 Sandbox,可能是:
markdown
程序
│
↓
┌───────────────┐
│ Sandbox │
│ │
│ 文件限制 │
│ 进程限制 │
│ 网络限制 │
│ 权限限制 │
│ 系统调用限制 │
└───────────────┘
│
↓
Operating System
现在再回头看"Sandbox"这个词,就会发现它描述的其实是: 一道安全边界。
4. Sandbox、Docker 和虚拟机到底是什么关系?
这三个概念经常一起出现,所以很容易混淆。我们可以做一个简单的对比。
| 概念 | 主要解决的问题 |
|---|---|
| Sandbox | 限制一段程序能够做什么 |
| Docker Container | 隔离程序的运行环境 |
| Virtual Machine | 虚拟出一台完整计算机 |
Python venv |
隔离 Python 包和依赖 |
其中最容易混淆的是 Docker 和虚拟机。
Docker
在 Linux 上,Docker Container 通常仍然和宿主机共享 Linux Kernel。 可以粗略理解成:
css
Application A Application B
│ │
┌───────────┐ ┌───────────┐
│Container A│ │Container B│
└───────────┘ └───────────┘
\ /
\ /
Linux Kernel
│
Hardware
Linux 通过 Namespace 等机制,让不同 Container 看到不同的:
进程
网络
文件系统挂载
主机名
用户
Docker 官方文档把 Namespace 称为容器最直接的一层隔离机制。 也就是说,容器里的程序可能感觉:
"这就是我的 Linux。"
实际上,它只是看到了操作系统专门给它准备的一部分视图。
虚拟机
虚拟机则更彻底,它连 Kernel 都可以是自己的:
markdown
┌──────────────────┐
│ Virtual Machine │
│ │
│ Application │
│ ↓ │
│ Guest OS │
│ ↓ │
│ Guest Kernel │
└──────────────────┘
↓
Hypervisor
↓
Hardware
因此虚拟机通常比普通容器的隔离边界更完整,但代价也更高。 不过,还要特别注意一点。
虚拟化本身并不等于安全。
一个系统用了虚拟机,不代表它天然就是一个设计良好的 Sandbox。 反过来,一个 Sandbox 也完全不要求必须使用虚拟机。因此还是那句话:
Sandbox 描述目标,Container 和 VM 更多描述实现方式。
5. 为什么 AI Agent 时代又开始频繁谈 Sandbox?
Sandbox 其实是一个非常老的概念,只是到了 AI Agent 时代,它突然变得更加重要。原因很简单,以前的大模型通常是:
markdown
你问 ChatGPT
↓
ChatGPT 告诉你命令
↓
你看一眼
↓
你自己决定是否执行
例如,ChatGPT 告诉你:
bash
rm test.txt
最后真正按下回车的人还是你。 但是 Coding Agent 不一样, 现在的流程越来越接近:
用户
↓
AI Agent
↓
分析代码
↓
读取文件
↓
执行 shell
↓
修改代码
↓
运行测试
↓
读取结果
↓
继续修改
AI 已经从:
"给你建议"
逐渐变成:
"替你行动"
也就是,从以前仅有的大脑思考后给你出主意,到现在开始长出了手脚,可以给你干活了。于是一个新的问题出现了:
我们到底应该给 AI 多大的权限?
这就是 Sandbox 重新变得重要的原因。
举一个我最近看到的 OpenClaw 的例子:OpenClaw 可以让 AI Agent 执行:
arduino
read
write
edit
exec
process
这些工具。
如果不做隔离,执行命令最终可能发生在 Gateway 所在的主机环境。启用 Sandbox 后,则可以把工具执行移动到沙箱后端。它默认可以使用 Docker 来做这件事。执行路线可以粗略理解成:
bash
AI Agent
│
│ 我要执行 npm test
↓
OpenClaw
│
↓
Sandbox
│
↓
Docker Container
│
↓
npm test
而不是:
bash
AI Agent
│
↓
我的真实电脑
│
↓
npm test
OpenClaw 甚至默认可以让 Docker Sandbox:
不能访问外网
根文件系统只读
移除 Linux capabilities
这些具体配置不是本文的重点。 真正值得注意的是它背后的设计思想:
Agent 可以获得执行代码的能力,但是这个能力应该有边界。
这正是 Sandbox 要解决的问题。
6. 其实我们每天都在使用 Sandbox
看到这里,Sandbox 可能仍然显得有一点陌生。其实我们每天都在使用它。 最典型的例子就是:
浏览器。
假设你打开一个陌生网站:
arduino
https://example.com
里面的 JavaScript 可以:
javascript
document.querySelector('#app')
fetch('/api')
localStorage.getItem('user')
但是你绝不会希望网页可以随便:
javascript
读取 ~/.ssh/id_rsa
扫描整个硬盘
启动一个 shell
杀掉 VS Code
删除 Documents
读取其他程序的内存
否则,访问一个网站就跟下载一个病毒没有多大区别了。 所以现代浏览器会把很多不可信内容放进受限制的进程中运行。
Chromium 官方对 Sandbox 的描述非常直接: 它的目标,就是给代码能够做什么、不能做什么提供明确的安全保证。
可以把浏览器理解成:
css
我的电脑
┌───────────────────────────────┐
│ │
│ Documents │
│ SSH Key │
│ VS Code │
│ 其他程序 │
│ │
│ ┌─────────────────────┐ │
│ │ Browser Sandbox │ │
│ │ │ │
│ │ JavaScript │ │
│ │ 页面渲染 │ │
│ │ │ │
│ └─────────────────────┘ │
│ │
└───────────────────────────────┘
网页仍然可以运行,JavaScript 仍然可以执行,页面也仍然可以展示动画、发送 HTTP 请求。只是浏览器告诉它:
你的世界到这里为止。
这其实就是描述 Sandbox 最形象的一句话。
7. 最后,重新理解 Sandbox
现在我们可以回到最开始的问题:
Sandbox 是不是一个虚拟环境?
答案是:不准确。
Sandbox 可以借助虚拟环境实现,但它本身不是某一种虚拟化技术。 如果让我现在给 Sandbox 下一个定义,我会写成:
Sandbox 是一个受控的代码执行边界。它通过限制程序可以访问的文件、进程、网络、系统调用和其他资源,把程序可能造成的影响控制在预定范围以内。
再压缩精简一下:
Sandbox 不是为了规定程序在哪里运行,而是为了规定程序最多能做什么。
这也是我认为理解 Sandbox 最关键的一点。以前的软件主要是:
人
↓
软件
↓
操作系统
人决定软件什么时候运行,但是 AI Agent 出现以后,慢慢变成了:
人
↓
AI
↓
AI 自己决定调用工具
↓
操作系统
中间多了一个能够自主决策的角色(AI Agent)。因此未来我们可能会越来越频繁地遇到:
css
Sandbox
Permission
Approval
Capability
Isolation
这些概念。
因为当 AI 只有"大脑"的时候,我们主要担心的是:
它说错了什么?
而当 AI 开始拥有"手",可以读文件、写代码、执行命令以后,我们还必须考虑另一个问题:
它到底被允许碰什么?
Sandbox,就是给这双手画出的那条边界。
参考资料
- OpenClaw 官方文档:《沙箱隔离》
OpenClaw Sandbox 文档 - OpenClaw 官方文档:《Codex harness》
OpenClaw Codex harness 文档 - Docker 官方文档:《Docker Engine security》
Docker Engine security - Chromium 官方文档:《Sandbox》
Chromium Sandbox Design