代码 Agent 沙箱怎么做最小验收?我用 4 条命令先验 repo 只读、scratch 可写、默认无网

代码 Agent 沙箱怎么做最小验收?我用 4 条命令先验 repo 只读、scratch 可写、默认无网

我在 Docker 28.5.2 上直接跑了 4 条命令,先验 代码 Agent 沙箱 最容易被讲空的 3 条底线:repo 只读、scratch 可写、默认无网。短答案是:这轮最小验收值得所有准备让代码 Agent 读仓库、跑测试、改文件的团队先做一遍;但如果你只是起了个容器,还没有把审批和日志留在控制面,那还不能算拿到了可上线的代码 Agent 沙箱。 OpenAI 刚在 Running Codex safely at OpenAI 里把这个边界讲得很直白:Codex 新闻稿说的是产品内部部署,文档里更通用的名字则是 Sandbox AgentsGuardrails and human review;前者是执行环境,后者是审批与控制面。

执行面先验清,治理面再放权。

这个边界和我们之前写过的 OpenAI Agents SDK 边界梳理 能直接对上;如果你在补更大的 Agent 基础设施,也可以顺手对照 infra 主题页 和那篇 Cloudflare 内部 AI 工程栈拆解:真正要补的不是一个新名词,而是边界和审查链路。

这轮代码 Agent 沙箱最小复现:4 条命令

环境标签:Docker 28.5.2 + Alpine + 本机目录挂载

docker run --name codexsmoke_ro_1201 --network none \
  -v /Users/fuuqiu/clawd/automation/ghost/ops/codex-sandbox-smoke/repo:/workspace:ro \
  alpine touch /workspace/WRITE.txt

docker run --name codexsmoke_scratch_1201 --network none \
  -v /Users/fuuqiu/clawd/automation/ghost/ops/codex-sandbox-smoke/repo:/workspace:ro \
  -v /Users/fuuqiu/clawd/automation/ghost/ops/codex-sandbox-smoke/scratch:/scratch \
  alpine touch /scratch/out.txt

docker run --name codexsmoke_netnone_1201 --network none \
  alpine wget -O- https://example.com

docker run --name codexsmoke_netok_1201 \
  alpine wget -O- https://example.com

对应输出也很直接:

  • repo 只读写入失败:touch: /workspace/WRITE.txt: Read-only file system
  • scratch 写入成功:容器退出码 0
  • 默认无网:wget: bad address 'example.com'
  • bridge 网络放开后:wget 能正常拿回 Example Domain

如果你要做一轮最便宜的 代码 Agent 沙箱 smoke test,这 4 条命令已经足够回答第一层问题:你的执行边界到底是靠参数真收紧了,还是还停留在“默认希望 Agent 不会乱来”。

第一步:先验 repo 是不是真的只读

执行:

docker run --name codexsmoke_ro_1201 --network none \
  -v /Users/fuuqiu/clawd/automation/ghost/ops/codex-sandbox-smoke/repo:/workspace:ro \
  alpine touch /workspace/WRITE.txt

通过信号:

touch: /workspace/WRITE.txt: Read-only file system

失败时说明什么:

  • 如果这条命令执行成功,你的 repo 默认就是可写的
  • 这意味着 Agent 第一轮就能直接改源码、脚本、配置和 hooks
  • 这种基线不适合直接进入真实仓库读写链路

为什么这一步要排第一?因为只要源码目录一开始就可写,后面再讲“先观察再执行”“让 reviewer 再看一眼”,往往都会退化成事后补救。对已经在让 Agent 批量产出补丁或 PR 的团队,这个风险和我们那篇 reviewer 证据链 讨论的是同一件事:不是先追求更快提交,而是先证明边界没塌。

第二步:再验 scratch 有没有被单独留出来

执行:

docker run --name codexsmoke_scratch_1201 --network none \
  -v /Users/fuuqiu/clawd/automation/ghost/ops/codex-sandbox-smoke/repo:/workspace:ro \
  -v /Users/fuuqiu/clawd/automation/ghost/ops/codex-sandbox-smoke/scratch:/scratch \
  alpine touch /scratch/out.txt

通过信号:

  • 容器退出码是 0
  • docker inspect codexsmoke_scratch_1201 里能看到 /workspacerw=False
  • 同一份 inspect 里 /scratchrw=True

