工程级解读 Agent 基础设施 Sandbox 安全 CREAO

云端 Agent 基础设施:跟桌面有什么不同,我们学到了什么

原文:Peter Pang (@intuitiveml) · Co-founder, CREAO · Previously GenAI @ Meta (LLaMA)
来源:X Article · 2026-06-05 · 298K views

9,500原文词数
12 min阅读时间
X Article来源类型
高级技术难度

🔍 Part 1: 工程级解读

把桌面 Agent 搬到云端,基础设施层面哪些东西会彻底改变,CREAO 怎么一个个解决

这篇文章回答的问题:把一个桌面 Agent 搬到云端运行,基础设施层面到底哪些东西会彻底改变,以及 CREAO 是怎么一个个解决的?
这篇文章应该回答但没回答的问题:snapshot 存储成本多少?热交换失败重试时用户状态怎么办?API bridge 成为单点故障怎么兜底?在多 region 场景下 snapshot 一致性如何保证?

🧠 运行时模型:这篇文章里的东西到底跑在哪里?

Peter Pang 描述的系统有三个明确的进程/信任边界,搞清楚它们各自在哪里运行,才能理解整个设计的意图:

组件跑在哪信任等级职责
Sandbox(沙箱) 容器 / microVM,共享宿主机 🔴 不信任 — 假设内部代码已被攻破 运行用户 Agent 代码 + Runner(平台注入的 harness 库)
API Bridge(凭证桥) Sandbox 外部,宿主机网络 🟢 受信任 — 平台控制 接收 sandbox 的 HTTP 请求,注入 OAuth token,转发到外部 API;同时承载计费、日志、监控的上报通道
Platform Control Plane(控制面) 独立服务集群 🟢 受信任 管理 snapshot 生命周期、签发 per-run JWT、调度 sandbox 启停、触发器路由(UI click / cron / API call → 统一 executeAgent)
关键调用链路:Trigger(UI/cron/API)→ Control Plane 签 JWT → 启动 Sandbox(从 frozen snapshot 恢复)→ 热交换 Runner → Agent 代码调用 localhost → API Bridge 验证 JWT + IP → 注入 OAuth token → 转发到 Slack/GitHub 等 → Response 原路返回(token 不进入 sandbox 内存)

🏗️ 核心架构拆解:两个 Lesson 的工程实现

Lesson 1:慢变快分离 — Sandbox Snapshot + Runner 热交换

问题的本质是变更频率不匹配。用户环境(pip install 的包、下载的数据、写的脚本)变更频率低(用户主动触发),平台 Runner 代码变更频率高(一天部署多次)。如果打包成一个 artifact,每次 Runner 更新都要重建 snapshot,用户环境就被破坏了。

Peter Pang 用了一个精妙的操作系统类比:

内核会更新。你的 home 目录不会。你不会为了装一个安全补丁就把硬盘格了。

The kernel changes. Your home directory does not. You do not wipe the disk to install a security patch.

热交换的 5 步序列(300ms 完成):

