OpenAI Codex 中文教程

权限

用权限配置档案为 Codex 本地命令设置可复用的文件系统和网络边界。

权限配置档案让你对 Codex 代你运行的本地命令应用最小权限边界。一个 profile 是一条具名策略,由文件系统规则和网络规则组合而成:文件系统规则定义命令可以读取或写入什么,网络规则定义命令可以访问哪些目的地。

使用 profile 可以只给 Codex 当前任务所需的访问权限,而不是广泛开放你的机器或网络。例如,只读 profile 可以让 Codex 检查项目但不能编辑;可写 profile 可以把编辑范围限制在选定 workspace roots 内。

本地权限配置档案支持 macOS、Linux、WSL 和原生 Windows。平台特定的执行细节与限制见安全限制

Codex 云端网络设置请参见网络访问

定义并选择 profile

Codex 内建三个权限配置档案:

  • :read-only 让本地命令执行保持只读。
  • :workspace 允许写入当前活动 workspace roots。
  • :danger-full-access 移除本地沙箱限制,只应在你确实需要这种宽访问时使用。

[permissions.<name>] 下创建具名 profile,然后把顶层 default_permissions 设置为该 profile 名称,或设置为上述内建名称之一。下面示例中的 project-edit 是用户自定义 profile 名,不是内建值。

自定义 profile 使用两个相关概念:

  • [permissions.<name>.workspace_roots] 添加应纳入该 profile workspace roots 的具体目录。
  • [permissions.<name>.filesystem.":workspace_roots"] 定义 Codex 应用于每个有效 workspace root 的文件系统规则:包括当前 session 的运行时 workspace roots,以及上面由 profile 定义的 roots。

Profile 也遵循普通配置层模型。更高优先级的配置层可以在不重写整个 profile 的前提下,为同一个 profile 名追加或替换条目。

例如,组织级配置和用户级配置可以分别扩展同一个 profile:

# /etc/codex/config.toml
[permissions.server.workspace_roots]
"~/code/server" = true
# ~/.codex/config.toml
[permissions.server.workspace_roots]
"~/code/mobile-app" = true

server 启用时,这两个 workspace root 都会参与有效 profile。

default_permissions = "project-edit"

[permissions.project-edit.workspace_roots]
"~/code/app" = true
"~/code/shared-lib" = true

[permissions.project-edit.filesystem]
":minimal" = "read"

[permissions.project-edit.filesystem.":workspace_roots"]
"." = "write"
".devcontainer" = "read"
"**/*.env" = "deny"

[permissions.project-edit.network]
enabled = true

[permissions.project-edit.network.domains]
"api.openai.com" = "allow"
"objects.githubusercontent.com" = "allow"
"*.github.com" = "allow"
"tracking.example.com" = "deny"

这个 profile 会:

  • 读取常用开发工具所需的最小运行时路径。
  • 对当前 session 和 profile 自定义的 workspace roots 应用同一组 workspace-root 规则。
  • .devcontainer/ 等 IDE 相邻设置在每个 root 下保持只读。
  • 通过 glob 规则拒绝匹配到的环境文件。
  • 只允许访问配置的域名策略。

在活动 profile 中,即使较宽的路径可读或可写,更窄的 deny 规则仍然生效。例如,一个 profile 可以让 workspace roots 可写,同时仍然把匹配到的 .env 路径设为 deny

配置规格

