# Codex 沙箱与 config.toml：权限、批准和网络怎么配

> 分清 Codex 沙箱、approval 与配置层级，用最小权限设置文件和网络边界，并按 macOS、Windows、WSL2、Linux 的真实限制排错。

- Source: https://www.aifreeapi.com/zh/posts/codex-config-toml
- Language: zh
- Published: 2026-08-15
- Updated: 2026-08-16
- Publisher: AI Free API (https://www.aifreeapi.com)

Codex 的沙箱不是一个单独的虚拟机开关，而是本地命令的执行边界：它限制命令能写哪些文件、能否访问网络。`approval_policy` 是另一套控制，决定 Codex 何时停下来请求你跨越边界。两者配合工作，但改其中一个不会自动改变另一个。OpenAI 的 [Sandbox 文档](https://learn.chatgpt.com/docs/sandboxing) 还明确说明，Codex 启动的 `git`、包管理器、测试 runner 等子命令也继承相同边界。

日常开发通常从 `workspace-write` 加 `on-request` 开始：Codex 可在工作区内读写并运行常规命令，超出边界时再询问。`read-only` 适合只检查不改文件；`danger-full-access` 会移除文件系统与网络沙箱，只适合你明确接受完整主机权限，或已经在可信的外层容器里完成隔离时使用。把 `approval_policy` 设成 `never` 只表示不弹 approval；它本身不等于 full access。

配置时最容易出问题的动作，是为了修一个权限错误，把别人的整份 `config.toml` 覆盖到自己机器上。这样一次改动可能同时换掉模型、provider、沙箱、批准策略、联网方式和 MCP；结果从一个可定位的边界问题，变成多层组合故障。

更稳妥的顺序是：先判断阻塞来自文件、网络、approval、配置覆盖还是操作系统；再确定这项设置属于个人、项目、profile 还是一次性命令；最后只改一个相关块并验证结果。个人默认配置通常在 `~/.codex/config.toml`，受信任仓库可以使用项目内的 `.codex/config.toml`。具体位置与行为见 OpenAI 的 [Config basics](https://learn.chatgpt.com/docs/config-file/config-basic)。

修改前只备份目标文件，不要为了恢复一个错误表就删除整个 `~/.codex`。那个目录还可能保存认证、profiles、规则和其他仍然正常的状态。

## 先判断设置到底归谁

普通配置从高到低按以下顺序解析：

1. CLI 参数和 `--config` 临时覆盖；
2. 受信任项目中的 `.codex/config.toml`，离当前目录更近的层优先；
3. `--profile` 选中的独立 profile 文件；
4. 用户级 `~/.codex/config.toml`；
5. Unix 上可能存在的 `/etc/codex/config.toml`；
6. Codex 内置默认值。

这是官方 [配置优先级](https://learn.chatgpt.com/docs/config-file/config-basic#configuration-precedence) 的当前顺序。于是，“我明明改了用户配置，为什么没变化”通常不是文件没保存，而是上方仍有 CLI、项目或 profile 值在覆盖。

![Codex 配置从 CLI、项目、profile、用户、系统到默认值的优先级关系](https://www.aifreeapi.com/posts/zh/codex-config-toml/img/precedence-map.webp)

可以先用下面的归属规则缩小范围：

| 你想改变的行为 | 建议放置位置 | 不应混入的内容 |
|---|---|---|
| 个人常用模型、推理强度、通知、个人 MCP | 用户级配置 | 仓库团队规则 |
| 某个仓库的执行边界和协作约定 | 受信任项目配置 | 个人 provider 与认证 |
| “只读检查”“深度审查”等可重复模式 | 独立 profile 文件 | 重复整份用户配置 |
| 临时试一个模型或开关 | CLI 参数、`-c key=value` | 长期默认值 |
| 公司不可绕过的限制 | 管理员 requirements | 依赖用户自觉的普通配置 |

项目配置还有一条硬边界：它不能覆盖机器本地的 provider、认证、profile 选择、通知和遥测类别，当前明确包括 `model_provider`、`model_providers`、`profile`、`otel` 等。完整名单应以最新 [Configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference#configtoml) 为准。把这些键从项目文件搬到用户级，比反复调优先级更有效。

## 沙箱模式和 approval 要分开选

一份能工作的低风险起点可以只有几行：

```toml
approval_policy = "on-request"
sandbox_mode = "workspace-write"
```

这两个值表达不同问题：

| 控制 | 它回答的问题 | 常见误判 |
|---|---|---|
| `sandbox_mode` | 命令在技术上可以读写哪里、能否联网 | 以为点一次批准就永久扩大可写范围 |
| `approval_policy` | 遇到边界或不受信任命令时是否停下询问 | 以为 `never` 自动解除沙箱 |
| `approvals_reviewer` | 由用户还是可用的 auto-review 处理 eligible approval | 以为自动 review 会修改 sandbox 边界 |

官方当前列出的三个常见沙箱模式是：

- `read-only`：可以检查文件，但编辑或执行受限动作需要批准；
- `workspace-write`：可以在工作区内读写并运行常规本地命令；
- `danger-full-access`：没有沙箱文件与网络边界。

批准策略常见为 `untrusted`、`on-request` 和 `never`。交互式工作中，`on-request` 允许 Codex 在既定边界内持续推进，需要越界时再停下。完整定义与当前 UI 入口应以 [Sandbox：How permissions work](https://learn.chatgpt.com/docs/sandboxing#how-permissions-work) 为准：CLI 可输入 `/permissions`，IDE 和桌面端可使用输入框下方的权限控件；具体选项会受版本和组织配置影响。

如果目标只是让 Codex 写另一个明确目录，不必直接改成 full access。当前 config reference 支持为 `workspace-write` 增加额外可写根：

```toml
sandbox_mode = "workspace-write"
approval_policy = "on-request"

[sandbox_workspace_write]
writable_roots = ["/absolute/path/to/second-repo"]
network_access = false
```

额外目录应使用清楚、具体的绝对路径。不要把 home 目录或磁盘根当作“省事的 writable root”。另外，`sandbox_workspace_write.network_access` 控制的是沙箱内子进程的外向网络；它与 Codex 的 web search、apps、MCP 或 remote browser 不是同一控制面。某个网页工具可用，不能证明 `npm install` 或测试进程也能联网。

## 同样的 config，在不同系统上可能有不同失败点

沙箱目标一致，但实现依赖操作系统。根据 OpenAI 当前的 [Getting started](https://learn.chatgpt.com/docs/sandboxing#getting-started)：

| 环境 | 当前执行基础 | 常见的最早失败点 |
|---|---|---|
| macOS | 系统内置 Seatbelt | 目标路径不在允许范围，或命令需要越界 |
| native Windows | Codex 的 Windows sandbox | native sandbox setup、管理员/设备策略、兼容性 |
| WSL2 | Linux sandbox 实现 | `bubblewrap`、WSL 环境或 user namespace |
| Linux | `bubblewrap` 加系统隔离机制 | `bwrap` 未安装、AppArmor 或 user namespace 被限制 |

Ubuntu/Debian 可先安装发行版提供的 `bubblewrap`：

```bash
sudo apt install bubblewrap
```

Fedora 使用：

```bash
sudo dnf install bubblewrap
```

若安装后仍出现 user namespace 或 AppArmor 警告，先按官方文档核对对应发行版步骤。不要把关闭系统级限制作为第一选择。运行在 Docker 里的 Codex 还多了一层：容器可能阻止 `bwrap` 所需的 namespace 或 seccomp 操作。此时应先确认外层容器已经提供你需要的隔离，再决定是否在容器内部使用更宽的 Codex 模式；这不等于直接在宿主机上使用 full access。

## Profile 现在是独立文件

如果你经常在日常开发和只读审查之间切换，不要在主文件里维护两套重复表。可以创建：

```toml
# ~/.codex/read-only-review.config.toml
model_reasoning_effort = "xhigh"
approval_policy = "on-request"
sandbox_mode = "read-only"
```

运行时选择：

```bash
codex --profile read-only-review
```

profile 只写与基础用户配置不同的值。项目层和 CLI 参数仍然可以在它之上覆盖。profile 的存放形式可能随客户端版本变化；升级后应先核对当前 [Advanced Config：Profiles](https://learn.chatgpt.com/docs/config-file/config-advanced#profiles)，不要沿用旧示例猜测。

## MCP 配置正确，不等于 MCP 已经可用

本地 STDIO server 至少有三层事实：TOML 表存在、命令能启动、工具能工作。可以把启动信息写清楚：

```toml
[mcp_servers.docs]
command = "docs-server"
args = ["--mode", "read-only"]
env_vars = ["DOCS_TOKEN"]
startup_timeout_sec = 20
tool_timeout_sec = 60
enabled = true
```

远程 streamable HTTP server 则以 URL 为主，并通过环境变量名引用 token：

```toml
[mcp_servers.issues]
url = "https://mcp.example.internal/mcp"
bearer_token_env_var = "ISSUES_MCP_TOKEN"
enabled = true
```

不要把真实 token 直接写进文章、项目文件或求助截图。OpenAI 的 [MCP 文档](https://learn.chatgpt.com/docs/extend/mcp) 说明了 STDIO、streamable HTTP、OAuth、环境变量 header、tool allow/deny、timeout 和 `required`。

当前 CLI 通常可以先列出已解析的 server：

```bash
codex mcp list
codex mcp --help
```

支持 OAuth 的 server 还可使用 `codex mcp login <server-name>`。出现在列表里，只能证明定义被读取；它不能证明可执行文件存在、URL 可达、认证成功或某个 tool 的输入输出正确。

## 把“没生效”拆成七个检查点

不要从头重写文件。沿着最早未证明的一层继续：

1. **文件**：编辑的是本机实际读取的用户、项目或 profile 文件吗？
2. **TOML**：当前客户端认识这些键吗？表的嵌套位置正确吗？
3. **优先级**：CLI、受信任项目或 profile 是否覆盖了用户值？
4. **沙箱**：目标路径是否属于 workspace 或额外 writable root？
5. **批准与网络**：approval policy 是否允许越界请求，子进程是否真的有 outbound network？
6. **系统**：native Windows、WSL2、`bubblewrap`、AppArmor 或外层容器是否满足前提？
7. **provider / MCP**：认证、endpoint、server 进程和 tool 调用是否分别成立？

近期 Codex CLI 提供 `--strict-config` 和 `doctor`，但命令是否存在取决于安装版本。先看：

```bash
codex --version
codex --help
codex doctor --help
```

若本机帮助包含相应选项，可做一次只读检查：

```bash
codex --strict-config doctor --summary
```

`--strict-config` 用于让未知字段直接报错，`doctor` 用于检查安装、配置、认证和运行环境。旧版本若没有这些入口，应使用它自己的 `--help` 和同版本参考，而不是继续粘贴新版本键。

![从文件、TOML、覆盖、权限、provider 到 MCP 的 Codex 排错路径](https://www.aifreeapi.com/posts/zh/codex-config-toml/img/troubleshooting-path.webp)

## 按症状回到最早失败的一层

| 表现 | 优先检查 | 暂时不要做 |
|---|---|---|
| 只在一个仓库里设置无效 | 项目信任、就近 `.codex/config.toml` | 删除用户配置 |
| CLI 正常，IDE 报缺少 key | IDE 进程能否看到环境变量 | 把 token 写死进 TOML |
| unknown field 或启动解析失败 | 当前版本 reference、strict config | 同时升级并重写全文件 |
| 只能读不能写 | 当前 sandbox mode、workspace root、protected path | 直接切到 `danger-full-access` |
| `npm install`、测试下载或 API 调用失败 | subprocess network、proxy、DNS 与 approval | 因 web search 可用就认定网络正常 |
| Windows 显示 sandbox setup 失败 | native/WSL2 路线、设备策略与当前官方 Windows 指引 | 把 Windows Sandbox、VM 与 Codex native sandbox 混为一谈 |
| 改了 model 却仍走旧路线 | `model_provider`、profile、CLI 覆盖 | 只反复改 model 字符串 |
| MCP 已列出但调用不到 | command/URL、认证、timeout、tool | 认为列表等于健康检查 |
| 工作电脑不允许高权限组合 | 企业 `requirements.toml` | 把禁止值换个本地层再写 |

在受管理的 Business 或 Enterprise 环境里，`requirements.toml` 可以限制 approval、permission profile、web search、MCP allowlist、plugin 和 feature。用户值与强制规则冲突时，客户端可以回退到允许值并提示。这个边界见 [Admin-enforced requirements](https://learn.chatgpt.com/docs/enterprise/managed-configuration#admin-enforced-requirements-requirementstoml)。这不是优先级技巧能绕过的问题。

最后把每次修改限制为一个可观察目标：先读、再在 workspace 内写一个临时文件、运行项目自带测试，最后才验证确实需要的网络或额外目录。失败就回到最早未证明的边界。这样做能明确区分“配置没被读取”“沙箱正确拒绝”“approval 没有机会出现”和“操作系统无法建立 sandbox”，也避免把安全边界本身误诊成 Codex 故障。

如果真正的问题是“该不该用 Codex”，而不是如何配置它，可以转到 [Claude Code 与 Codex 的工作流比较](/zh/posts/claude-code-vs-codex)。配置文件无法替你完成产品选择。
