第 13 / 15 章 约 6 分钟
Sandbox 与安全
限制执行环境、权限和资源,保护凭据。
内容同步:2026年10月25日 · 文档版本 6
这个模块在 Agent 里的位置
安全边界决定:
- Agent 能调用什么工具。
- 能访问哪个租户的数据。
- 能读写哪些路径。
- 能访问哪些网络。
- 能消耗多少资源。
- 哪些动作必须人审。
- 失败时影响范围多大。
Prompt 不是安全边界。它只能引导模型,不能阻止恶意输入或混淆命令。
先记住几个概念
| 概念 | 含义 | 为什么重要 |
|---|---|---|
| Tool allowlist | 允许调用的工具集合 | 缩小能力面 |
| Schema | 参数结构和范围 | 防止非法输入 |
| Permission | 数据和操作权限 | 防止越权 |
| Human approval | 高风险动作审批 | 防止误操作 |
| Sandbox | 进程 / 文件 / 网络隔离 | 限制执行影响 |
| Workspace | 任务独立工作目录 | 防止跨任务读写 |
| Resource limit | CPU、内存、磁盘、时间 | 防止资源失控 |
从一个真实问题开始:一条“看起来正常”的命令删除了共享目录
Agent 需要分析一个 20GB 数据文件。
模型生成了:
rm -rf /workspace/inputs
系统只有一条正则规则:
禁止 rm -rf /
这条命令没有命中规则,因为它删除的是 /workspace/inputs。
结果:
- 共享输入目录被删。
- 其他任务读取失败。
- 没有审计记录。
- 无法回滚。
根因不是正则写得不够多,而是没有真正的执行隔离。
Prompt 和正则都不是沙箱
它们只能降低误操作概率,不能作为安全边界。
真正边界应该是:
tool allowlist
+ input schema
+ permission policy
+ human approval
+ real sandbox
如果一个模型能绕过 prompt,就说明这条边界本来就不安全。
代码执行必须进入沙箱
正确链路:
模型生成分析任务
-> 提交 sandbox
-> 输入目录只读
-> 输出目录独立
-> 限制 CPU / 内存 / 时间
-> 网络默认禁用
-> 返回 stdout / object ref
沙箱至少要有:
- 独立进程。
- 独立文件系统或前缀。
- 网络限制。
- CPU / 内存 / 磁盘 / PID 限制。
- 超时销毁。
- 凭据隔离。
数据库设计
create table agent_sandboxes (
id bigint primary key,
run_id bigint not null,
tenant_id bigint not null,
provider_session_id text not null,
status text not null,
input_prefix text not null,
output_prefix text not null,
cpu_limit_millicores int not null,
memory_limit_mb int not null,
created_at timestamptz not null,
destroyed_at timestamptz
);
create unique index agent_sandbox_provider_idx
on agent_sandboxes (provider_session_id);
设计要点:
- input 和 output prefix 独立。
- 每个 run 独立沙箱。
- 状态包含创建和销毁时间。
- provider session ID 唯一,便于追踪。
文件路径要防逃逸
工具只接受相对路径:
{
"scriptPath": "analysis.py",
"inputPath": "inputs/data.csv",
"outputPath": "outputs/result.json"
}
必须拒绝:
../secret.txt
/etc/passwd
C:\Windows\system32
symlink-to-outside
服务端要做:
- realpath 校验。
- 拒绝绝对路径。
- 拒绝 ..。
- 拒绝 symlink escape。
网络默认禁用
沙箱网络策略:
| 场景 | 策略 |
|---|---|
| 本地数据分析 | 禁网 |
| 需要下载依赖 | 使用预构建镜像 |
| 需要访问内部 API | 域名白名单 + 短期 token |
| 需要访问外网 | 通常禁止 |
不要把长期凭据注入沙箱。
如果必须访问内部服务:
- 使用短期 token。
- 设置域名白名单。
- 记录访问审计。
- token 到期自动失效。
资源限制
一个典型的沙箱限制:
{
"cpuMillicores": 2000,
"memoryMb": 4096,
"diskMb": 20480,
"timeoutMs": 120000,
"network": "disabled"
}
如果没有资源限制,一个死循环或大文件处理就可能:
- 占满 CPU。
- 打爆内存。
- 写满磁盘。
- 影响宿主机或其他任务。
高风险动作必须人审
即使有沙箱,以下动作仍然应该进入审批:
| 动作 | 原因 |
|---|---|
| 删除文件 | 不可逆 |
| 发送外部通知 | 影响真实用户 |
| 修改生产数据 | 业务风险 |
| 执行高权限命令 | 影响范围大 |
| 访问跨租户数据 | 合规风险 |
安全不是一个开关,而是分层策略。
和传统后端的关系
沙箱安全可以类比成后端里的容器安全和最小权限:
| Agent 里的概念 | 传统后端里的对应物 |
|---|---|
| Tool allowlist | API 权限白名单 |
| Sandbox | 容器隔离 |
| Resource limit | cgroup / container limit |
| Network policy | 网络策略 / 防火墙 |
| Short-term token | 临时凭证 |
| Human approval | 审批流 |
| Audit | 审计日志 |
做过后端安全的人,熟悉的仍然是同一套东西:最小权限、隔离、限资源、控网络、管凭证、留审计。
常见工程错误
| 错误 | 实际后果 | 正确做法 |
|---|---|---|
| 正则当沙箱 | 可被混淆绕过 | 真隔离 |
| 共享 workspace | 跨任务读写 | 独立 prefix |
| 凭据注入沙箱 | 泄漏 | 短期 token / 不注入 |
| 无资源限制 | 宿主机风险 | CPU / 内存 / 时间 |
| 网络全开 | 数据外传或攻击面扩大 | 默认禁网 |
| 高风险动作不人审 | 误操作进入真实世界 | approval |
| 路径不校验 | 读取或删除外部文件 | realpath + 白名单 |
上线前检查
- allowlist 显式。
- 高风险动作人审。
- 代码执行有真实沙箱。
- 文件路径校验。
- 网络受限。
- 资源受限。
- 超时销毁。
- 凭据隔离。
- 每个沙箱可审计。