条目 类型 / 值 默认值 说明
default_permissions String profile name None Codex 默认应用的权限配置档案名称。值必须匹配 [permissions] 下的 profile,或 :workspace 等内建 profile。启用权限配置档案时必填。若旧版 sandbox 设置生效,Codex 会改用旧版 sandbox 设置。
[permissions.<name>] Table None 定义一个 profile 及其标识符。default_permissions 选择默认 profile;其他权限 profile 选择器也使用 profile 名。
[permissions.<name>.workspace_roots] Table None 添加由 profile 定义的 workspace roots,它们会和当前 session 的运行时 workspace roots 一起接收 :workspace_roots 文件系统规则。
permissions.<name>.workspace_roots."<path>" Boolean false true 时,把该路径加入 profile 的 workspace root 集合。值为 false 的条目保持不生效。
[permissions.<name>.filesystem] Table None 把文件系统路径映射到访问值,或映射到带 scope 的子路径表。缺失或为空的 filesystem 表会让文件系统访问保持受限,并在启动时发出警告。
permissions.<name>.filesystem.glob_scan_max_depth Number None 在 Linux、WSL 和原生 Windows 上,限制 deny-read glob 在 sandbox 启动前快照匹配结果时的展开深度。较大值可能增加启动扫描开销。当无界 ** pattern 需要有界预展开时,至少设为 1
[permissions.<name>.filesystem]."<path>" read, write, or deny None 为受支持路径授予直接访问权限。deny 拒绝访问,并优先于同等具体度的 writeread。如果当前运行时不能执行直接写规则,Codex 会拒绝该配置。
[permissions.<name>.filesystem."<path>"]."<subpath>" read, write, or deny None <path> 的后代路径授权。用 . 表示基础路径。其他子路径必须是相对后代,不能包含 ... 组件。
[permissions.<name>.network] Table None 为该 profile 配置网络沙箱代理和沙箱网络策略。
permissions.<name>.network.enabled Boolean false 为该 profile 中的 sandboxed commands 启用网络访问。这会改变 sandbox 网络策略,但不会自行启动网络代理。
[permissions.<name>.network.domains] Table None 把主机 pattern 映射到 allowdeny。如果没有任何 allow 条目,域名请求会被阻止。deny 条目优先于 allow
permissions.<name>.network.domains."<pattern>" allow or deny None 支持精确主机、仅匹配子域的 *.example.com、匹配 apex 加子域的 **.example.com,以及只能用于 allow 的全局通配符 *。主机 pattern 会被 trim、小写、移除尾部点,并剥离简单端口或括号。
[permissions.<name>.network.unix_sockets] Table None 映射 Unix socket allowlist 覆盖项。仅用于 Docker 等本地集成。
permissions.<name>.network.unix_sockets."<path>" allow or none None allow 把某个绝对 Unix socket 路径加入有效 allowlist,或用 none 清除继承来的 allow 条目。none 不是独立的 deny-list 决策。
permissions.<name>.network.proxy_url URL string http://127.0.0.1:3128 HTTP proxy listener,用于 HTTP_PROXYHTTPS_PROXY、websocket proxy 变量和相关工具代理环境变量。
permissions.<name>.network.enable_socks5 Boolean true 启用 SOCKS5 listener,用于 ALL_PROXY 和 FTP proxy 变量。
permissions.<name>.network.socks_url URL string http://127.0.0.1:8081 SOCKS5 listener 地址。
permissions.<name>.network.enable_socks5_udp Boolean true 启用 SOCKS5 listener 时,是否启用 SOCKS5 UDP 支持。
permissions.<name>.network.allow_upstream_proxy Boolean true 允许网络沙箱代理遵循上游 HTTP(S)_PROXYALL_PROXY 设置。
permissions.<name>.network.allow_local_binding Boolean false true 时关闭本地 / 私有网络保护。为 false 时,localhost127.0.0.1 等精确本地字面量必须显式 allowlist,解析到本地或私有 IP 的主机名仍会被阻止。
permissions.<name>.network.dangerously_allow_non_loopback_proxy Boolean false 允许代理 listener 绑定非 loopback 地址。普通本地开发请保持未设置。
permissions.<name>.network.dangerously_allow_all_unix_sockets Boolean false 在支持 Unix socket proxying 的地方绕过 Unix socket allowlist。这是一个很宽的本地逃生口。

文件系统权限

文件系统条目使用 readwritedeny

访问 含义
read 允许命令读取该路径下的文件并列出目录。命令不能在其中创建、修改、重命名或删除文件。
write 允许命令读取并修改该路径下的内容,包括在操作系统允许时创建、重命名和删除文件。
deny 拒绝读取和写入该路径。可用它从较宽的 readwrite 授权中挖出一个拒绝子路径。

更具体的条目会覆盖更宽的条目。当两个条目指向同一路径时,deny 优先于 writewrite 优先于 read

这让 profile 可以先描述一个较宽的工作区域,再挖出必须保持不可读的文件或目录:

[permissions.project-edit.filesystem]
":minimal" = "read"

[permissions.project-edit.filesystem.":workspace_roots"]
"." = "write"
".devcontainer" = "read"
"**/*.env" = "deny"

在这个例子中,workspace root 保持可写,.devcontainer/ 保持可读但不可写,匹配的环境文件仍然不可用。

更具体的路径也可以在较宽的 deny 中重新打开一个更窄的子树:

[permissions.project-edit.filesystem]
"~/Documents" = "deny"
"~/Documents/codex" = "write"

支持的路径形式:

路径 含义 Scoped subpaths
:root 文件系统根目录 .
:minimal 常用工具所需的平台和运行时路径 .
:workspace_roots 当前 session 的 workspace roots 加上已启用的 profile-defined workspace roots Yes
:tmpdir 可用时的 $TMPDIR 位置 .
/absolute/path 平台绝对路径,例如 macOS/Linux/WSL 上的 /path 或原生 Windows 上的 C:\path Yes
~/path 当前用户 home 目录下的路径 Yes

在原生 Windows 上,home 相对路径也可以使用反斜杠,例如 ~\work

只有当 profile 明确需要宽读访问时,才使用 :root

[permissions.audit.filesystem]
":root" = "read"

使用 :workspace_roots 下的嵌套条目,可以把访问权限限定到 workspace-root 相对子路径:

[permissions.project-edit.filesystem.":workspace_roots"]
"." = "write"          # each workspace root
"docs" = "read"        # each workspace-root docs directory
"generated" = "deny"   # each workspace-root generated directory

嵌套子路径必须留在对应 workspace root 内。../other-repo 这类父级跳转会被拒绝。

用精确路径或 glob 拒绝读取

即使附近有较宽的 profile 规则授予访问权限,也可以用 deny 标记 Codex 不应读取的文件或子树。精确路径适合 ~/.ssh 这类稳定位置;glob pattern 适合覆盖一类在不同仓库中位置会变化的敏感文件。

当 glob 位于 :workspace_roots 下时,Codex 会把它解释为相对于每个有效 workspace root。例如:

[permissions.project-edit.filesystem.":workspace_roots"]
"**/*.env" = "deny"

这条规则会拒绝读取每个运行时或 profile-defined workspace root 下匹配到的 .env 文件。适合你希望保留正常 workspace 写权限,同时让环境文件、生成密钥或类似凭据文件保持不可读的场景。

deny glob pattern 支持作为 deny-read 规则。readwrite glob 在 Linux、WSL 和原生 Windows 沙箱中可移植性较弱,因此应优先使用精确路径,或 "docs/**" = "read" 这类子树规则。

在 Linux、WSL 和原生 Windows 上,无界 ** deny-read pattern 可能需要在 sandbox 启动前有界预展开。使用 "**/*.env" = "deny" 这类无界 pattern 时,请设置 glob_scan_max_depth

[permissions.project-edit.filesystem]
glob_scan_max_depth = 3

[permissions.project-edit.filesystem.":workspace_roots"]
"**/*.env" = "deny"

