Codex 的 API Key 不只是一个字符串。它决定了请求以谁的身份计费、能调用哪些模型、泄露后影响多大。遇到的 401,多数不是 Key 失效,而是变量名不一致、请求头被改写、配置层级不对,或本地缓存了旧凭证。

本文按“Key 的类型、创建、环境变量与配置文件、profiles、轮换、最小权限、CI、401 排查”的顺序,给出一套可以直接照做的配置方法。命令与配置项以当前 Codex 版本和所用网关文档为准。

说明:OpenAI、Codex、ChatGPT 是 OpenAI 的商标或注册商标,本文仅作技术说明,与 OpenAI 无隶属关系。密钥权限、接口范围和计费方式以各平台官方文档及站内页面为准。

一、先分清三种 Key 与两套存储

Codex 相关凭证容易混淆,先按用途分开:

名称 典型用途 存放位置 注意
OpenAI Platform API Key codex login --with-api-key 登录 auth.json 或系统钥匙串 按接口标准费率计费
CODEX_API_KEY codex exec、SDK 等单次运行 仅当次进程环境 不落盘,适合 CI
自定义 provider Key 通过 env_key 指向环境变量 shell 环境或密钥管理服务 团队网关常用,便于限额

第一套存储是“登录凭证”,由 cli_auth_credentials_store 控制:file 写入 CODEX_HOME 下的 auth.json,keyring 用系统钥匙串,auto 先试钥匙串再回退文件,ephemeral 只保存在当前进程内存。第二套存储是“provider Key”,由 env_key 指定环境变量名,Codex 每次请求时读取。注意:env_key 只是变量名,不是变量本身。

CODEX_HOME 默认是 ~/.codex,可以改到受控目录。OPENAI_API_KEY 是登录命令读取的来源变量;CODEX_API_KEY 则是非交互运行时的单次凭证,名字相近,用途不同。

二、创建 Key:五步做完

  1. 打开中商起航 AI 网关或所用平台,注册并登录控制台。
  2. 进入「API 密钥」页面新建,名称写清环境和用途,例如 codex-work-mac。
  3. 设置额度上限和过期时间。测试 Key 先给低额度,确认真实消耗后再调整。
  4. 如果平台支持模型白名单或项目范围,只勾选 Codex 需要调用的模型。
  5. 复制完整 Key,立即存入密码管理器或密钥管理服务。多数控制台只显示一次。

Key 常以 sk- 开头,但前缀不能证明真伪,也不能说明权限。复制时注意首尾空格、换行和多余引号,这是 401 的高频原因。创建后先用最小请求验证,再分发给团队成员。

三、环境变量与 config.toml 怎么配合

推荐做法是:配置文件只写变量名,真实 Key 放环境变量或密钥管理工具。~/.codex/config.toml 示例:

# ~/.codex/config.toml
model = "your-model-id"
model_provider = "zsqh"

[model_providers.zsqh]
name = "ZSQH AI Gateway"
base_url = "https://ai.zhongshangqihang.com/v1"
wire_api = "responses"
env_key = "ZSQH_API_KEY"
env_key_instructions = "在网关控制台创建 Key 后导出为环境变量"

然后在启动 Codex 的同一个 shell 里导出:

export ZSQH_API_KEY="sk-你的密钥"

macOS 和 Linux 可以把这行放进 ~/.zshrc.local 之类的私有文件,主配置文件只引用变量。Windows PowerShell 用 $env:ZSQH_API_KEY="sk-你的密钥"。从 Dock、IDE 或桌面应用启动的进程,可能读不到 shell 配置里的变量,遇到这种情况要改在启动脚本或系统环境变量里注入。

如果网关要求自定义请求头,可用 env_http_headers = { "X-API-Key" = "ZSQH_API_KEY" } 代替 env_key,并配置本地模型目录。如果 Key 由 Vault、KMS 一类工具动态签发,可用 [model_providers.zsqh.auth] 的 command 取令牌,但不能与 env_key 同时配置。配置里的 experimental_bearer_token 能直接写密钥,但官方不推荐,团队环境应避免。

个人也可以走登录方式:printenv OPENAI_API_KEY | codex login --with-api-key,凭证进入 auth.json 或钥匙串;清除用 codex logout。团队网关更建议用 env_key,额度、模型权限和吊销都可在网关侧统一管理。

四、多套配置与 profiles

建议至少分三套凭证:个人日常、项目专用、自动化。它们的额度、权限和轮换周期不同,混用会让用量和故障都难以定位。

较新的 Codex 版本把 profile 拆成了独立文件。主配置里定义两个 provider,分别读取不同的环境变量:

# ~/.codex/config.toml
model = "your-model-id"
model_provider = "zsqh_work"

[model_providers.zsqh_work]
base_url = "https://ai.zhongshangqihang.com/v1"
wire_api = "responses"
env_key = "ZSQH_WORK_KEY"

[model_providers.zsqh_test]
base_url = "https://ai.zhongshangqihang.com/v1"
wire_api = "responses"
env_key = "ZSQH_TEST_KEY"

再建 ~/.codex/test.config.toml,只写要覆盖的顶层键:

model = "your-test-model-id"
model_provider = "zsqh_test"

运行 codex --profile test 即可切换。注意:从 0.134.0 起,旧的 [profiles.xxx] 表和顶层 profile = "..." 写法不再被读取,profile 文件里也不要再嵌套 [profiles.xxx],直接用顶层键。旧版本可能仍接受旧写法,升级前先看版本说明。

受信任项目里的 .codex/config.toml 只适合放非敏感约定;其中的 model_provider、model_providers 和 profile 会被忽略,也不要把 Key 写进去提交。

五、Key 轮换:什么时候换、怎么换