1
Stage:将新版 Runner 放到 sandbox 内的临时目录
2
Validatenode --check 语法校验,确保不会替换一个有语法错误的文件
3
Atomic Swap:解锁旧文件的 immutable flag → 覆盖 → chattr +i 重新锁定 → 隐藏 chattr 二进制文件本身(防止 sandbox 内代码逆向解锁)
4
Purge Cache:清除 V8 编译缓存(/home/user/.cache/v8-compile-cache/*),防止加载旧的字节码
5
Fail-Fast:任何步骤失败,直接 kill 整个 sandbox,用全新 template 重试。不允许半升级状态运行 Agent
⚠️ 注意:步骤 3 中"隐藏 chattr 二进制"是个关键的安全细节。如果 sandbox 内的代码能找到 chattr,就能解除 immutable flag,替换 Runner。这是 defense-in-depth 的体现——不是信任 sandbox 的隔离,而是主动减少攻击面。

Lesson 2:凭证外置 — API Bridge 模式

安全模型的核心假设:sandbox 内的代码已经被攻破了。不是"可能被攻破",是"已经攻破了"。在这个假设下设计。

安全层机制防护什么绕过成本
网络层 IP Allowlist — Bridge 只接受 sandbox 宿主机内网 IP 段的连接 外部直接调用 Bridge(开发者笔记本、公网、泄露的 URL) 需要获取内网访问权限
应用层 Short-lived JWT — per-run 签发,scope 包含 user/app/session,有效期仅覆盖单次运行 Sandbox 被劫持后横向移动;过期 token 重放 需要在 token 有效期内 + 内网环境同时满足
架构层 Token 永不进入 sandbox — Bridge 在 host 侧注入,response 不含 credential process.env dump、内存读取、prompt injection 钓取 需要攻破 Bridge 本身(受信任边界外)

🔧 代码级细节:如果你要自己实现

Runner 热交换的核心代码逻辑(伪代码,基于原文描述推断):

# 热交换 Runner — 300ms 完成的原子操作
function hotSwapRunner(sandbox, newRunnerPath):
    # Step 1: 拷贝到临时位置
    tmpPath = sandbox.fs.tempDir() + "/runner_new.js"
    sandbox.fs.copy(newRunnerPath, tmpPath)

    # Step 2: 语法校验
    exitCode = sandbox.exec("node --check " + tmpPath)
    if exitCode != 0:
        killSandbox(sandbox)  # fail-fast
        return BOOT_FRESH

    # Step 3: 原子交换
    sandbox.exec("chattr -i /opt/runner/runner.js")     # 解锁旧文件
    sandbox.exec(f"cp {tmpPath} /opt/runner/runner.js")  # 覆盖
    sandbox.exec("chattr +i /opt/runner/runner.js")     # 重新锁定
    sandbox.exec("rm /usr/bin/chattr")                  # 隐藏工具本身

    # Step 4: 清除 V8 编译缓存
    sandbox.exec("rm -rf /home/user/.cache/v8-compile-cache/*")

    # Step 5: 验证成功 → 运行结束后 re-snapshot
    return SWAP_SUCCESS  # 触发 re-snapshot

API Bridge 的 JWT 签发与验证:

# Control Plane: 签发 per-run JWT
function mintRunToken(run):
    return jwt.sign({
        sub: run.userId,
        app: run.appId,
        session: run.sessionId,
        exp: now() + run.maxDuration  # 仅覆盖运行窗口
    }, PLATFORM_SECRET)

# API Bridge: 验证并注入凭证
bridge.handleRequest = async (req) => {
    # 第一层:网络层 — 非内网 IP 直接丢弃
    if not isInternalIP(req.sourceIP):
        return 403

    # 第二层:JWT 验证
    claims = jwt.verify(req.headers["X-Run-Token"], PLATFORM_SECRET)
    if claims.exp < now():
        return 401

    # 从 vault 解析该用户的 OAuth token(sandbox 永远看不到)
    userToken = await vault.resolve(claims.sub, req.targetService)

    # 注入 token,转发请求
    response = await fetch(req.targetUrl, {
        headers: { Authorization: `Bearer ${userToken}` }
    })

    # 返回 response body(不含 token)
    return response.body
}

⚖️ DIY 对比:手搓版 vs CREAO 官方版

工程细节手搓版(桌面 Agent 套路)CREAO 官方版
环境持久化 pip install 写入本地 venv,终端关了就没了 Frozen sandbox snapshot,每次 run 从同一 image 启动
依赖可复现 6 个月前的 pip install 今天 resolve 到不同版本 Snapshot 是同一组 bytes,永远不变
平台代码更新 直接覆盖,或者重建环境 300ms 原子热交换,用户环境不受影响
凭证存储 写在 .env 文件里,Agent 代码直接读取 Host 侧 Vault,sandbox 通过 Bridge 间接使用,token 永不进入内存
攻击面控制 信任 Agent 代码不会泄露 key 假设 sandbox 已被攻破,JWT per-run + IP allowlist + token 不落地
触发方式 手动运行,或简单 cron 统一 executeAgent:UI / cron / API 调用共用一条管道
失败恢复 用户手动重试 自动 kill sandbox → fresh template 重试(但代价是可能丢失用户环境)

🎯 选型决策框架:什么时候该考虑这种架构?

场景该用这种架构吗?理由
个人开发工具 Agent ❌ 不需要 桌面 Agent 足够,你自己就是信任边界
SaaS Agent 平台(多租户) ✅ 必须要 多用户共享硬件,安全隔离是硬需求
企业内部 Agent(单租户) ⚠️ 部分需要 Snapshot 可复现 + 凭证外置有价值,但 IP allowlist 可能过于严格
Cron-driven Agent(无人值守) ✅ 关键需求 环境冻结 + Runner 热交换解决了"部署破坏 cron"的问题
CLI 工具 / 本地 Agent ❌ 不需要 过度工程,桌面框架够用
Agent-to-Agent 编排 ✅ 强烈推荐 统一 executeAgent 入口让 A2A 调用只是一个路由变更
竞品对比:类似思路不止 CREAO 一家。OpenAI 的 Sandbox Agents 提供了容器化的 Agent 执行环境;Google GKE 的 Agent Sandbox + Pod Snapshot 做了类似的事;Cloudflare Dynamic Workers 用 Cap'n Web RPC 做 sandbox 与 harness 间的安全桥接;社区还有 "Phantom Token Pattern" 和 IETF 的 CB4A(Credential Broker for Agents)草案。CREAO 的独特之处在于把 环境冻结 + Runner 热交换 + 凭证桥 三件事串成了一个完整故事。

🚫 诚实限制:这篇文章没告诉你的

1. Snapshot 存储成本:每个用户一个 frozen snapshot,如果用户量大(比如 10 万),存储 I/O 和成本不是小数目。文章完全没提。
2. Re-snapshot 的原子性风险:热交换成功后 re-snapshot,如果 re-snapshot 失败,下次 run 又要走一遍热交换。累积效应是什么?
3. 热交换失败的用户体验:原文说"kill sandbox,用全新 template 重试"——但全新 template 意味着用户自定义的环境全丢了。这个 fallback 的代价是"降级到空白状态"。
4. API Bridge 是单点故障:所有外部 API 调用、计费、日志都走一个 Bridge。Bridge 挂了 = 所有 Agent 都不能调用外部服务。文章没提 Bridge 的高可用方案。
5. Response 侧的敏感数据泄露:Bridge 确保 token 不进入 sandbox,但 API response 里可能包含敏感数据(比如 Slack 消息里的 API key、GitHub issue 里的 token)。Bridge 没做 response 侧的过滤。
6. 利益相关:Peter Pang 是 CREAO CTO/Co-founder。这篇文章本质上是技术营销——展示 CREAO 的工程能力,吸引开发者和客户。方案本身有技术含量,但阅读时需要意识到这是供应商视角,不是中立评估。

💬 金句

Cloud agent infrastructure has none of those luxuries.

云端 Agent 基础设施没有这些奢侈品。
The security model has to assume the code inside the sandbox is already compromised, not hope against it.

安全模型必须假设 sandbox 内的代码已经被攻破了,而不是祈祷不会。
An agent on a laptop is bound to the laptop. An agent in the cloud is a function the rest of your stack can call.

笔记本上的 Agent 绑定在笔记本上。云端的 Agent 是你的技术栈可以调用的一个函数。

🗣️ Part 2: 苏格拉底对话

从 Docker 容器到安全凭证——一步步理解云端 Agent 的设计挑战

🧑‍💻 尾巴
我刚把我的 Agent 从本地搬到云端跑了,用的是 Docker 容器。感觉没什么区别啊?
🧑‍🏫 老师
你每次 run 完,容器销毁了吗?
🧑‍💻 尾巴
对,跑完就销毁。每次 run 都从干净 image 起一个新容器。
🧑‍🏫 老师
那你的 Agent 在运行中安装的包、下载的数据、写的脚本——下次 run 还在吗?
🧑‍💻 尾巴
不在了……所以每次都要重新 pip install。但我可以打一个新的 image 啊。
🧑‍🏫 老师
可以。但如果你的平台 runner 代码一天部署 3 次,每次都要把用户的自定义环境重新打进去呢?
🧑‍💻 尾巴
那确实很麻烦。用户每次等 image rebuild……这就是 CREAO 遇到的"耦合问题"。
🧑‍🏫 老师
对。他们的解法是——你用 Linux 的时候,内核更新会清空你的 home 目录吗?
🧑‍💻 尾巴
当然不会。内核和用户空间是分开的。
🧑‍🏫 老师
CREAO 做的就是同一件事:用户的 snapshot 就是 home 目录,Runner 就是内核。Runner 更新时,300ms 热交换,用户的包、文件、配置原封不动。
🧑‍💻 尾巴
那安全呢?Agent 代码毕竟是大模型写的,万一被 prompt injection 了,process.env 全被 dump 出来怎么办?
🧑‍🏫 老师
这正是第二个 Lesson。你觉得 process.env 里能 dump 到什么?
🧑‍💻 尾巴
API keys、OAuth tokens……所有凭证。但 CREAO 说 credentials 永远不进 sandbox——那 sandbox 里的代码怎么调 Slack API?
🧑‍🏫 老师
它不发 Slack API,它发一个 localhost 请求给 Bridge。Bridge 在 sandbox 外面拿着 token 帮你发。攻击者从 process.env 里 dump 到的只是一个 15 分钟过期的 JWT,而且只从内网 IP 才能用。
🧑‍💻 尾巴
所以攻击者拿到的是一把只能开一个房间、15 分钟后自动失效的钥匙——而且这个房间还只能从大楼内部进入。
🧑‍🏫 老师
精准。现在你想想:Peter Pang 说"Agent 是一个带自然语言接口的函数"。一个函数最强大的地方是什么?
🧑‍💻 尾巴
可以被任何调用者调用。人点的按钮、cron 定时器、另一个 Agent……只要接口统一。
🧑‍🏫 老师
没错。那你有没有想过:如果 executeAgent 被另一个 Agent 调用,那个 Agent 也在 sandbox 里,它的凭证也走 Bridge——这会不会形成一链条式的攻击面?
🧑‍💻 尾巴
好问题……这篇文章确实没深入讨论 Agent-to-Agent 编排的安全边界。

💡 Part 3: 个性化洞察

跟你直接相关的发现和可执行建议

1. 快慢分离原则直接适用于你的 Agent 平台项目
为什么跟你有关:你做自己的 AI 产品,如果涉及 Agent 在云端跑,用户环境和平台代码的耦合问题迟早会遇到。CREAO 的"内核/home 分离"模型是一个成熟的参考架构。
你可以怎么做:在设计数据持久化层时,明确区分"用户拥有的 artifact"和"平台控制的 artifact"。用不同的更新策略和生命周期管理。这是架构决策阶段就该画好的线。
2. API Bridge 模式比 "把 token 放环境变量" 安全一个数量级
为什么跟你有关:你的 Agent 如果要调用外部 API(GitHub、数据库、第三方服务),把 token 放在 .env 或 config 里是最方便也最危险的做法。prompt injection 攻击已经从理论变成了现实威胁。
你可以怎么做:即使不用 CREAO 的完整架构,也可以引入一个轻量的"凭证代理"——Agent 代码不直接持有 token,而是通过 localhost 调用一个 credential proxy,proxy 从 vault 注入 token 后转发。这个模式可以独立于任何平台使用。
3. 统一 executeAgent 入口 = Agent-as-a-Service 的架构前提
为什么跟你有关:你在关注 AI 产品方向。Agent-as-a-Service 的核心卖点就是"写一次,到处调"。CREAO 的设计让 UI click、cron、API 调用共享一条执行管道——这意味着 Agent 的触发方式是一个路由配置,不是架构变更。
你可以怎么做:如果你要构建自己的 Agent 平台,从第一天就设计统一的执行入口。trigger → queue → executeAgent → result。新增触发源只需要在路由层加一个 producer。
4. "假设 sandbox 已被攻破" 是正确的心智模型
为什么跟你有关:你在做 AI 相关的产品和技术评估,安全是绕不过去的话题。CREAO 的安全设计思路(defense-in-depth: IP allowlist + per-run JWT + token 不落地)是业界最佳实践的体现。
你可以怎么做:在评估任何 Agent 平台或框架时,用这篇文章的 checklist 做安全审查:token 在哪里?JWT 有效期多长?sandbox 逃逸后攻击者能获取什么?Bridge 有没有单点故障?
5. 技术写作的标杆:Peter Pang 的叙事结构值得学习
为什么跟你有关:你在做技术自媒体,内容创作是核心能力之一。这篇文章的结构(问题引入 → 桌面 vs 云端的对比 → Lesson 1 架构细节 → Lesson 2 安全细节 → 总结为 4 条原则)是高质量技术写作的模板。
你可以怎么做:下次写技术分析文章,套用这个结构:先建立读者已知的锚点(桌面 Agent),再展示差异(云端没有的奢侈品),然后逐层深入(具体问题 → 具体解法 → 代码级细节),最后抽成可复用的原则。

💬 精选评论

社区对 API Bridge 模式和凭证安全的讨论

@Ronycoder
云端 Agent 的安全归根结底是一个原则:如果没有一个隔离访问的 Bridge 模型,一个泄露的 token 就能把 sandbox 突破变成更大的安全问题。
Security in cloud agents comes down to one principle: Without a bridge model that isolates access, a single leaked token can turn a sandbox breach into a much larger security problem.
Cloudflare Blog — Dynamic Workers
Cloudflare 的 Dynamic Workers 用 Cap'n Web RPC 在 sandbox 和 harness 之间做安全桥接,harness 侧可以做 HTTP 过滤和凭证注入,Agent 在 sandbox 里甚至不知道自己不是在调本地库。这跟 CREAO 的 API Bridge 思路如出一辙,但 Cloudflare 的方案多了自动 HTTP 过滤。
The Workers Runtime will automatically set up a Cap'n Web RPC bridge between the sandbox and your harness code, so that the agent can invoke your API across the security boundary without ever realizing that it isn't using a local library.
SANS Institute — Credential Broker for Agents (CB4A)
SANS 提出的 CB4A(Credential Broker for Agents)已经作为 IETF Internet-Draft 提交,目标是标准化 AI Agent 的凭证保管和代理层。CREAO 的 API Bridge 是 CB4A 思路的一个具体实现,但 CB4A 的野心是成为跨平台标准。
The Credential Broker for Agents (CB4A) is an architecture proposed in an IETF Internet-Draft that specifies a credential vaulting and brokering layer for AI agents.
Reddit — Phantom Token Pattern
"幻影 Token 模式"跟 CREAO 的凭证桥思路类似:一个凭证注入代理坐在 sandbox 外面,Agent 永远看不到真实的 token。不同之处在于 Phantom Token 更强调 token 的生命周期管理和自动轮换。
We built what we're calling the "phantom token pattern" — a credential injection proxy that sits outside the sandbox. The agent never sees the real token.