给 Codex 配置 API Key 和 Base URL 时,最容易犯的错误不是少写一个斜杠,而是把三条不同路线拼进同一份 config.toml:一边保留 ChatGPT 登录,一边把第三方 key 写进 auth.json,再在项目目录里声明一个不会生效的 provider。
先只回答两个问题:谁签发凭证,谁实际接收模型请求? 如果两者都是 OpenAI,你需要的是 OpenAI API-key 登录;如果请求仍属于内置 OpenAI provider,只是经过 OpenAI proxy 或数据驻留地址,使用 openai_base_url;如果模型、账户、账单或支持方属于另一个服务,则声明独立 custom provider。
本文按 2026 年 9 月 1 日的 OpenAI Codex 高级配置 与 认证说明 校对。配置 schema 会随 Codex 更新;复制前请再看当前官方页面。
先选路线,再碰配置文件
| 你的真实任务 | 正确入口 | 凭证从哪里来 | 主要限制 |
|---|---|---|---|
| 本地 Codex 使用 OpenAI Platform 计费 | OpenAI API-key 登录 | OpenAI Platform key | 不是 ChatGPT 订阅用量;Codex cloud 仍需要 ChatGPT 登录 |
| 内置 OpenAI provider 经过 proxy、router 或数据驻留 endpoint | openai_base_url | 仍按该 OpenAI 路线认证 | proxy 必须保留所需的 OpenAI API 合同 |
| 另一个服务提供模型、key、账单与支持 | [model_providers.<id>] | provider 指定的环境变量或 auth command | “OpenAI-compatible” 不自动证明 Codex 所需能力都可用 |
| 本机 endpoint 不需要认证 | custom provider,不写 env_key | 无 | 只适用于你能控制并确认无需认证的本地服务 |

如果你的问题其实是“ChatGPT Plus、Codex credits 和 OpenAI API key 哪个付费”,先看 Codex API Key 与订阅路线。账单 owner 没确定时,任何 Base URL 示例都可能把工作送到错误的账户。
OpenAI API Key 登录:不要把它当 custom provider
OpenAI 文档将 ChatGPT 登录和 API-key 登录列为本地 Codex 的两种认证方式。CLI 可以从标准输入读取 key,避免 key 出现在命令历史参数里:
bashprintenv OPENAI_API_KEY | codex login --with-api-key codex login status
这条路线的使用量归 OpenAI Platform 账户与 project,按 API 费率计费;它不会把任意 Platform 调用变成 ChatGPT 订阅内用量。OpenAI 也明确说明 Codex cloud 需要 ChatGPT 登录,因此 API key 不是所有 cloud 功能的等价替代。
登录缓存可能保存在 ~/.codex/auth.json,也可能进入操作系统 credential store,取决于 cli_auth_credentials_store。把 auth.json 当密码处理:不要提交到 Git,不要贴进工单,也不要发给别人排错。需要确认当前路线时看 codex login status,不要打开文件复制其内容。
只覆盖内置 OpenAI Base URL
如果请求仍属于内置 openai provider,只是必须经过一个保留 OpenAI API 合同的 proxy、router 或地区 endpoint,官方建议直接在用户配置中写 openai_base_url:
toml# ~/.codex/config.toml openai_base_url = "https://proxy.example.com/v1"
不要为了这件事创建 [model_providers.openai]。openai、ollama 和 lmstudio 是保留的内置 provider ID,自定义 provider 不能用同名配置覆盖它们。
openai_base_url 也不是“任何兼容网关都能用”的证明。它适合保留 OpenAI 认证与接口语义的路由。如果网关签发自己的 token、使用自己的账单、模型名或支持合同,应把它作为独立 provider,而不是让 OpenAI 登录状态和第三方凭证混在一起。
独立 custom provider 的最小配置
provider 的机器级配置放在 ~/.codex/config.toml。下面所有值都是占位符:
tomlmodel = "EXACT_PROVIDER_MODEL_ID" model_provider = "company_gateway" [model_providers.company_gateway] name = "Company gateway" base_url = "https://gateway.example.com/v1" env_key = "COMPANY_GATEWAY_API_KEY" wire_api = "responses"
把 key 放入 provider 文档要求的环境变量,而不是 TOML:
bashexport COMPANY_GATEWAY_API_KEY="replace-with-provider-key"
env_key 的值是环境变量名,不是 secret 本身。Codex 启动进程必须能看到这个变量;你在一个 terminal 里 export,却从另一个 IDE 或桌面进程启动 Codex,变量可能根本没有传过去。安全检查只判断是否存在,不输出内容:
bashif [ -n "${COMPANY_GATEWAY_API_KEY:-}" ]; then echo "COMPANY_GATEWAY_API_KEY is set" else echo "COMPANY_GATEWAY_API_KEY is missing" fi
Base URL 是否带 /v1,由该 provider 的当前文档和实际 endpoint 合同决定,不存在适用于所有服务的斜杠公式。模型 ID 也必须来自同一个 provider 的可用模型清单,不能把 OpenAI、网关别名和本地模型名随意互换。
三种 provider 认证方式不能混写
OpenAI 认证文档 为 alternative provider 区分了三种常见情况:
requires_openai_auth = true:沿用 OpenAI 登录,Codex 会忽略env_key。它适合通过 LLM proxy 访问 OpenAI 模型、且该 proxy 明确接受 OpenAI 认证的路线。env_key = "VARIABLE_NAME":从指定环境变量读取该 provider 自己的 API key。- 两者都不写:Codex 假定 endpoint 不需要认证,适合受控的本地模型服务。
需要短期 bearer token 的企业网关还可使用官方文档里的 [model_providers.<id>.auth] command。这个 auth command 不能与 env_key、requires_openai_auth 或 experimental bearer token 同时使用。选择一个 credential owner,不要靠多种认证方式“互相兜底”;否则 401 出现时,你甚至不知道实际发送了哪套凭证。
为什么放进项目 .codex/config.toml 不生效
Codex 可以读取可信项目里的 .codex/config.toml,但 provider 与认证属于机器级路由。当前 Advanced Configuration 明确列出项目层会忽略的键,其中包括:
openai_base_urlmodel_providermodel_providers
所以项目已经 trusted,并不等于这些键可以随仓库覆盖。把它们放回用户级 ~/.codex/config.toml。这条限制也避免一个仓库静默把你的 prompt、代码上下文和凭证导向另一个 endpoint。
如果用户配置仍未生效,再看更高优先级的 CLI flags、--config、选中的 profile 和实际启动命令。优先级只能解释“哪个已允许的值获胜”,不能让项目层的受限 key 变得合法。
用同一路径最小验证,不要只看 /v1/models
配置被解析只证明 Codex 接受了字段。/v1/models 返回 200 也只证明一个列表 endpoint 可达;它没有验证 Codex 实际使用的认证、模型、Responses、streaming 或工具调用。

