一、核心结论
在 SaaS Agent 场景中,Sandbox 不应被简化理解为“一个运行代码的容器”。它本质上是 Agent 执行动作的受控边界。
本文的核心观点是:虚拟化技术(Docker、microVM、云浏览器)只是实现手段。真正的挑战在于如何将生命周期、权限校验、凭证发放、网络限制、状态恢复、多租户配额和人类审批集成到统一的 Sandbox 控制面。
2026 核心观察:从“隔离执行”到“应用原语”
站在 2026 年的视角,Sandbox 已经从单纯的安全加固层演进为 SaaS Agent 的逻辑运行原语。主要的范式转移包括:
- 自托管沙箱 (Self-hosted Sandboxes):厂商如 Anthropic 开始支持编排权在云端、执行权在客户侧的模式。Agent 逻辑在云端思考,但代码执行、文件 IO 和网络请求完全发生在客户基础设施内 Anthropic Self-hosted Sandboxes。
- Sandbox 即服务 (SaaS Integration):Cloudflare 等基础设施厂商开始提供深度集成的 Sandbox 运行时,包含内置的出网控制 (Egress control)、动态凭证注入 (Credential mediation)、原生浏览器 (Browser Run) 和专属邮箱能力 Cloudflare Claude Managed Agents。
- MCP / tool approval 标准化:Model Context Protocol (MCP) 正在把外部工具变成可枚举、可过滤、可审批的接口层;Sandbox 负责执行边界,MCP/Tool Gateway 负责工具边界,两者需要组合使用而不能互相替代。OpenAI Agents SDK MCP approval;Anthropic MCP Tunnels
- 过度代理与 Agentic 风险上升:随着 Agent 从回答问题走向执行动作,OWASP 的 LLM08 Excessive Agency 和 Agentic Applications Top 10 都把工具滥用、权限继承、目标劫持等问题推到更中心的位置;Sandbox 的价值因此从“防 RCE”扩展为限制工具爆炸半径。OWASP Excessive Agency;OWASP Agentic Applications Top 10
核心论点总结
- Sandbox 是执行隔离现场:用于隔离代码执行、文件处理及浏览器操作 托管代码执行环境。
- 不只是代码隔离:Agent 风险更多来自工具滥用、权限扩大和数据外泄,仅靠计算隔离是不够的 OWASP AI Agent Security。
- 受控行动原则:Agent 可以自由思考,但严禁自由行动。所有外部副作用必须经过策略和审计边界 OWASP Secure Coding。
阅读导引
- 原理篇 (二至四):明确 Sandbox 的适用场景与控制权归属。
- 控制面篇 (五至十四):深入探讨身份凭证、网络安全、文件流转、状态恢复及人类审批的设计。
- 工程篇 (十五至十七):解决多租户配额、资源调度及生命周期管理的落地难题。
本文的威胁模型
在安全设计中,威胁模型 (Threat Model) 意味着“我们假设要防范什么”。对于 SaaS Agent 而言,Sandbox 需要同时约束来自不可信输入、恶意指令和执行副作用的多维风险:
1. 资产与凭证风险 (Assets)
- 凭证泄露:客户的 OAuth Token、API Key、Cookie 或浏览器登录态被 Agent 意外泄露。
- 租户数据污染:跨租户数据残留,或因 Workspace 复用导致的隔离失效。
2. 不可信输入 (Untrusted Inputs)
- 代码注入:LLM 生成的恶意 Shell、Python 或 SQL 脚本。
- 间接提示词注入:第三方网页、邮件或文档中埋伏的指令干扰 Agent 决策。
- 文件陷阱:恶意构造的压缩包、脚本或代码仓库。
3. 执行边界与副作用 (Boundaries & Side Effects)
- 网络外泄:代码访问内网敏感服务、Metadata Endpoint 或非法外网地址 OWASP SSRF Prevention。
- 外部副作用:未经授权发送邮件、支付扣款、删除数据或创建 PR。
- 供应链风险:Sandbox 基础镜像、运行时及依赖包本身的安全漏洞。
本文后续的所有建议,均致力于构建一套针对上述风险的防御面:定义哪些动作能执行、在哪里执行、使用什么凭证、访问什么网络,以及何时必须中断并请求人类介入。
二、什么时候需要 Sandbox
不是所有 Agent 都需要复杂 Sandbox。判断标准很简单:
只要 Agent 要执行不可信、可变、带副作用的动作,就应该进入 Sandbox 或经过等价的隔离执行层。托管计算环境:用于隔离代码执行与文件处理;OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP Prompt Injection:网页/文档/邮件可成为注入载体;OWASP Secure Coding with AI:工具权限、输入校验、不可信上下文
需要 Sandbox 的场景
典型场景包括:
- 执行 LLM 生成的代码;
- 运行 Python / JavaScript / Shell;
- 处理用户上传文件;
- 修改 repository;
- 运行测试;
- 打开浏览器访问第三方网站;
- 下载或上传文件;
- 生成图表、报告、CSV、PDF;
- 执行多步骤自动化任务;
- 为每个租户创建隔离工作区。
不一定需要 Sandbox 的场景
如果 Agent 只是:
- 读数据库里已经授权的数据;
- 调一个固定后端 API;
- 做只读问答;
- 生成文本草稿;
- 调用没有副作用的内部函数;
那么不一定要上完整 Sandbox,但仍然要有 tool gateway、权限控制和审计。这个判断来自 OWASP 对 Agent least privilege、tool abuse 和 monitoring 的要求:即使没有代码执行环境,工具调用本身仍然是安全边界。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP Secure Coding with AI:工具权限、输入校验、不可信上下文
三、谁该拥有 Sandbox 的控制权
Sandbox 不应直接暴露给 LLM。它必须由 Orchestrator (编排层) 统一管理。这是为了确保工具调用能严格遵循用户权限、会话上下文及最小权限原则。
graph TD
USER["User / Tenant"] --> ORCH["Agent Orchestrator"]
ORCH --> POLICY["Policy Engine"]
ORCH --> CRED["Credential Broker"]
ORCH --> TOOL["Tool Gateway"]
ORCH --> SB["Sandbox Manager"]
ORCH --> ARTIFACT["Artifact Store"]
ORCH --> AUDIT["Audit Log"]
怎么读这张图:Orchestrator 居中调度,将权限校验 (Policy)、凭证分发 (Credential)、工具接入 (Tool) 与实际执行环境 (Sandbox) 解耦,确保 Agent 所有的外部副作用都可被审计 (Audit) 和阻断。
Orchestrator 负责什么
Orchestrator 负责:
- 创建 Sandbox 并绑定租户/会话上下文。
- 注入最小必要的执行参数。
- 调用工具并记录全量审计日志。
- 在执行失败后执行任务恢复逻辑。
在凭证管理上,建议参考一种凭证中继 (Credential Broker) 模式:通过受控的身份管理器或凭证库动态发放短期、受限的 Token,而不是将原始 Secret 直接暴露给 Agent。Google Cloud Agent Identity 文档中的 auth manager / credential vault 可以作为这一类控制面的参考,但它不等于所有云平台都会提供相同语义的托管能力。Google Cloud Agent Identity:auth manager / credential vault 管理凭证
Sandbox 负责什么
Sandbox 仅作为“隔离的执行现场”:
- 运行代码、读写临时文件。
- 启动无头浏览器进行网页操作。
- 运行测试套件并生成中间产物。
小结:Sandbox 不应负责最终的业务权限判断,也不应作为业务数据的长期存储。权限判断属于外部的 Policy 层,业务产物应通过受控的 Artifact Store 流出。 OWASP Secure Coding;托管代码解释器与 E2B 的文件处理逻辑
四、一次 Agent 任务的标准执行流
典型的安全执行流程:先将执行限定在隔离环境,再将外部副作用引流至受控网关、凭证中继、人类审批及审计系统。
graph TD
START["用户发起任务"] --> SESSION["Orchestrator 创建 task / session"]
SESSION --> POLICY["Policy Engine 判断需要哪些能力"]
POLICY --> CREATE["Sandbox Manager 创建 sandbox"]
CREATE --> CONTEXT["注入输入文件和最小上下文"]
CONTEXT --> EXEC["Agent 在 sandbox 中执行代码 / 浏览器 / 文件操作"]
EXEC --> ARTIFACT["产物写入 Artifact Store"]
EXEC --> TOOL["外部动作通过 Tool Gateway 执行"]
TOOL --> APPROVAL["高风险动作进入 Human Approval"]
ARTIFACT --> AUDIT["Audit Log 记录全过程"]
APPROVAL --> AUDIT
AUDIT --> END["任务完成后销毁或 checkpoint sandbox"]
怎么读这张图:从任务发起至销毁,所有数据流转(输入文件、中间产物、外部动作)都必须跨越 Sandbox 的物理边界。关键在于 “产物外置” 与 “动作受控”,确保 Sandbox 内部的意外状态不会直接污染外部环境。
关键原则:结果不等于效果
Sandbox 里的执行结果不能自动转化为真实世界的业务效果 OWASP Secure Coding。
以 Coding Agent 为例,安全的修改流程如下:
graph TD
COPY["copy repo into sandbox"] --> MODIFY["agent modifies code"]
MODIFY --> TEST["run tests"]
TEST --> DIFF["produce diff"]
DIFF --> APPROVE["human / policy approves"]
APPROVE --> PR["merge or create PR"]
怎么读这张图:Agent 只在 Sandbox 副本中操作,输出仅为 Diff。最终的仓库合并必须经过人类审核 (HITL) 或预定义的自动化策略。
五、Sandbox 的生命周期模型
Sandbox 的生命周期建议根据任务性质分为三类。隔离环境的复用会带来 /tmp 目录、内存对象等状态残留风险,因此生命周期越长,状态清理的要求就越高。
1. 短任务 (Ephemeral Task)
场景:文件格式转换、即时数据分析、单次网页抓取。
graph LR
CREATE["create"] --> EXEC["execute"]
EXEC --> EXPORT["export artifacts"]
EXPORT --> DESTROY["destroy"]
策略:随用随建,完事即毁。这是最安全、成本最低的模式。设计核心在于:只保留输出产物和日志,不保留任何执行环境状态。
2. 会话级 (Session-based)
场景:多轮对话协作、Notebook 交互式开发、带上下文的浏览器操作。
graph LR
CREATE["create"] --> EXEC["execute multiple steps"]
EXEC --> IDLE["idle timeout"]
IDLE --> CHECKPOINT["checkpoint"]
IDLE --> DESTROY["destroy"]
策略:支持多步连续操作,但必须设置 Idle Timeout (空闲超时)。空闲时可选择暂停(Checkpoint)以节省资源。
3. 项目级 (Workspace-based)
场景:长期软件项目开发、复杂的 Repository 持续修改。
graph LR
CREATE["create"] --> EXEC["execute steps"]
EXEC --> PERSIST["persist workspace"]
PERSIST --> DESTROY["destroy compute"]
策略:状态与计算分离。将持久化的 Workspace(文件系统)与瞬时的执行 Sandbox 解耦。这样即便 Sandbox 崩溃或被回收,项目进度也能安全保留。
六、持续运行 Agent:状态怎么保持
持续运行 Agent 最大的问题是:中间一定会断。Cloudflare Workflows 这类 durable workflow 的思路是把长任务建模为可恢复的 workflow/history,而不是依赖一次连续不失败的进程执行。Cloudflare Workflows:durable workflow、history、幂等恢复
可能断在:
- LLM 调用失败;
- sandbox 被回收;
- 浏览器崩溃;
- worker 重启;
- 网络超时;
- 用户暂停;
- 审批等待;
- 任务超过执行时间。
所以不能依赖“一个一直活着的 sandbox”。正确做法是把状态拆开保存:Agent 控制状态进入 workflow/state store,执行产物进入 artifact/workspace,外部副作用进入 operation log。这是对 durable workflow、云浏览器会话记录和 sandbox 文件流转能力的组合推导。Cloudflare Workflows:durable workflow、history、幂等恢复;Browserbase:云浏览器 session、录制、timeout 与 keep-alive;托管代码解释器与 E2B:文件进出 sandbox 与产物处理
三类状态
1. Agent 控制状态
包括:
- task id;
- tenant id;
- 当前计划;
- 已完成步骤;
- 下一步 cursor;
- tool call history;
- approval 状态;
- retry count;
- 错误信息。
这些应该存在 Agent State Store 或 workflow engine 中。Cloudflare Workflows 文档强调 workflow runtime 会保存执行历史/状态,用于恢复和继续执行。Cloudflare Workflows:durable workflow、history、幂等恢复
2. Sandbox 执行状态
包括:
- 工作目录;
- 生成文件;
- 安装依赖;
- notebook kernel;
- browser profile;
- screenshots;
- stdout / stderr。
这些可以通过 artifact、workspace volume、snapshot 或 checkpoint 保存。E2B 的 sandbox 文档和 Firecracker snapshot 文档分别提供了 sandbox pause/resume 与底层 snapshot/restore 的参考,但它们都应服务于上层生命周期策略。Firecracker Snapshot / Jailer:snapshot 恢复与隔离增强;E2B Sandbox:按需创建、暂停、恢复 sandbox
Snapshot / Checkpoint 到底应该保存什么
Snapshot 不是“把整个 sandbox 当成数据库”。它更像是一个可恢复的执行现场,用来缩短恢复时间、保留运行上下文,或者从同一个干净基线恢复出新的执行分支。不同平台的 pause/resume、snapshot、checkpoint 语义并不等价,不能把 E2B persistence、Firecracker snapshot 和 Docker checkpoint 混成同一种能力。E2B Persistence / Auto-resume:pause/resume 保留运行状态;E2B / Firecracker Snapshot:point-in-time 状态恢复和 fork
推荐把 snapshot 拆成几层:
graph TD
SNAPSHOT["Snapshot / Checkpoint"] --> BASE["base image snapshot"]
BASE --> BASE_CONTENT["OS / runtime / common dependencies"]
SNAPSHOT --> WORKSPACE["workspace snapshot"]
WORKSPACE --> WORKSPACE_CONTENT["repo files / generated files / installed packages / local caches"]
SNAPSHOT --> RUNTIME["runtime snapshot"]
RUNTIME --> RUNTIME_CONTENT["process state / memory / notebook kernel / open editor state"]
SNAPSHOT --> BROWSER["browser profile snapshot"]
BROWSER --> BROWSER_CONTENT["cookies / localStorage / history / downloads / extension state"]
SNAPSHOT --> HISTORY["execution history snapshot"]
HISTORY --> HISTORY_CONTENT["command history / tool call transcript / stdout / stderr / screenshots"]
这几层不要混在一起保存。原因是它们的生命周期、敏感度和复用边界都不同:
| 内容 | 是否适合 snapshot | 更推荐的位置 |
|---|---|---|
| 基础镜像、语言运行时、常用依赖 | 适合 | base image / golden snapshot |
| 当前 workspace 文件、临时 repo、生成文件 | 适合 | workspace volume / object store / diff |
| notebook kernel、长任务进程、内存中间结果 | 有条件适合 | runtime snapshot / pause-resume |
| browser profile、cookies、localStorage、下载记录 | 只适合同租户/同 session | encrypted profile store |
| 命令历史、stdout/stderr、截图、tool trace | 适合保存,但不一定放进 sandbox snapshot | audit log / execution log / artifact store |
| 用户上传的原始文件 | 不建议只存在 snapshot 里 | user file store / artifact store |
| 长期 secret、OAuth refresh token、客户 API key | 不应该 | credential broker / secret vault |
| 已经发生的外部动作 | 不应该 | operation log / idempotency store |
也就是说,snapshot 可以包含“运行现场”,但不应该成为唯一事实来源。尤其是用户数据要单独建模:用户上传文件、浏览器登录态、生成产物、审计日志和业务数据库记录,不应该因为恢复一个 sandbox snapshot 就被隐式恢复或覆盖。
一个更稳的保存模型是:
1 | checkpoint_id |
恢复时不要只做:
graph LR
RESTORE["restore snapshot"] --> CONTINUE["continue"]
更安全的流程是:
graph TD
LOAD["load checkpoint metadata"] --> BINDING["verify tenant / user / session binding"]
BINDING --> POLICY["verify base image and policy version"]
POLICY --> WORKSPACE["restore workspace snapshot"]
WORKSPACE --> RUNTIME["restore runtime snapshot if allowed"]
RUNTIME --> BROWSER["attach browser profile if same trust boundary"]
BROWSER --> HISTORY["reload execution history and last safe cursor"]
HISTORY --> RECONCILE["reconcile external side effects"]
RECONCILE --> CONTINUE["continue from next idempotent step"]
这里有几个容易踩坑的点:
- snapshot 可能保存内存里的 token、shell history、浏览器 cookie,所以 snapshot 本身必须按敏感数据加密、隔离、设置 TTL;
- runtime snapshot 可能包含打开的 socket、后台进程和依赖宿主机的状态,恢复后要做健康检查,不能假设所有连接还有效;Firecracker Snapshot Caveats:恢复依赖宿主条件和健康检查;Docker checkpoint / CRIU:checkpoint 的一致性风险
- browser profile 是用户数据,不是普通缓存;Playwright / Chromium 的 user data directory 会包含 cookie、localStorage、history 等登录态和浏览痕迹;Playwright Persistent Context:userDataDir 保存浏览器会话状态;Chromium User Data Directory:cookies/history/local state 等用户数据
- 跨 tenant 默认不要复用同一个 runtime snapshot;如果要用基础镜像 snapshot 加速启动,也应该只复用无用户数据、无凭证、无历史状态的 clean snapshot;
- audit log 和 operation log 必须外置,因为它们是判断“上一步到底有没有对外生效”的依据,不能跟着 sandbox 回滚。
一句话:
Snapshot 用来恢复执行现场,不用来保存业务事实;用户数据、凭证和外部副作用必须有独立的系统记录。
3. 外部副作用状态
包括:
- 是否已经发邮件;
- 是否已经提交表单;
- 是否已经创建订单;
- 是否已经写数据库;
- 是否已经创建 PR。
这些不能靠 sandbox 恢复,必须靠 operation log 和 idempotency key 管理。因为外部副作用已经发生在 sandbox 之外,恢复时首先要 reconcile,而不是盲目 replay。Cloudflare Workflows:durable workflow、history、幂等恢复
推荐恢复流程
graph TD
STATE["load task state"] --> CURSOR["load last safe cursor"]
CURSOR --> SANDBOX["restore or recreate sandbox"]
SANDBOX --> ARTIFACTS["load artifacts / workspace"]
ARTIFACTS --> RECONCILE["reconcile external side effects"]
RECONCILE --> CONTINUE["continue from next safe step"]
关键原则:
1 | Sandbox can be durable, |
也就是:sandbox 可以长时间存在,但系统必须能在它消失后恢复。
七、工具和凭证怎么接入 Sandbox
这是 SaaS Agent 最容易做错的部分。OWASP AI Agent Security 和 Secure Coding with AI 都把 tool permissions、least privilege、输入校验和不可信上下文视为核心风险点。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP Secure Coding with AI:工具权限、输入校验、不可信上下文
不要把长期 Secret 放进 Sandbox
错误做法:
1 | export CUSTOMER_API_KEY=xxx |
更好的做法:
graph LR
AGENT["Agent requests capability"] --> POLICY["Policy Engine approves"]
POLICY --> TOKEN["Credential Broker issues short-lived scoped token"]
TOKEN --> TOOL["Tool Gateway executes action"]
TOOL --> AUDIT["Audit Log records result"]
Agent 不应该直接持有客户长期凭证。Sandbox 也不应该变成 secret 仓库。可以参考 Google Cloud Agent Identity 文档中的做法:把凭证交给 auth manager / credential vault,并让 Agent 使用绑定身份的授权能力。本文只把它当成 credential broker 模式的例子,而不是所有云平台的通用事实。Google Cloud Agent Identity:auth manager / credential vault 管理凭证
短期凭证也不是绝对安全的。如果它被注入 sandbox,就可能被 LLM 生成的代码、恶意依赖、shell history、日志或 snapshot 泄漏。因此 credential broker 还要配合:
- 极短 TTL 和最小 scope;
- token binding / audience 限制;
- 可撤销和可轮换;
- 日志脱敏;
- snapshot / checkpoint 排除策略;
- egress proxy,避免凭证被发到未知域名。
凭证仲裁与 MCP 代理
在复杂的 SaaS 集成中,Agent 的工具访问正从“直连”转向“中转控制”。通过 Model Context Protocol (MCP),Agent 可以通过标准接口发现并调用工具;但工具是否暴露、是否需要审批、调用时附带什么元数据,应该由控制面和 Tool Gateway 决定,而不是由 sandbox 内部的任意代码决定。OpenAI Agents SDK MCP approval
现代架构倾向于使用 凭证仲裁 (Credential Mediation):
- 静默注入:Sandbox 或 Egress Proxy 拦截请求,并根据目标域名自动注入 OAuth Token 或 API Key。Agent 本身从未感知到凭证的原文 Cloudflare Claude Managed Agents。
- MCP 隧道解耦:MCP Server 可以部署在与 Sandbox 不同的网络边界中。Anthropic 的 MCP tunnels 是一个例子:通过 outbound-only 隧道把私有网络里的 MCP server 暴露给 Claude,无需开放入站端口;同时要注意它是 beta/research preview,不能把它当作通用可用性或安全保证本身。Anthropic MCP Tunnels
Tool Gateway 比直接 API 调用更重要
Agent 不应该在 sandbox 里随便 curl 生产 API。OWASP 对 Agent 的建议是工具调用要有明确权限边界、输入校验和 least privilege;直接从 sandbox 调真实 API 会绕过这些控制点。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP Secure Coding with AI:工具权限、输入校验、不可信上下文
应该通过 Tool Gateway:
1 | send_email(...) |
每个工具都应该有:
- schema validation;
- permission check;
- rate limit;
- idempotency key;
- dry-run;
- approval rule;
- audit event。
八、网络怎么管
对不可信 workload,Sandbox 默认不应该拥有任意外网访问能力。更现实的默认策略不是“完全不能访问公网”,而是:阻断 non-HTTP、内网地址、localhost、link-local、metadata endpoint 和未知外发通道;公网 HTTP / browser 访问按任务类型走 allowlist、approval 或 monitored proxy。OWASP SSRF 防护建议使用 allowlist、阻断内网/metadata 地址等控制;Agent 场景还要叠加 prompt injection 风险,因为外部网页或文档可能诱导 Agent 访问恶意目的地。OWASP Prompt Injection:网页/文档/邮件可成为注入载体;OWASP SSRF Prevention:allowlist、阻断内网和 metadata endpoint
推荐策略:
graph TD
DEFAULT["default deny outbound"] --> ALLOW["allow by tenant policy"]
ALLOW --> PROXY["proxy all HTTP / API / browser traffic"]
PROXY --> BLOCK_INTERNAL["block internal IP ranges"]
PROXY --> BLOCK_METADATA["block cloud metadata endpoints"]
BLOCK_INTERNAL --> LOG["log destination and method"]
BLOCK_METADATA --> LOG
尤其要防:
- SSRF;
- 访问云 metadata;
- 扫描内网;
- 将数据 POST 到未知域名;
- DNS rebinding、redirect 到内网、IPv6 / link-local 绕过;
- WebSocket、文件上传、浏览器下载等非普通 API 外发路径;
- 被网页 prompt injection 引导访问恶意地址。
Browser Agent 也一样。浏览器不是“天然安全”的工具,浏览器只是另一个高风险执行环境;OWASP Prompt Injection 文档明确把网页、文档、邮件等外部内容视为可注入载体。OWASP Prompt Injection:网页/文档/邮件可成为注入载体
九、Browser Agent 怎么用 Sandbox
带登录态或真实副作用的 Browser Agent 要单独建模。Browserbase 文档中的 session、video recording、timeout、keep-alive 等能力说明浏览器自动化本身需要被当作可观察、可管理的会话,而不是一次普通函数调用;Playwright 的 persistent context 也明确 user data directory 会保存 cookies 和 localStorage 等会话状态。Browserbase:云浏览器 session、录制、timeout 与 keep-alive;Browserbase:云浏览器、会话管理、录制、代理;Playwright Persistent Context:userDataDir 保存浏览器会话状态
推荐规则:
graph TD
PROFILE["one browser profile per tenant / session"] --> COOKIES["no shared cookies"]
PROFILE --> ALLOWLIST["domain allowlist"]
PROFILE --> FILES["controlled uploads / downloads"]
PROFILE --> TRACE["record screenshots / action trace"]
PROFILE --> APPROVAL["approval before submit / payment / delete / post"]
PROFILE --> TTL["session TTL"]
如果 Agent 只是浏览网页,风险还可控;如果它要提交表单、发消息、下单、改设置,就必须走审批或明确的 tenant policy。Cloudflare HITL 文档提供了“暂停 workflow 等待人工确认”的实现参考,OWASP 也建议对高风险 Agent 动作引入 human-in-the-loop。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;Cloudflare HITL:workflow 暂停等待人工确认
中断恢复时尤其要注意:
不要盲目 replay click。
如果上一次中断发生在“提交”附近,恢复时应该先检查外部系统状态,确认动作是否已经完成,再决定继续、跳过或让用户确认。
十、产物怎么管理
Sandbox 里的文件不应该直接变成用户可下载文件。托管代码解释器 (如 OpenAI Code Interpreter) 与 E2B 都涉及文件上传、沙箱文件系统或产物流转能力,但它们的 API、持久化语义和安全边界并不等价。SaaS 产品应在这层之上增加 artifact metadata、访问控制、扫描和审计。托管计算环境:用于隔离代码执行与文件处理;托管代码解释器与 E2B:文件流转和产物处理
现实世界的 Sandbox 新应用场景
除了传统的代码解释器,Sandbox 正在成为多种复杂任务的专用运行时:
- Browser Sandbox(浏览器沙箱):如 Browserbase 或 Cloudflare Browser Run。不再只是运行 Playwright 脚本,而是提供带会话保持、录制审计、网络策略和截图/CDP 控制的云端浏览器环境。Browserbase Documentation;Cloudflare Claude Managed Agents
- Email Sandbox(邮件隔离环境):为每个 Agent 会话分配专属邮箱,让 Agent 在受控边界内收发邮件、处理验证码或业务消息;真正外发前仍应经过内容过滤、权限检查和审计。Cloudflare Claude Managed Agents
- IDE / Workspace Sandbox(开发沙箱):如 Daytona、E2B、Modal 或 OpenAI Agents SDK hosted sandbox clients。重点不是“给 Agent 一个容器”,而是给它 repo/workspace、shell、文件编辑、测试运行、挂载存储和恢复机制,同时把 merge / deploy 留在外部审批链路。Daytona Docs;OpenAI Agents SDK sandbox clients
- Sandbox-native Agent SDK:OpenAI Agents SDK 的 Sandbox Agents 把 manifest、filesystem tools、shell、sandbox lifecycle、snapshots/session state 和 hosted sandbox client 选择纳入 agent runtime 配置,说明 sandbox 已经从外部执行器变成 agent 框架的一等运行时能力。OpenAI Agents SDK Sandbox Agents;OpenAI Agents SDK sandbox clients
推荐所有产物先进入 Artifact Store:
1 | artifact_id |
Artifact Store 要解决:
- 谁能下载;
- 保存多久;
- 是否包含敏感信息;
- 是否需要病毒扫描;
- 是否可以外发;
- 是否进入审计日志。
对于 coding agent,最重要的 artifact 往往不是文件本身,而是:
1 | diff + test result + logs + explanation |
十一、危险动作怎么审批
可以把动作分成四级。这个分级是对 OWASP least privilege / human-in-the-loop 建议、Cloudflare workflow approval 模式和 SaaS 审计需求的产品化表达。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP Secure Coding with AI:工具权限、输入校验、不可信上下文;Cloudflare HITL:workflow 暂停等待人工确认
Level 0:只读动作
例如读取文件、读取公开网页、查询已授权文档。
策略:自动允许,记录日志。
Level 1:Sandbox 内部写入
例如生成文件、修改临时 repo、运行测试。
策略:允许,但不能自动影响生产。
Level 2:外部可见动作
例如发 Slack、创建 ticket、提交网页表单、创建 PR。
策略:需要 policy allowlist,中高风险时需要用户确认。
Level 3:高风险动作
例如删除数据、付款、改权限、发布生产、导出大量数据。
策略:默认禁止,除非显式授权 + human approval + full audit。
十二、选型只需要粗略判断
不要一开始陷入过多 sandbox 实现细节。产品早期更重要的是使用方式,而不是底层技术完美;不同厂商提供的 sandbox 能力不同,层级也不同:代码解释器、浏览器会话、workspace、microVM、容器隔离、workflow 编排不能简单当成等价替代品。托管计算环境:用于隔离代码执行与文件处理;Browserbase:云浏览器 session、录制、timeout 与 keep-alive;Modal Sandboxes:隔离运行代码、命令和文件操作;Daytona:agent / developer workspace infrastructure
粗略选型即可:
| 层级 | 需求 | 可选方案 |
|---|---|---|
| 托管代码执行 | 数据分析、文件处理、短代码运行 | OpenAI Code Interpreter、E2B、Modal、CubeSandbox |
| 浏览器会话 | 网页访问、自动化、录制、profile 管理 | Browserbase、Playwright、CubeSandbox Browser 示例 |
| 持久 workspace | coding agent、长期项目、repo 状态 | Daytona、Codespaces-like workspace、自建 persistent workspace |
| 隔离运行时 | 更强隔离、自托管、高风险代码 | Firecracker-based、Kata、gVisor、microVM |
| 内部低风险任务 | 已知代码、可信网络、低敏数据 | Docker / Kubernetes |
这里的重点不是“哪个技术最强”,而是:
不管选哪个 sandbox,都要放在同一套 policy、credential、network、artifact、audit 框架下面使用。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP SSRF Prevention:allowlist、阻断内网和 metadata endpoint;Cloudflare HITL:workflow 暂停等待人工确认
十三、推荐默认方案
如果要做一个 SaaS Agent 产品,我会建议默认这样用。这个默认方案不是来自单一厂商,而是把 OWASP Agent 安全、受控身份、SSRF 防护、HITL、durable workflow、artifact/file handling 等来源组合成 SaaS Agent 的控制面设计;它是架构推导,不是 vendor reference architecture。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP SSRF Prevention:allowlist、阻断内网和 metadata endpoint;Cloudflare HITL:workflow 暂停等待人工确认;Cloudflare Workflows:durable workflow、history、幂等恢复
graph TD
PRODUCT["SaaS Agent Product"] --> SANDBOX["Sandbox"]
PRODUCT --> CONTROL["Control Plane"]
SANDBOX --> CODE["code sandbox for code / file / data work"]
SANDBOX --> BROWSER["browser sandbox for web automation"]
SANDBOX --> WORKSPACE["persistent workspace only when needed"]
CONTROL --> STATE["Agent State Store"]
CONTROL --> POLICY["Policy Engine"]
CONTROL --> TOOL["Tool Gateway"]
CONTROL --> CRED["Credential Broker"]
CONTROL --> EGRESS["Egress Proxy"]
CONTROL --> ARTIFACT["Artifact Store"]
CONTROL --> AUDIT["Audit Log"]
CONTROL --> APPROVAL["Human Approval"]
默认策略:
1 | one sandbox lease per run by default |
十四、最重要的反模式
1. 把 Sandbox 当成安全模型本身
Sandbox 只是执行隔离。真正的安全模型还包括 policy、credential、network、approval 和 audit。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP SSRF Prevention:allowlist、阻断内网和 metadata endpoint;Cloudflare HITL:workflow 暂停等待人工确认
2. 给 Agent 一个永不销毁的容器
这会导致成本不可控、状态不可解释、secret 残留、依赖漂移和恢复困难。AWS Lambda execution lifecycle 对环境复用状态的说明、以及 durable workflow 文档对外置状态的强调,都支持“不依赖永不销毁执行环境”的设计。AWS Lambda Execution Lifecycle:复用会保留 /tmp 与进程内状态;Cloudflare Workflows:durable workflow、history、幂等恢复
3. 把客户 Secret 放进 Sandbox
Agent 不应该直接持有长期凭证。应该用短期、窄权限、可撤销的 capability。Google Cloud Agent Identity:auth manager / credential vault 管理凭证
4. 让 Browser Agent 自动提交关键动作
浏览器里的“点击提交”可能意味着发邮件、下单、付款、删数据。必须有审批边界。OWASP AI Agent Security:least privilege、HITL、tool abuse 风险;OWASP Prompt Injection:网页/文档/邮件可成为注入载体;Cloudflare HITL:workflow 暂停等待人工确认
5. 没有外部副作用记录
恢复时最怕重复执行:重复发邮件、重复付款、重复删除。所有外部写动作都要有 idempotency key 和 operation log。Cloudflare Workflows:durable workflow、history、幂等恢复
十五、多租户 SaaS 资源调度与配额设计
在 SaaS 环境下,由于主账号资源配额(如最大并发 10 个实例)的限制,必须在“用户感知”与“物理并发”之间建立分层调度模型。
核心资源模型对比
| 维度 | 租户 (Tenant) / 用户 (User) | 会话 (Session) | 执行 (Run) | Sandbox 实例 |
|---|---|---|---|---|
| 性质 | 数据库记录、权限上下文 | 任务逻辑容器、对话历史 | 实际消耗 CPU/内存的任务 | 物理/虚拟计算资源 |
| 绑定关系 | 长期稳定 | 随任务启动 | 仅在运行期间占用 | 与 Run 临时绑定 |
| 资源限制 | 无限 | 业务逻辑限制 | 受全局配额 10 的约束 | 稀缺资源池 |
关键设计原则
1. 并发位不等于租户数
“10 个实例”代表的是最大并发执行位,而非最大租户数。
- 租户数可达成千上万,但同时处于“运行状态”的 Agent 任务不能超过 10 个。
- 建议参考 Kubernetes ResourceQuota 机制,为不同租户分配 Nominal Quota。
2. Session 与 Sandbox 解耦
不要让 Session 长期霸占 Sandbox。除非 Session 必须保持极低延迟且处于“独占/在线”状态,否则应在 Run 结束后立即释放实例,并将文件、状态外置。
3. 分层调度策略
引入 Sandbox Scheduler 进行精细化管理:
- 按优先级分池:交互式任务(用户正在等待)进入 Warm Pool;后台长任务进入等待队列。
- 配额阶梯:
- 全局上限:10
- 租户并发限制:如 4
- 单用户并发限制:如 2
- 单 Session 并发限制:1
4. 队列与背压 (Backpressure)
当 10 个实例全部满载时,后续请求应进入队列排队并设置合理超时,而不是直接报错。利用任务的异步性(如 Agent 思考时间)来平滑资源尖峰。
十六、生命周期管理的工程落地
Sandbox 的生命周期权应当由外部控制面 (Control Plane) 统一拥有。Agent 框架(如 LangGraph, OpenAI Agents SDK)可以封装使用体验,但不应成为资源分配和安全边界的唯一决策者。
为什么必须由外部管理?
- 配额全局视角:框架只看得到单个任务,控制面才看得到全局 10 个并发的占用情况。
- 安全审计要求:生命周期钩子(创建、销毁)是注入审计探针的最佳时机。
- 状态持久化:框架擅长保存对话历史,但控制面擅长管理 Workspace 镜像和 Artifacts 流转。
状态流转最佳实践
- Warm Pool:预热空闲实例以抵消冷启动耗时。
- Checkpoint & Resume:利用平台提供的暂停/恢复、会话保持或快照能力,在长任务等待 LLM 生成或人类审批时释放部分计算资源,仅保留恢复所需状态。E2B、Browserbase 等产品在这里提供的是不同层面的能力,不能视为同一种 API 或同一种隔离保证。
十七、最终判断
SaaS Agent 使用 Sandbox 的重点不是“选 Docker、KVM 还是 Firecracker”。
真正的问题是:
Agent 的每一次行动,是否都被放进了可控、可恢复、可审计的执行边界里?
最实用的原则是:
graph TD
THINK["Think freely"] --> ACT["Act through controlled sandboxed workflows"]
ACT --> STATE["Persist state outside the sandbox"]
ACT --> APPROVE["Approve dangerous actions"]
ACT --> AUDIT["Audit everything that crosses a boundary"]
这才是 SaaS Agent 场景下 Sandbox 的正确使用方式。
十八、参考文献
以下仅保留完整出处。正文中的引用链接已经直接写明该来源支撑的具体内容。
- [3] AWS Lambda Execution Environment Lifecycle
- [4] AWS SaaS Lens - Pool Isolation
- [5] Kubernetes Multi-tenancy
- [6] Kubernetes Resource Quotas
- [7] Kueue ClusterQueue
- [8] Kueue Fair Sharing
- [9] Inngest: Building a Fair Multi-Tenant Queue
- [10] OpenKruise Warm Pool Management
- [11] Kubernetes Pod Priority and Preemption
- [12] gVisor Security Model
- [13] Firecracker Snapshot Support / Jailer
- [14] Kata Containers Architecture
- [15] E2B Sandbox Documentation
- [16] OpenAI Code Interpreter
- [17] Browserbase Documentation
- [18] OWASP AI Agent Security Cheat Sheet
- [19] OWASP LLM Prompt Injection Prevention
- [20] OWASP Secure Coding with AI Cheat Sheet
- [21] Google Cloud Agent Identity
- [22] OWASP SSRF Prevention Cheat Sheet
- [24] Cloudflare Human-in-the-loop Patterns
- [25] Cloudflare Rules of Workflows
- [26] E2B Code Interpreter Sandbox Reference
- [29] Browserbase Manage Browser Session
- [30] OpenAI Code Interpreter
- [31] E2B Sandbox Persistence
- [32] E2B Sandbox Snapshots
- [33] Firecracker Snapshot Page Fault Handling
- [34] Docker checkpoint CLI
- [35] Playwright BrowserType API
- [36] Chromium User Data Directory
- [37] Modal Sandboxes
- [38] Daytona Docs
- [39] LangGraph Persistence
- [40] OpenAI Agents SDK Sessions
- [41] Temporal Workflow
- [42] Anthropic Managed Agents - Self-hosted Sandboxes
- [43] Cloudflare Claude Managed Agents Integration
- [44] OWASP LLM08: Excessive Agency
- [45] Anthropic MCP Tunnels Overview
- [46] OWASP Top 10 for Agentic Applications 2026
- [47] OpenAI Agents SDK - Model Context Protocol
- [48] OpenAI Agents SDK - Sandbox Clients
- [49] OpenAI Agents SDK - Sandbox Agents Quickstart