失败时说明什么:

  • 如果 scratch 也不可写,Agent 很难保存 patch、日志、截图、临时报告
  • 如果 repo 和 scratch 混成同一个可写挂载,Agent 又会重新拿回对源码目录的直接改写权

这一步的目标不是让 Agent 完全不能写,而是把“写哪儿”这件事先收紧。更稳的基线不是“一刀切全只读”,而是 repo 只读,scratch 可写

第三步:把默认网络改成先关后开

执行:

docker run --name codexsmoke_netnone_1201 --network none \
  alpine wget -O- https://example.com

通过信号:

wget: bad address 'example.com'

对照命令:

docker run --name codexsmoke_netok_1201 \
  alpine wget -O- https://example.com

对照输出:

<!doctype html><html lang="en"><head><title>Example Domain</title>...

失败时说明什么:

  • 如果 --network none 这条还能直接出网,你的隔离层根本没有按预期收口
  • 如果你平时默认就是 bridge 网络,那很多本来该挂到审批或 allowlist 的外连,第一天就已经放过去了

代码 Agent 沙箱 来说,默认 bridge 网络不是“中立配置”,而是已经替 Agent 开了一层外连能力。先关后开,比先全开再补审批更容易解释,也更容易审计。

第四步:用 inspect 把“看起来像隔离”变成“配置上真隔离”

执行:

docker inspect codexsmoke_ro_1201

docker inspect codexsmoke_scratch_1201

docker inspect codexsmoke_netnone_1201

我这轮看到的关键状态是:

  • codexsmoke_ro_1201/workspace 挂载 rw=FalseNetworkMode=none
  • codexsmoke_scratch_1201/workspace 只读、/scratch 可写,NetworkMode=none
  • codexsmoke_netnone_1201:退出码 1NetworkMode=none
  • codexsmoke_netok_1201:退出码 0NetworkMode=bridge

通过信号:配置结果和命令意图一致。

失败时说明什么:如果运行输出和 inspect 结果对不上,优先信配置层。因为很多“看起来没写进去”“好像没联网”只是偶然结果,不能拿来当正式基线。

代码 Agent 沙箱上线前,最小顺序应该怎么排

如果你下周就要在团队里试点,我建议直接照这个顺序走:

  1. 把 repo 先挂成只读
    通过:直接写入报只读错误;失败:源码目录还能被容器写。

  2. 给 Agent 单独留一个 scratch 目录或工作卷
    通过:产物能落到 scratch;失败:要么哪儿都不能写,要么源码目录也跟着被放开。

  3. 默认网络收紧
    通过:无网容器不能直接拉外部页面;失败:默认外连已放开。

  4. 把越界动作接到审批层
    通过:改写 repo、出网、敏感命令会产生审批事件;失败:所有风险动作都靠容器内部脚本兜底。

  5. 把日志、diff 和产物接回 review 流程
    通过:reviewer 能看见 Agent 做了什么;失败:只剩一个“任务完成”的结果,没有过程证据。

前 3 步是这轮已经实测过的;后 2 步则是 OpenAI 这次讲 Codex 安全时最值得拿回去补的地方。OpenAI 的原话不是“沙箱解决一切”,而是 approvals and sandboxing work together。如果你的 rollout 只做到了前 3 步,那它更像一个合格的执行面基线,还不是完整治理面。

这篇 tutorial 没覆盖到什么

这轮本机实验没有验证 3 件事,所以别把结论说大:

  • 没有验证审批工作流本身:这需要控制面或 harness,不是 Docker 参数自己能证明
  • 没有验证审计日志链路:我只验证了执行边界,没有验证谁批准了什么、为什么批准
  • 没有验证真实代码变更回写流程:这篇教程故意把 repo 保持在只读基线,没有继续演示 patch 回写

所以这篇文章能支撑的判断很收敛:代码 Agent 沙箱 的第一层基线,完全可以先用只读挂载、scratch、默认无网和 inspect 校验跑通;但如果要把它推进生产,审批和日志还得回到控制面去补。

结论

如果你们现在正准备让 Agent 真读仓库、真跑命令、真碰配置,我会建议把这轮 代码 Agent 沙箱 最小验收排到很前面。它的价值不在于“又加了一层容器”,而在于你终于能用明确的通过/失败信号回答 4 个问题:repo 能不能直接写、临时产物写到哪、默认能不能出网、配置层到底有没有真的收紧。