glob_scan_max_depth 必须至少为 1。值越大,启动前扫描越深,可能增加 Linux、WSL 和原生 Windows 上的启动开销。如果不想使用有界展开,可以显式枚举深度,例如 *.env*/*.env*/*/*.env

当你希望同一组规则作用到当前 session root 以外的目录时,请把可复用 workspace roots 加到 profile:

[permissions.project-edit.workspace_roots]
"~/code/app" = true
"~/code/shared-lib" = true

该 profile 启用时,Codex 会把 :workspace_roots 规则应用到当前 session 的运行时 workspace roots,以及每个启用的 profile-defined workspace root。

在原生 Windows 上,D:\work 这类盘符路径和 \\server\share 这类 UNC 路径都支持作为绝对路径。

网络权限

为所选 profile 设置 enabled = true 即可允许网络访问:

[permissions.project-edit.network]
enabled = true

启用网络访问后,Codex 默认使用完整网络行为。大多数 profile 也应定义域名规则:

[permissions.project-edit.network.domains]
"example.com" = "allow"      # exact host
"*.example.com" = "allow"    # subdomains only
"**.example.com" = "allow"   # apex and subdomains
"ads.example.com" = "deny"   # deny wins over allow

网络沙箱代理默认绑定本地 listener:

[permissions.project-edit.network]
enabled = true
proxy_url = "http://127.0.0.1:3128"
enable_socks5 = true
socks_url = "http://127.0.0.1:8081"
enable_socks5_udp = true

除非你正在接入特定运行时,否则请保留这些 listener 默认设置。dangerously_* 网络键是面向特殊环境的逃生口,不应用于普通本地开发。

本地和私有网络

Codex 默认应用本地 / 私有网络保护,防御 DNS rebinding 和对本地服务的意外访问。若要刻意允许某个本地字面量目标,请把精确主机或 IP 字面量加入 allowlist:

[permissions.project-edit.network.domains]
"localhost" = "allow"
"127.0.0.1" = "allow"

只有当 profile 必须访问解析到本地或私有地址的 allowlisted 主机名时,才设置 allow_local_binding = true

[permissions.project-edit.network]
enabled = true
allow_local_binding = true

[permissions.project-edit.network.domains]
"localhost" = "allow"

Unix sockets

Unix socket proxying 是面向 Docker 等工具的本地逃生口,应谨慎使用:

[permissions.project-edit.network.unix_sockets]
"/var/run/docker.sock" = "allow"
"/tmp/old.sock" = "none"

使用 none 可以清除从低优先级配置层继承来的 socket allow 条目。它不是类似域名规则的 deny。

启用 Unix sockets 时,请让 proxy listeners 继续绑定到 loopback 地址。

从旧版沙箱设置迁移

当你希望用一个可复用 profile 同时描述文件系统和网络行为时,权限配置档案会替代旧版 sandbox_modesandbox_workspace_write 组合。一个 session 中请只使用其中一套系统。

建议起点:

  • 对只读工作流,使用内建 :read-only profile,或定义一个只在必要位置授予读取权限的自定义 profile。
  • 对 workspace 编辑,使用内建 :workspace profile,或定义一个通过 :workspace_roots 写入、并只添加任务所需临时目录或缓存路径的自定义 profile。
  • 对不受限本地执行,只有当你确实想要最宽本地访问模型时,才使用 :danger-full-access

Profile 描述的是一个 session 的本地默认姿态。组织托管 requirements 仍可添加不应被用户配置放宽的限制。关于管理员强制执行的文件系统和网络约束,请参见托管配置

范围与执行

权限配置档案定义的是本地 sandboxed command execution 的边界。请把它们和审批策略,以及其他 Codex 表面的独立控制一起使用。

Profile 控制什么

  • 本地命令执行: 权限配置档案管理在你机器上运行的 sandboxed commands。App connectors、MCP servers、浏览器或 computer-use 表面、Codex 云端环境设置,以及已批准的提权操作,都使用各自的控制。
  • 文件系统写入: 可写 profile 可以创建持久改动。对脚本、构建步骤、package manager hooks、shell 启动文件和共享目录的写入要视为敏感,因为后续工具或用户可能在原始 sandbox 上下文之外执行这些文件。
  • 出站目的地: 网络域名规则限制 sandboxed command 流量可以通过网络代理访问哪里。它们不判断允许的目的地是否可信,通配符 allow 规则仍然很宽。
  • 本地服务: 本地和私有网络目标默认被阻止。把 localhost、私有 IP、Unix sockets 加入 allowlist,或设置 allow_local_binding = true,都会显式打开本地服务访问。

安全限制

  • 在 macOS 上,Codex 使用 Seatbelt sandbox profiles。如果所选策略无法由平台 sandbox 执行,Codex 会拒绝运行命令,而不是静默地以无 sandbox 方式运行。
  • 在 Linux 和 WSL 上,Codex 使用 bubblewrapseccomp,并在兼容性 fallback 路径上使用 Landlock。最强执行路径取决于 user namespaces 和内核支持;受限容器主机可能强制走兼容路径,不支持的 split policies 会被拒绝。
  • 在原生 Windows 上,elevated sandboxing 最强,因为它可以使用专用低权限 sandbox 用户、文件系统权限边界和防火墙规则。unelevated sandboxing 是较弱的 fallback,网络隔离更弱,也不能执行每一种拆分读写 carveout,因此不支持的策略会被拒绝。需要 Linux sandbox 模型时,请使用 WSL。

操作建议

选择仍能完成任务的最窄 profile,尤其是在你授予写权限或出站网络访问时。请让审批策略、密钥处理和 allow 规则与该访问级别保持一致。

常见 profile

带网络 allowlist 的只读 profile

default_permissions = "readonly-net"

[permissions.readonly-net.filesystem]
":minimal" = "read"

[permissions.readonly-net.filesystem.":workspace_roots"]
"." = "read"

[permissions.readonly-net.network]
enabled = true

[permissions.readonly-net.network.domains]
"api.openai.com" = "allow"

无网络的 workspace 写入

default_permissions = "project-edit"

[permissions.project-edit.filesystem]
":minimal" = "read"

[permissions.project-edit.filesystem.":workspace_roots"]
"." = "write"

[permissions.project-edit.network]
enabled = false

带公共 Web 访问的 workspace 写入

default_permissions = "workspace-net"

[permissions.workspace-net.filesystem]
":minimal" = "read"

[permissions.workspace-net.filesystem.":workspace_roots"]
"." = "write"

[permissions.workspace-net.network]
enabled = true

[permissions.workspace-net.network.domains]
"*" = "allow"

只有当你确实打算允许公共网络访问时,才使用全局 "*" allow 规则。Deny 规则可以收窄较宽的 allowlist。