环境变量最常见的误区是:
我刚才 export 过,所以 Codex 一定能读到。
实际上,变量可能只存在于当前终端,变量名也可能和 Provider 配置里的 env_key 对不上。先确认名字,再确认进程和作用域。
这篇教程先讲清 Codex 会读哪些环境变量,再按 macOS、Linux、Windows 分别给出"临时设置"和"永久保存"的方法,最后是报错对照表和常见问题。配置文件本身怎么写,请配合《Codex config.toml 配置指南》一起看。
速查:和 Codex 有关的环境变量
| 变量 | 作用 | 来源 |
|---|---|---|
| env_key 指向的变量(如 PROVIDER_API_KEY) | 自定义 Provider 读取的 API Key | 你在 config.toml 里自己命名 |
| OPENAI_API_KEY | 常用来通过 codex login --with-api-key 登录 | OpenAI 官方认证文档 |
| CODEX_HOME | Codex 本地状态目录,默认 ~/.codex | OpenAI 官方配置文档 |
| CODEX_CA_CERTIFICATE | 企业网络下的自定义根证书(PEM) | OpenAI 官方认证文档 |
| SSL_CERT_FILE | 未设置 CODEX_CA_CERTIFICATE 时的证书回退 | OpenAI 官方认证文档 |
| env_http_headers 指向的变量 | 给 Provider 请求附加的 HTTP 头 | OpenAI 官方配置文档 |
先确认 Provider 要读哪个变量
假设你的 ~/.codex/config.toml 里是这样写的:
[model_providers.custom]
name = "My Provider"
base_url = "https://<服务商给出的地址>/v1"
env_key = "PROVIDER_API_KEY"
wire_api = "responses"
这时 Codex 读取的是 PROVIDER_API_KEY。你设置成 OPENAI_API_KEY,并不会因为两者都"像 API Key"就自动等价。env_key 里写的是变量的名字,不是 Key 的值。
还要注意一条官方规则:如果自定义 Provider 设置了 requires_openai_auth = true,Codex 会使用 OpenAI 认证,并忽略 env_key。所以不要同时设计两条相互冲突的 Key 读取路线。
macOS:临时设置与永久保存
只对当前终端生效
export PROVIDER_API_KEY='你的 Key'
codex
export 只对当前终端窗口,以及从这个窗口启动的程序生效。关掉窗口,变量就没了。
安全地检查变量是否存在
if [ -n "$PROVIDER_API_KEY" ]; then
echo "PROVIDER_API_KEY is set"
else
echo "PROVIDER_API_KEY is missing"
fi
不要直接 echo 完整的 Key,终端历史和屏幕截图都可能把它泄露出去。
永久保存
macOS 默认的 shell 是 zsh,把 export 那一行写进 ~/.zshrc:
echo "export PROVIDER_API_KEY='你的 Key'" >> ~/.zshrc
source ~/.zshrc
写进启动文件后,每个新终端都会自动加载。但这也意味着 Key 以明文保存在这个文件里,不要把 ~/.zshrc 同步到公开的 dotfiles 仓库。
清除
unset PROVIDER_API_KEY
如果变量写进了 ~/.zshrc,新终端还会再次加载,需要把那一行从文件里删掉。
Linux:临时设置与永久保存
Linux 的临时设置、检查和清除命令和 macOS 完全一样:
export PROVIDER_API_KEY='你的 Key'
unset PROVIDER_API_KEY
永久保存时,大多数发行版默认用 bash,写进 ~/.bashrc:
echo "export PROVIDER_API_KEY='你的 Key'" >> ~/.bashrc
source ~/.bashrc
如果你在服务器上通过 SSH 登录使用,或者用 systemd、cron 之类的方式运行 codex exec,要特别注意:这些场景不一定会读取 ~/.bashrc。cron 任务通常需要在脚本里显式设置变量,或者在 crontab 中声明。我们在《cron + codex exec 每天自动生成 GitHub Trending 中文日报》里就遇到过这类问题。
Windows:临时设置与永久保存
只对当前 PowerShell 窗口生效
$env:PROVIDER_API_KEY = '你的 Key'
codex
检查是否存在
if ($env:PROVIDER_API_KEY) {
'PROVIDER_API_KEY is set'
} else {
'PROVIDER_API_KEY is missing'
}
永久保存到当前用户
[Environment]::SetEnvironmentVariable('PROVIDER_API_KEY', '你的 Key', 'User')
这条命令把变量写进当前用户的环境变量,已经打开的窗口不会自动生效,需要关掉 PowerShell(以及 VS Code 等编辑器)重新打开。你也可以在"系统属性 → 高级 → 环境变量"里手动添加,效果一样。
清除
Remove-Item Env:PROVIDER_API_KEY
[Environment]::SetEnvironmentVariable('PROVIDER_API_KEY', $null, 'User')
第一条只清除当前窗口,第二条删除永久保存的用户变量。
长期持久化之前,建议先在一个干净的新窗口里验证变量名和启动方式都没问题,再写入永久设置。
变量名怎么起才不容易出错
变量名看起来是小事,但很多"读不到 Key"的问题就出在名字上。几条建议:
- 全部用大写字母和下划线,例如
AICODEWITH_API_KEY。环境变量在 macOS 和 Linux 上区分大小写,Provider_Api_Key和PROVIDER_API_KEY是两个不同的变量。 - 名字里带上服务商或用途,不要统一叫
API_KEY。同时使用好几个服务时,一眼就能看出哪个变量对应哪个 Provider。 - config.toml 里的
env_key直接复制粘贴,不要手打,避免多一个空格或少一个字母。 - 不同项目、不同用途分开命名,比如本机用一个、CI 用另一个,出问题时可以单独替换。
临时设置还是永久保存?
很多问题其实源于一开始就选错了方式。可以按下面的表来选:
| 场景 | 推荐方式 | 理由 |
|---|---|---|
| 第一次试用、排查问题 | 临时设置(export / $env:) | 关掉窗口就消失,不会留下残留,方便对比 |
| 自己的电脑日常使用 | 写进 shell 启动文件或用户环境变量 | 不用每次手动设置 |
| 多人共用的机器 | 只用临时设置,或用系统凭据库 | 避免别人登录后读到你的 Key |
| CI/CD、定时任务 | 平台自带的密钥管理 | 不依赖交互式 shell,也不会写进日志 |
一个实用的习惯是:先用临时设置跑通,再写成永久设置。如果临时设置能跑通而永久设置不行,问题一定出在启动文件没被加载,或者写错了文件;如果临时设置也不行,就去检查变量名、Key 和 Provider 配置。
从编辑器或桌面图标启动时要注意
在终端里 export 的变量,只会传给从这个终端启动的程序。如果你是从程序坞、开始菜单或桌面图标打开编辑器,再在编辑器里使用 Codex,编辑器不一定能拿到你在某个终端里临时设置的变量。
稳妥的做法有两种:一是把变量写进永久设置,然后完全退出编辑器再重新打开;二是先在终端里设置好变量,再从这个终端用命令启动编辑器。排查时,可以在编辑器的内置终端里运行前面的检查命令,确认变量确实存在。
.env 文件不是自动答案
项目里存在 .env,不代表 Codex CLI 会自动加载它。是否生效取决于你的 shell、启动脚本或项目工具。
如果你确实在用 .env,至少检查 .gitignore 里有这两行:
.env
.env.*
团队如果只需要共享变量名,可以提交一份 .env.example,里面只写变量名和说明,不要提交真实密钥。
别让 Codex 运行的命令读到你的 Key
很多人没意识到:Codex 执行命令时,会把环境变量传给它启动的子进程。官方提供了 shell_environment_policy 来控制这件事,而且有一个容易误解的默认值:ignore_default_excludes 默认是 true,也就是默认不会自动过滤名字里带 KEY、SECRET、TOKEN 的变量。
如果你的终端里放着各种 API Key,可以在 config.toml 里加上:
[shell_environment_policy]
ignore_default_excludes = false
这样 Codex 运行的命令就不会自动拿到这些敏感变量。具体的过滤规则见官方 Advanced Configuration 文档。
企业网络:证书相关的环境变量
如果公司网络使用 TLS 代理或私有根证书,登录和请求可能报证书错误。官方给出的做法是,在登录前设置 CODEX_CA_CERTIFICATE 指向公司提供的 PEM 证书:
export CODEX_CA_CERTIFICATE=/path/to/corporate-root-ca.pem
codex login
没有设置这个变量时,Codex 会退回使用 SSL_CERT_FILE。Windows 上把 export 换成 $env:CODEX_CA_CERTIFICATE = '路径' 即可。
环境变量、auth.json 和 config.toml 是什么关系
刚接触 Codex 的用户,经常分不清这三样东西各管什么。简单说:
- config.toml 决定"连哪里、用什么模型、用哪种认证方式"。它是说明书,本身最好不包含任何密钥。
- 环境变量 是"把 Key 交给 Codex"的一种方式。当 Provider 配置了
env_key,Codex 就到对应的环境变量里取 Key。 - auth.json 是另一种方式。官方说明,无论用 ChatGPT 登录还是 API Key 登录,Codex 都会把登录信息缓存在
~/.codex/auth.json(或系统凭据库)里。当 Provider 设置了requires_openai_auth = true时,用的就是这条路线。
所以排查"Key 为什么没生效"时,先看 config.toml 里的 Provider 用的是哪条路线:是 env_key,就查环境变量;是 requires_openai_auth,就查 codex login status 和 auth.json。两条路线的检查方法完全不同,查错了方向会浪费很多时间。auth.json 的位置、风险和处理方法,详见《Codex auth.json 是什么》。
变量已经设置,为什么还失败
按这个顺序查:
env_key和变量名是否完全一致,包括大小写;- Codex 是否是从设置了变量的同一个终端启动的;
- Key 是否多了空格、引号或换行;
- 当前
model_provider是否真的指向这段 Provider 配置; - Base URL 和模型 ID 是否正确;
- 是否同时设置了
requires_openai_auth = true,导致env_key被忽略。
在 CI/CD 里使用环境变量
OpenAI 官方认证文档建议,CI/CD 这类程序化的 Codex CLI 工作流使用 API Key 认证,同时提醒不要在不受信任或公开的环境里暴露 Codex 的执行能力。落到环境变量上,有几条实用原则:
- 用平台的密钥功能。GitHub Actions、GitLab CI 等平台都有专门的密钥设置,Key 存在那里,运行时再注入为环境变量,不要写进仓库里的配置文件。
- 一个用途一个 Key。给 CI 单独创建 Key,出问题时可以只撤销这一个,不影响你本机的使用。
- 不要在日志里打印。脚本里只检查变量是否存在,不要输出它的值。
- 限制谁能触发。公开仓库的外部 PR 不应该能拿到带 Key 的环境。
多个项目各自使用不同 Key 的完整方案,可以参考《Codex 多项目怎么管理 API Key》。
一套完整的验证流程
改完环境变量后,按这五步确认整条链路是通的:
- 打开一个新的终端窗口;
- 用前面的检查命令确认变量存在(只看"set / missing",不打印值);
- 确认
~/.codex/config.toml里model_provider指向的那段配置,env_key和变量名一致; - 启动
codex,只发一句很短的请求; - 到服务商后台查看调用记录,确认时间、模型和 Key 都对得上。
五步都通过,才算真正配置成功。只看到"配置文件存在"或"变量设置了",都不能说明 Codex 已经在用这个 Key。
常见报错对照表
| 报错或现象 | 常见原因 | 解决方法 |
|---|---|---|
| 401 Unauthorized | 变量没设置、变量名和 env_key 不一致,或 Key 无效 | 用上面的检查命令确认变量存在,核对名字,必要时重新创建 Key |
| export 之后新窗口里读不到 | export 只对当前窗口有效 | 写进 ~/.zshrc 或 ~/.bashrc,或在新窗口重新设置 |
| Windows 永久设置后仍读不到 | 已打开的窗口不会刷新环境变量 | 关掉 PowerShell 和编辑器后重新打开 |
| 设置了 env_key 却在用 OpenAI 登录 | Provider 设置了 requires_openai_auth = true | 两种认证二选一,删掉不用的那一项 |
| cron / CI 里运行失败 | 这些环境不读取交互式 shell 的启动文件 | 在脚本或 CI 的密钥设置里显式提供变量 |
| 登录时报证书错误 | 企业 TLS 代理 | 设置 CODEX_CA_CERTIFICATE 指向 PEM 证书 |
| Key 出现在了命令输出里 | 子进程继承了环境变量 | 设置 ignore_default_excludes = false |
更多 401 的排查方法见《Codex 401 Unauthorized 怎么解决》。
如果用 AI Code With
如果你希望用环境变量管理 AI Code With 的 Key,可以先注册 AI Code With,为 Codex 单独创建一个 Key,再用一个容易识别的变量名,例如 AICODEWITH_API_KEY,然后让 Provider 的 env_key 指向它。
但要注意:AI Code With 当前的 Codex(终端)文档用的是另一套方式:设置 requires_openai_auth = true,把 Key 写进 ~/.codex/auth.json。按前面讲的官方规则,这种方式下 env_key 会被忽略。两种方式不要混在一起。最稳的做法是:选一套认证路线,跑通后再固化。
常见问题
Codex 会自动读取 OPENAI_API_KEY 吗?
不能这么假设。自定义 Provider 读取的是 env_key 指定的变量。官方认证文档里,OPENAI_API_KEY 的用法是通过 printenv OPENAI_API_KEY | codex login --with-api-key 把 Key 传给登录命令。
env_key 里应该写 Key 还是变量名?
写变量名。比如 env_key = "PROVIDER_API_KEY",然后在系统里设置 PROVIDER_API_KEY 这个环境变量,值才是你的 Key。
macOS 上写进 ~/.bash_profile 为什么没用?
macOS 默认 shell 是 zsh,读取的是 ~/.zshrc。可以用 echo $SHELL 确认你当前用的是哪个 shell,再写进对应的启动文件。
可以把 Key 写进项目的 .env 吗?
可以,但 Codex CLI 不会自动加载 .env,需要你的 shell 或工具负责加载。无论如何,都要确认 .env 已经加进 .gitignore。
怎么修改 Codex 的配置目录?
设置 CODEX_HOME 环境变量。官方文档说明 Codex 的本地状态都存放在 CODEX_HOME 下,默认是 ~/.codex。
换了 Key 之后为什么还在用旧的?
最常见的原因是旧值还留在启动文件或用户环境变量里,或者当前窗口没有重新打开。清除旧值,重开终端,再用检查命令确认。
免费注册 AI Code With,给 Codex 配一个专用 Key →



