Codex CLI 0.145.0配置沙箱模式和审批策略
阿沐沐,
Codex CLI 沙箱与审批配置:从 workspace-write 扩展可写目录和命令网络权限
Codex CLI 能正常调用模型之后,下一步通常不是继续放大权限,而是回答一个更具体的问题:当前任务究竟需要读哪些文件、写到哪里、是否允许 Shell 命令联网,以及越界时要不要停下来询问。
本文以 sandbox_mode = "workspace-write" 和 approval_policy = "on-request" 为基线,给出只读审查、日常开发、额外输出目录、依赖下载和非交互检查等场景的配置方法。适用版本为 Codex CLI 0.145.0,最后核验日期为 2026-07-28。
证据边界也先说清楚:本文的字段、枚举和默认值来自官方文档、本机 0.145.0 CLI 帮助与该版本固定 Schema。配置解析或严格加载只能证明字段被客户端接受,不能代替真实文件写入、越界审批和命令联网测试。本文不讨论 Provider、API 认证、模型、推理强度、Personality、MCP、Skills、Plugins、Agents 或 Hooks。
文中的 /status 是进入 Codex 交互式 TUI 后输入的命令,不是 PowerShell、CMD、Bash 或 Zsh 命令。还要提前区分两种网络边界:sandbox_workspace_write.network_access 控制沙箱内 Shell 命令联网,web_search 或 --search 控制模型使用 Web Search 工具;任一结果都不能证明另一项已经启用。
先理解两条独立边界
沙箱和审批经常被写在一起,但它们解决的是两个不同问题:
sandbox_mode是命令执行的技术边界,决定默认能读写到哪里。approval_policy决定执行动作前何时暂停并请求批准;触发原因可以是越过沙箱、访问网络,也可以是命令不在可信集合中。
因此,approval_policy = "never" 不等于拥有完整权限。它只表示不弹出批准请求;如果沙箱仍是 workspace-write,越界操作仍会失败,并立即把失败返回给模型。反过来,danger-full-access 放宽的是沙箱边界,也不等于命令本身安全。
Codex CLI 0.145.0 的帮助列出三种沙箱模式:
| sandbox_mode | 适合的任务 | 主要边界 |
|---|---|---|
read-only | 阅读、分析、代码审查 | 默认不允许写入 |
workspace-write | 日常修改、构建、测试 | 允许工作区内写入,可单独增加可写根目录 |
danger-full-access | 已有外部隔离的特殊运行环境 | 不再依赖 Codex 沙箱限制文件和命令范围,风险显著增加 |
同一版本的 CLI 帮助列出三种字符串审批策略:
| approval_policy | 行为 | 适合的交互方式 |
|---|---|---|
untrusted | 只有被判定为可信且只读的命令自动执行,其他命令请求批准 | 陌生仓库或希望逐步确认的交互检查 |
on-request | 由模型判断何时请求批准 | 常规交互开发,也是官方默认配置文档推荐搭配 workspace-write 使用的基线 |
never | 从不请求批准,失败直接返回给模型 | 明确要求无交互、且已有合适沙箱或外部隔离的流程 |
danger-full-access + never 同时移除了 Codex 沙箱约束和批准停顿。本文只把它列为风险边界,不提供推荐配置;如果没有容器、虚拟机或同等级外部隔离,不应把它当作“省事模式”。
修改前先备份,所有示例都只合并字段
下面所有 TOML 片段都用于合并到现有配置,不是空文件完整模板,更不能整文件覆盖。已有同名顶层键或 [sandbox_workspace_write] 表时,修改原值;不要重复追加同名键或同名表。原有 Provider、Profile 和其他配置全部保留。
备份命令默认操作用户级 $CODEX_HOME/config.toml,未设置 CODEX_HOME 时使用 $HOME/.codex/config.toml。如果要修改项目级配置,必须把 $configPath 或 $config_path 改为该项目实际的 .codex/config.toml 绝对路径,并确保备份、编辑和回退始终指向同一文件。
PowerShell 备份
在实际运行 Codex 的 Windows PowerShell 中执行:
$codexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $HOME ".codex" }
$configPath = Join-Path $codexHome "config.toml"
if (-not (Test-Path -LiteralPath $configPath)) { throw "未找到 $configPath" }
$timestamp = Get-Date -Format "yyyyMMdd-HHmmssfff"
$backupPath = "$configPath.before-sandbox-approval.$timestamp.bak"
if (Test-Path -LiteralPath $backupPath) { throw "备份已存在,停止覆盖:$backupPath" }
Copy-Item -LiteralPath $configPath -Destination $backupPath -ErrorAction Stop
Write-Output "backup_path=$backupPath"预期结果是原文件旁出现带时间戳的 .bak 文件,并打印本次实际 $backupPath。保存这条完整路径,回退时只使用它。命令报“未找到”时,先检查配置层、CODEX_HOME、Windows 与 WSL 是否混用;路径冲突或 Copy-Item 报错都表示备份没有完成,不应继续编辑。这个步骤只能证明备份文件已创建,不能证明其内容以后一定能被当前 CLI 加载。
Bash 或 Zsh 备份
在实际运行 Codex 的 Bash 或 Zsh 中执行:
codex_home="${CODEX_HOME:-$HOME/.codex}"
config_path="$codex_home/config.toml"
[ -f "$config_path" ] || { printf '未找到 %s\n' "$config_path" >&2; exit 1; }
timestamp="$(date '+%Y%m%d-%H%M%S')-$$"
backup_path="$config_path.before-sandbox-approval.$timestamp.bak"
[ ! -e "$backup_path" ] || { printf '备份已存在,停止覆盖:%s\n' "$backup_path" >&2; exit 1; }
cp "$config_path" "$backup_path" || exit 1
printf 'backup_path=%s\n' "$backup_path"预期结果和失败判断与 PowerShell 相同。恢复时先退出正在运行的 Codex,再把本次打印并保存的 $backupPath 或 $backup_path 精确复制回同一 $configPath 或 $config_path;新 Shell 中必须手动填入这两个实际路径,不要用通配符猜测备份。恢复后仍要重新做配置加载和实际权限验证。
场景一:日常开发保留 workspace-write + on-request
把下面两个顶层字段合并到现有 config.toml:
approval_policy = "on-request" sandbox_mode = "workspace-write"
这组基线适合需要修改当前仓库、运行本地构建或测试,同时希望越界操作有机会停下来确认的交互任务。它不是“允许所有写入”:工作区之外的目录和命令网络仍受各自边界约束。
选择权限时先问四个问题:
- 任务只需要读取,还是确实要修改文件?
- 输出是否必须写到工作区之外?
- Shell 子进程是否必须访问包仓库或外部服务?
- 当前流程是否有人可以处理批准请求?
只有答案发生变化时,才在基线上增加相应权限。
场景二:只读审查改为 read-only
阅读代码、比较配置或做不落盘的安全审查时,把现有顶层字段改为:
approval_policy = "on-request" sandbox_mode = "read-only"
如果还希望大部分非只读命令在执行前都由人确认,可以把审批改为 untrusted:
approval_policy = "untrusted" sandbox_mode = "read-only"
这两个片段仍然只是合并修改,不应覆盖整份配置。read-only 能减少误写范围,但不能证明读取的内容可信,也不能替代对命令参数、符号链接和敏感信息的人工检查。
临时任务不想修改长期配置时,可在 PowerShell、CMD、Bash 或 Zsh 中运行:
codex --sandbox read-only --ask-for-approval on-request
预期结果是本次会话按命令行覆盖值启动;若出现“不认识参数”或枚举错误,应先运行 codex --version 和 codex --help 核对版本。命令成功启动只证明 CLI 接受了本次选项,不能证明每一次写入尝试都已按预期被阻止。
场景三:只增加确实需要的 writable roots
构建产物、共享文档或缓存必须写到工作区之外时,不必直接切换到 danger-full-access。保持基线,并在现有 [sandbox_workspace_write] 表中增加本文推荐的显式绝对路径数组。
Windows 示例:将下面字段合并到现有配置,并把示例路径替换为真实绝对路径。TOML 单引号会按字面保留反斜杠。
approval_policy = "on-request" sandbox_mode = "workspace-write" [sandbox_workspace_write] writable_roots = ['D:\codex-shared-output'] network_access = false
Linux 或 macOS 示例同样只用于合并:
approval_policy = "on-request" sandbox_mode = "workspace-write" [sandbox_workspace_write] writable_roots = ["/srv/codex-shared-output"] network_access = false
固定 Schema 将 writable_roots 定义为路径字符串数组,默认值为空数组。Codex CLI 0.145.0 源码会把相对路径按声明该配置层的 config.toml 所在目录解析;为避免误判基准目录,本文示例仍推荐显式填写绝对路径。不要为了省事把用户主目录、磁盘根目录或包含大量无关项目的上级目录加入数组。CLI 的 --add-dir <DIR> 也可以为单次会话增加一个可写目录,适合临时任务:
codex --sandbox workspace-write --ask-for-approval on-request --add-dir D:\codex-shared-output
这条命令可在 Windows PowerShell 或 CMD 中使用,路径应替换为真实目录;Bash/Zsh 则使用对应的 Unix 绝对路径。预期结果是会话启动并把该目录作为工作区之外的附加可写目录。启动失败说明参数、路径或版本需要检查;启动成功仍只是选项接受证据,实际写入要用无敏感内容的探针文件单独验证。
可写根目录内仍有受保护路径
官方安全文档说明:即使目录位于 writable root 下,以下路径仍递归只读:
.git,无论它是目录还是文件指针;文件指针解析后指向的 Git 目录也受保护;.agents,在它作为目录存在时;.codex,在它作为目录存在时。
因此,把整个项目加入 writable_roots 不会自动让这些控制目录变成普通可写目录。反过来,也不要把“受保护路径存在”理解为整个 writable root 都没有风险:该根目录中的普通源码、产物和数据仍可能被修改。
固定 Schema 还包含 exclude_tmpdir_env_var 和 exclude_slash_tmp 两个布尔字段,0.145.0 中默认值均为 false。本文没有足够的当前运行证据展开它们在各操作系统上的具体临时目录行为,因此示例保持省略,不根据字段名称推断效果。
场景四:只有命令确实需要联网时才开启 network_access
workspace-write 下的 Shell 命令网络默认关闭。任务确实需要下载依赖、访问包仓库或调用外部测试服务时,编辑已经存在的 [sandbox_workspace_write] 表,把 network_access 改为 true:
approval_policy = "on-request" sandbox_mode = "workspace-write" [sandbox_workspace_write] writable_roots = ["/srv/codex-shared-output"] network_access = true
这是合并到现有配置的场景片段。Windows 用户应保留自己的 Windows 绝对路径数组;如果不需要额外目录,可以让 writable_roots = [],或者在没有其他子项需要保留时省略该字段,但不要重复创建第二个 [sandbox_workspace_write] 表。
命令网络会扩大两个风险面:一是外部网页、包内容和响应都可能成为不可信输入;二是本地文件、环境信息或命令输出可能被发往外部。开启前应缩小可写目录,避免在命令中回显凭据,并把目标域名和下载内容纳入审查。任务结束后,如果后续命令不再需要联网,应恢复为 false。
不同任务怎样选择组合
| 任务 | 沙箱 | 审批 | 额外设置 | 选择理由 |
|---|---|---|---|---|
| 只读分析、审查 | read-only | on-request 或 untrusted | 无 | 先限制写入,再决定审批频率 |
| 日常本地开发 | workspace-write | on-request | 命令网络默认关闭 | 保留工作区写入与越界确认 |
| 输出到工作区外的指定目录 | workspace-write | on-request | 只添加必要的 writable_roots | 比全盘放权更容易说明影响范围 |
| 下载依赖、访问包仓库 | workspace-write | on-request | network_access = true,完成后关闭 | 只为确有网络需求的命令开放 |
| 无人值守但必须保持文件边界 | read-only 或 workspace-write | never | 使用隔离环境并预期越界直接失败 | 不弹审批,但沙箱仍保留 |
| 无沙箱且不审批 | danger-full-access | never | 仅作为高风险边界说明 | 同时失去技术限制和人工停顿,不是本文推荐方案 |
never 适合的是“失败也不要等待人工处理”的明确流程,而不是“尽量让任务成功”。如果无人值守任务必须越过沙箱,应先用容器、虚拟机或同等级外部隔离重新设计运行边界,而不是默认改成 danger-full-access。
如何验证配置层和真实权限层
验证应分层进行,避免把“配置能加载”写成“权限已经按预期执行”。
第一步:确认 CLI 版本和可选值
下面是跨平台 Codex CLI 命令,可在 PowerShell、CMD、Bash 和 Zsh 中运行:
codex --version codex --help
本文环境的版本输出为 codex-cli 0.145.0,帮助中列出了 read-only、workspace-write、danger-full-access,以及 untrusted、on-request、never。若命令不存在、版本不同或帮助中的枚举不一致,应停止照抄本文值,改按当前版本官方文档核对。这个步骤只能证明当前二进制版本和 CLI 公开选项。
第二步:检查配置能否被当前 CLI 严格加载
备份并合并配置后,在同一 CODEX_HOME 环境运行:
codex --strict-config
预期结果是没有 TOML 解析或 unknown field 错误,并进入正常启动流程;可以按 Ctrl+C 结束。出现重复键、重复表、路径类型或未知字段错误,就说明配置层仍未通过。
这一步只证明当前客户端严格加载了配置。它不能证明 writable root 实际可写、受保护路径实际被拒绝、审批一定出现,或者 Shell 命令已经能联网。
本文 6 段 TOML 可以通过仓库检查复核其解析结果。专题验证记录记载六段配置曾完成严格加载,但本文未保存可独立复核的运行命令、退出码或脱敏输出,因此不把这项历史记录当作当前可重放证据;即使严格加载成功,也不能升级为真实权限执行证据。
第三步:在隔离测试目录做真实权限探针
真实权限验证应使用不含源码、凭据和个人数据的专用实验目录。范围外探针不能放进 /status 报告的任何 Writable Root,也不能被其中某个父目录覆盖。Codex CLI 0.145.0 在 Unix 下还可能默认列出 /tmp 与有效 $TMPDIR,因此不要在这些临时根内创建“范围外”目录;Windows 和其他平台不按临时目录 API 或路径名称推断,只依据本次 TUI 的 /status。若状态显示目标已被任一有效根覆盖,应退出并重新选择实验目录。
网络对照必须固定审批策略,两轮都使用 --ask-for-approval never,避免 on-request 下批准升级后改变结果。分别启动关闭和开启命令网络的会话:
codex -c 'sandbox_workspace_write.network_access=false' --ask-for-approval never --sandbox workspace-write codex -c 'sandbox_workspace_write.network_access=true' --ask-for-approval never --sandbox workspace-write
这两条命令用于 PowerShell、Bash 或 Zsh;进入每轮 TUI 后先输入 /status 核对实际配置,再要求 Codex 使用 Shell 执行同一个已安装的网络客户端、访问同一个公开测试地址,并记录工具调用、退出码与标准错误。never 模式不应出现审批;若出现,或两轮使用了不同命令、目标或环境,本次对照无效。若坚持使用 on-request,则必须拒绝所有权限升级并保存审批界面与选择结果,不能把批准后的成功归因于原配置。
确认边界后分别尝试:
- 在主工作区创建一个无敏感内容的探针文件;
- 在配置的额外 writable root 创建另一个探针文件;
- 在两者之外尝试创建文件;
- 在上述固定为
never的两轮会话中,分别使用同一网络客户端访问同一个公开测试地址; - 检查真实文件、命令退出码和批准界面,不采信模型仅用文字声称“成功”或“被拦截”。
预期边界是:前两处写入可完成,范围外写入需要批准或失败;命令网络只在打开相应设置且本机 DNS、代理、防火墙和目标服务都正常时可能成功。范围外写入意外成功,或网络关闭时命令仍成功,都应视为失败并停止扩大权限。
网络访问失败本身不能单独证明沙箱阻断,因为 DNS、代理、客户端缺失和目标站点故障也会产生失败。反过来,访问一个测试地址成功只证明该命令在这一次运行中能到达该地址,不代表任意域名、协议或后续会话都可用。
本文没有在读者的操作系统、代理和目录布局中执行这些真实探针,因此这些运行结果必须由读者在自己的隔离环境中核验。
完成后的检查清单
- 已备份实际生效的
config.toml,并确认备份路径。 - 所有片段都是合并修改,没有整文件覆盖原配置。
- 任务只读时优先选择
read-only。 writable_roots只包含必要的绝对路径,没有放大到用户目录或磁盘根目录。- 没有把
.git、.agents、.codex的保护误解成整个根目录只读。 - 只有 Shell 命令确实需要联网时才设置
network_access = true。 - 已区分命令网络与 Web Search 工具。
- 已把严格配置加载与真实权限执行分开验证。
- 高风险的
danger-full-access + never没有被当作日常默认。
总结
从 workspace-write + on-request 扩展权限时,最稳妥的顺序是:先判断是否只读,再只增加必要的 writable roots,最后才为确有需要的 Shell 命令开启网络。审批策略决定是否停下来问人,沙箱模式决定技术边界,两者不能互相替代。
这样配置的目标不是让所有命令都成功,而是让每项权限都能对应一个真实任务需求,并且可以通过文件、退出码和批准界面复核。
FAQ
approval_policy = “never” 是否等于完全放开权限?
不等于。never 只是不请求批准,沙箱仍由 sandbox_mode 决定。与 workspace-write 搭配时,越界失败会直接返回给模型;只有再配合 danger-full-access 才同时失去沙箱限制和批准停顿。
writable_roots 应该写相对路径还是绝对路径?
Codex CLI 0.145.0 会把相对路径按声明该配置层的 config.toml 所在目录解析,固定 Schema 本身只把数组元素约束为路径字符串。为了让配置审查和迁移时更容易确认真实边界,本文推荐填写当前运行环境中范围尽可能小的绝对目录。
把项目加入 writable_roots 后,.git 也能写吗?
不能据此推断 .git 可写。官方安全文档说明 writable root 下的 .git 仍递归只读,包括文件指针解析后指向的 Git 目录;.agents 与 .codex 在作为目录存在时也递归只读。
network_access = true 是否也会开启 Web Search?
不会。它控制沙箱内 Shell 命令的网络访问;Web Search 是独立工具边界。验证时应分别观察 Shell 命令退出码和 Web Search 工具活动。
codex --strict-config 通过,是否说明沙箱已经生效?
不能。严格加载只证明 TOML 被当前 CLI 接受。真实文件写入、越界拒绝、批准请求和命令联网仍要在隔离目录中逐项执行并观察。
以上就是Codex CLI 0.145.0配置沙箱模式和审批策略的详细内容,更多关于Codex CLI沙箱与审批配置的资料请关注脚本之家其它相关文章!