而 OpenAI 这次把 Codex 安全边界讲透后的最大提醒,也不是“Codex 很安全”,而是执行面和治理面要拆开验。先把这 4 个本地检查做扎实,再谈自动化放权,顺序通常会更稳。

来源

Read more

GitHub Copilot CLI 企业托管插件怎么落地:我先按官方 marketplace 跑了一次,再说哪些能统一、哪些还统一不了

GitHub Copilot CLI 企业托管插件怎么落地:我先按官方 marketplace 跑了一次,再说哪些能统一、哪些还统一不了

GitHub Copilot CLI 企业托管插件怎么落地:我先按官方 marketplace 跑了一次,再说哪些能统一、哪些还统一不了 如果你们团队已经把 GitHub Copilot CLI 当成开发工具链的一部分,现在最值得先看的,不是“又多了一个 Copilot 预览功能”,而是 GitHub 终于给 Copilot CLI 补上了企业统一下发插件的入口。短答案是:值得平台团队现在就做一轮小范围试点,但别把它误解成“Copilot CLI 已经有了完整企业治理面”。它现在更像一个能统一 marketplace 和 auto-install 插件的分发层,不等于 MCP、IDE 插件策略、模型权限这些边界也一起被接管了。 这里先把名字说准。GitHub 这次公开预览的官方名称是 enterprise-managed plugins for GitHub Copilot CLI。

By One AI
GitHub Copilot 的 GPT-5.2 / GPT-5.2-Codex 6 月要退役:手动锁模型的团队现在就该补一次排查

GitHub Copilot 的 GPT-5.2 / GPT-5.2-Codex 6 月要退役:手动锁模型的团队现在就该补一次排查

GitHub Copilot 的 GPT-5.2 / GPT-5.2-Codex 6 月要退役:手动锁模型的团队现在就该补一次排查 截至 2026-05-02,GitHub 已在官方 changelog 里写明:从 2026-06-01 开始,GPT-5.2 和 GPT-5.2-Codex 会从大多数 GitHub Copilot 体验里退役,例外只剩 Copilot Code Review 里的 GPT-5.2-Codex。短答案也很直接:如果你们平时手动选模型、给团队设过 model policies,或者把某些 Copilot 流程默认绑在旧模型上,这不是“到点自动变好”的提醒,而是现在就该补的一轮排查。 反过来,如果团队大部分人一直用 Auto

By One AI
Cloudflare Rust Workers 遇到 panic 还会把后续请求一起拖死吗?我做了个最小复现

Cloudflare Rust Workers 遇到 panic 还会把后续请求一起拖死吗?我做了个最小复现

Cloudflare Rust Workers 遇到 panic 还会把后续请求一起拖死吗?我做了个最小复现 如果你现在评估 Cloudflare Rust Workers panic recovery,先说结论:按我这轮用 workers-rs 最新模板、worker-build --panic-unwind 和 wrangler dev 做的最小复现,单次 /panic 和 /abort 请求都会失败并返回 500,但后续新的 / 请求还能继续返回 200 ok。这说明 Cloudflare 最近这轮 Rust Worker 恢复改进,至少已经把“一个请求炸掉后把后续请求一起拖死”这个老风险明显收紧了。 但这不等于 Rust Worker 从此“出了 panic 也没事”。它更准确的含义是:

By One AI
Cloudflare Shared Dictionaries 现在值得试吗?我按官方 demo 跑了一次,先给频繁发版团队一个判断

Cloudflare Shared Dictionaries 现在值得试吗?我按官方 demo 跑了一次,先给频繁发版团队一个判断

Cloudflare Shared Dictionaries 现在值得试吗?我按官方 demo 跑了一次,先给频繁发版团队一个判断 如果你的网站或 Web 应用每天会发很多次前端 bundle,而且每次改动都不大,那么截至 2026-04-29,Cloudflare Shared Dictionaries 已经值得进测试名单,但还不值得当成“所有站点都该立刻上的通用优化项”。它真正解决的不是传统 gzip / Brotli 不够强,而是“你明明只改了一小段配置,用户却要重新下载整包”的高频发版浪费。 我这轮没有只看 Cloudflare 的发布文。我直接按官方 demo 给的 curl 流程跑了一次 canicompress.com:同一类约 93KB 的 JavaScript 资源,普通 gzip 传输了 22,423B,带共享字典的

By One AI
Follow @Fuuqius