更有用的验证顺序是:
- 备份当前用户配置,只保留这次路线需要的最小 provider block。
- 确认
model_provider、精确 model ID、Base URL 和 credential 都属于同一服务。 - 从会实际启动 Codex 的同一 terminal 或进程环境检查变量是否存在。
- 启动一次隔离会话,发送不含仓库、客户或账号数据的短任务,例如只要求回复
ROUTE_OK。 - 文本成功后,再分别验证你的真实工作需要的 streaming、tool call、长上下文或 web search;不要从第一条文本回复推断所有能力都兼容。
如果最小文本请求都没有到达目标 provider,回到配置层与 override;如果请求已经到达,继续改 TOML 通常不会修复 provider 账户或协议能力。
按结果确定下一位 owner
| 可观察结果 | 最可能的下一位 owner | 下一步 |
|---|---|---|
| 仍显示或调用旧 provider | 配置层、启动参数、profile | 核对用户文件与高优先级 override |
| 环境变量缺失 | Codex 启动环境 | 在启动该进程的环境提供变量,不输出 key |
401 / 403 | credential、账户、权限或认证合同 | 向 key 的签发方核对 scope、状态与 auth scheme |
404 / 405 | Base URL、路径拼接或 wire API | 对照 provider 当前 endpoint 文档,不先换 key |
| model not found | provider 模型映射或账号访问 | 核对同一 provider 的精确 model ID 与可用性 |
| 文本成功,stream/tool 失败 | provider capability 或 adapter | 保存失败功能的最小复现,停止宣称“完全兼容” |
| ChatGPT 用量不变、Platform 账单增加 | 认证与 billing route | 返回检查 codex login status 与 用量账本 |
对外求助时,只发送去敏后的诊断包:Codex 版本、操作系统、启动 surface、provider ID、Base URL 的 hostname、model ID、wire_api、完整错误文本、状态码、request ID 和时间戳。删除 API key、Authorization header、auth.json、私有代码与客户数据。
最终判断标准
一次成功配置应该让你清楚回答四件事:Codex 从哪个配置层读取 provider;credential 由谁签发;请求被送到哪个 Base URL;失败后该找 OpenAI、网关、本地服务、网络还是配置 owner。
如果这四个答案仍混在一起,先不要添加更多字段。退回到一条路线、一份用户级配置、一个环境变量和一个无敏感数据的最小请求。边界清楚以后,401、404、模型错误和功能缺口才会指向可执行的修复,而不是继续复制下一份“万能 config.toml”。