轮换的目的不是走流程,而是缩短泄露后的有效窗口。员工离职、设备丢失、怀疑泄露、供应商要求,以及固定周期(例如每 90 天),都适合触发轮换。

  1. 在控制台创建新 Key,命名带日期,例如 codex-prod-2026-10。
  2. 先把新 Key 写入密钥管理工具或环境变量,暂时保留旧 Key。
  3. 用 codex exec 和一条最小请求各验证一次,确认模型、额度、权限正常。
  4. 观察旧 Key 的用量日志,确认没有遗漏的脚本或成员仍在使用。
  5. 停用旧 Key,再观察一到两天错误率和失败请求。
  6. 记录轮换时间、负责人和影响范围,方便交接与审计。

不要在生产高峰期做轮换。两把 Key 并行一段时间,比“删了再建”安全。只用登录方式时,轮换后执行 codex logout 再重新登录,避免 auth.json 里残留旧凭证。auth.json 应当按密码级别保护,不要同步到公共网盘或代码仓库。

六、最小权限与防泄露

  • 一人一把 Key,按环境再拆;CI 用单独 Key,额度单独设置。
  • 给 Key 设过期时间、预算和并发上限,模型权限只开需要的范围。
  • 平台支持 IP 白名单时,限制到办公网或 runner 出口;不支持就靠额度和告警兜底。
  • 企业环境可用 forced_login_method = "api" 或 "chatgpt" 强制统一登录方式,避免成员混用凭证。
  • 个人机器优先用 cli_auth_credentials_store = "keyring";共享机器或 CI 用 ephemeral,减少落盘。
  • .gitignore 覆盖 .env、.env.*、auth.json、*.pem 等文件;提交前用 secret scanning 或 pre-commit hook 检查 sk- 模式。
  • 不在代码里写默认 Key,不用 echo $ZSQH_API_KEY 调试,日志中对 Authorization 请求头脱敏。

确认泄露后的顺序是:先停用或删除 Key,再创建新 Key,然后查用量日志和仓库历史。只删文件不够,旧 Key 可能已经被复制到别处。

七、CI 与非交互使用

CI 的原则是“Key 不进入代码、不进入镜像、不进入日志”。

  • 单次运行用 CODEX_API_KEY=<key> codex exec --json "...",只在该命令前注入,不要把变量设成作业级环境变量。
  • GitHub Actions 优先用 Codex 官方 Action,不要把 Key 直接塞进 shell 步骤。
  • CI 使用独立 Key,额度低、权限窄,只在受保护分支或受信工作流中可用。
  • 用 --ephemeral 避免把会话文件写到磁盘;不在 Git 仓库内运行时按需加 --skip-git-repo-check。
  • 不要在公开仓库或不可信 runner 上使用 ChatGPT 托管凭证。

八、401 排查:按这个顺序查

401 表示认证失败,不代表 Key 一定错了。按顺序排查即可:

  1. 执行 codex login status,确认当前实际生效的认证方式。
  2. 确认 env_key 指向的变量名拼写一致,且在当前进程里非空;只看长度,不打印完整值。
  3. 确认 Codex 从哪个环境启动。IDE 内置终端、Docker、systemd、launchd 可能没有继承 shell 变量。
  4. 重新从控制台复制 Key,排除首尾空格、换行和引号。
  5. 如果使用登录凭证,执行 codex logout 后重新登录,排除 auth.json 残留。
  6. 检查 forced_login_method 是否与当前凭证类型冲突;不匹配时 Codex 可能直接退出或拒绝请求。
  7. 检查 Key 是否过期、被停用、余额不足,或没有该模型的权限。
  8. 确认 Base URL 和 /v1 路径正确,代理没有剥离或改写 Authorization 头;必要时用网关日志核对请求。

常见错误对照:

现象 常见原因 处理
401 Unauthorized 变量未导出、变量名不一致、凭证过期 核对 env_key;重开终端;重新登录
403 Forbidden 无模型权限、IP 限制、额度冻结 查控制台权限和白名单
404 Not Found Base URL 多了或少了 /v1,路径不对 逐段核对地址与接口范围
429 Too Many Requests 并发或额度超限 降并发,检查 Key 限额
model not found 模型标识填错 复制价格页上的准确标识

常见问题

Codex API Key 和 ChatGPT 订阅是一回事吗?

不是。ChatGPT 订阅面向网页和客户端产品;Codex 可以走账号登录,也可以用 API Key 按量计费。两者的额度、账单和权限范围不同,团队采购时要分开核算。

env_key 和 OPENAI_API_KEY 是什么关系?

env_key 是配置项,值是一个环境变量名;OPENAI_API_KEY 是常见的变量名之一,也是 codex login --with-api-key 读取的来源。你可以让 env_key = "OPENAI_API_KEY",但更建议为网关单独起名,避免和登录凭证混用。

可以把 Key 直接写进 config.toml 吗?

不建议。明文 Key 容易随配置备份、截图或仓库泄露。用 env_key 引用环境变量,或通过 [model_providers.xxx.auth] 调用外部取令牌命令。

轮换 Key 需要停服吗?

不需要。先创建新 Key 并验证,再切换配置,最后停用旧 Key,让两把 Key 并行一段时间,可以避免请求中断。

为什么 codex login status 正常,请求还是 401?

登录状态正常只说明本地凭证存在,不代表自定义 provider 的 Key 可用。重点检查 env_key 变量、Base URL、网关余额和模型权限;如果请求经过代理,再检查请求头是否被改写。

下一步

如果你还没有 Key,可以从注册入口创建一把低额度测试 Key,按本文顺序配置和验证。模型、额度和计费方式见模型价格,价格会随模型版本和上游政策调整,以页面实时信息为准。

相关阅读: