第 4 章 / 共 10 章
两个旋钮:审批策略与沙盒决定它能闯多大祸
4.1 为什么权限要拆成两个维度
先看一个很多工具都犯过的错误:把安全性做成一个滑块,从”什么都问我”到”什么都别问我”。这种设计的问题是,它把两个完全不同的问题捆在了一起:
- 它有能力做什么?(技术边界)
- 它做之前要不要问我?(打断频率)
这两件事没有必然联系。“能改工作区文件,但每次都问我”和”只能读文件,但读的时候不用问”是两种完全合理、且完全不同的配置。
Codex 把它们拆成了两个独立的旋钮:
- 沙盒(sandbox):决定它技术上能碰到什么。
- 审批策略(approval policy):决定它什么时候停下来问你。
理解这个拆分,是安全使用 Codex 的全部基础。
4.2 沙盒三档:能力边界
| 沙盒模式 | 能读 | 能写 | 能跑命令 | 能联网 |
|---|---|---|---|---|
read-only | 是 | 否 | 否 | 否 |
workspace-write | 是 | 仅工作目录内 | 是 | 默认否 |
danger-full-access | 是 | 全盘 | 是 | 是 |
几个关键细节:
workspace-write默认阻止向工作目录以外写入。它可以改你的项目文件,但不能去改~/.ssh/config。- 网络访问默认是关闭的,即使在
workspace-write下也是。需要联网(比如装依赖)时要显式开启。这是刻意的设计:断网的代理装不了恶意包,也发不出你的代码。 danger-full-access移除所有限制。它对应--dangerously-bypass-approvals-and-sandbox(简写--yolo)这个参数——参数名本身就是警告。
Codex 的默认值也体现了这套思路:在受版本控制的目录里默认 workspace-write,在没有版本控制的目录里默认 read-only。理由很直接——有 Git 的地方,改坏了能还原;没有 Git 的地方,改坏了就没了。
4.3 审批三档:打断时机
| 审批策略 | 行为 |
|---|---|
untrusted | 已知安全的只读操作直接跑,任何会改变状态的操作都要你批准 |
on-request | 沙盒范围内的操作直接跑;需要越界时(写到工作区外、访问网络)才请求批准 |
never | 从不询问 |
never 看起来很爽,但要配合沙盒一起理解:never + read-only 是安全的(它什么都改不了,所以不用问),never + danger-full-access 等于把 root 权限交给一个会犯错的实体。前者适合 CI 里跑只读分析,后者几乎没有正当的日常用途。
默认组合是 on-request + workspace-write(在 Git 仓库里)。这个默认值对大多数日常开发是合理的。
4.4 四种场景,四种组合
# 场景一:摸清陌生仓库 / 做代码分析,绝不改文件
codex --sandbox read-only --ask-for-approval on-request
# 场景二:日常开发(默认组合,可直接 codex 启动)
codex --sandbox workspace-write --ask-for-approval on-request
# 场景三:跑一个你已经充分理解、边界清楚的重复性改动
codex --sandbox workspace-write --ask-for-approval never
# 场景四:CI 里做只读检查,不能有交互
codex exec --sandbox read-only -a never "检查是否有硬编码密钥"
--ask-for-approval 可以简写为 -a,--sandbox 可以简写为 -s。

4.5 什么时候才该开网络
需要联网的合理场景其实不多,主要是:装依赖、拉取远程分支、调用外部 API 做验证。开启方式是在配置文件里:
[sandbox_workspace_write]
network_access = true
开之前问自己一个问题:这次任务里,Codex 会执行哪些我没看过的第三方代码? 装依赖意味着执行安装脚本;跑测试可能触发下载。如果答案是”不确定”,那就先手动把依赖装好,再让 Codex 在断网状态下工作。
4.6 动手:用同一个任务撞两次沙盒边界
广告位 · Multiplex 关联广告