维护 Codex 账户身份验证在 CI/CD (高级)
如需完整文档索引,请参阅 llms.txt。文档页面的 Markdown 版本可通过在页面后追加
.md来获取 URL。
本指南说明如何保持 ChatGPT管理的 Codex 身份验证在受信任的 CI/CD 运行器上正常工作,而无需自行调用 OAuth 令牌端点。
自动化身份验证的正确方式是使用 API 密钥。仅当你确实需要以你的 账户运行工作流时,才使用本指南 Codex 。
模式如下:
- 创建
auth.json一次,在受信任的机器上使用codex login。 - 将该文件放到运行器上。
- 正常运行 Codex 。
- 让 Codex 在会话过期时刷新会话。
- 保留刷新后的
auth.json供下一次运行使用。
这是面向企业和其他受信任私有 自动化的高级工作流。 API 密钥仍然是大多数 CI/CD 作业的推荐选项。
请像对待密码一样对待 ~/.codex/auth.json :它包含访问令牌。不要
提交它、粘贴到工单中,或在聊天中分享它。不要将此
工作流用于公共或开源仓库。
Codex 已经知道如何刷新 ChatGPT 管理的会话。
截至当前的开源客户端:
- Codex 从以下位置加载本地身份验证缓存:
auth.json - 如果
last_refresh早于约 8 天, Codex 会刷新令牌 包,然后运行继续 - 成功刷新后, Codex 会将新令牌和新的
last_refresh写回到auth.json - 如果请求收到
401, Codex 也内置了刷新并重试路径
这意味着受支持的 CI/CD 策略不是“自行调用刷新 API ”。
而是“运行 Codex 并持久化更新后的 auth.json。”
何时使用本指南
Section titled “何时使用本指南”仅当以下条件全部满足时,才使用本指南:
- 你需要 ChatGPT 管理的 Codex 身份验证,而不是 API key
codex login无法在远程 runner 上运行- runner 是受信任的私有基础设施
- 你可以在多次运行之间保留刷新的
auth.json - 每个
auth.json副本只会由一台计算机或串行作业流使用
本指南适用于 Codex-managed ChatGPT 身份验证(auth_mode: "chatgpt")。
本指南不适用于:
- API 密钥身份验证
- 外部令牌主机集成(
auth_mode: "chatgptAuthTokens") - 通用 OAuth 以外的客户端 Codex
如果你的凭据存储在 OS 钥匙串中,请先切换到基于文件的存储 。参见 凭据存储。
初始化一次 auth.json
Section titled “初始化一次 auth.json”在可以进行浏览器登录的受信任计算机上:
- 将 Codex 配置为在文件中存储凭据:
cli_auth_credentials_store = "file"- 运行:
codex login- 验证文件内容看起来是由 ChatGPT 管理的身份验证:
AUTH_FILE="${CODEX_HOME:-$HOME/.codex}/auth.json"
jq '{ auth_mode, has_tokens: (.tokens != null), has_refresh_token: ((.tokens.refresh_token // "") != ""), last_refresh}' "$AUTH_FILE"仅当以下条件满足时,才继续:
auth_mode为"chatgpt"has_refresh_token为true
然后将 auth.json 的内容放入你的 CI/CD 密钥管理器,或将
复制到受信任的持久运行器。
推荐模式:在自托管 runner 上使用 GitHub Actions
Section titled “推荐模式:在自托管 runner 上使用 GitHub Actions”最简单的全自动设置是一个自托管的 GitHub Actions 运行器,并带有一个
持久的 CODEX_HOME。
这种模式运行良好的原因:
- runner 可以在不同作业之间将
auth.json保留在磁盘上 - Codex 可以直接更新该文件
- 后续作业会自动获取刷新的令牌
- 你只需在引导或重新初始化时使用原始 secret
关键细节是仅在 auth.json 缺失时才注入种子。如果你
每次运行都用原始密钥重写该文件,就会丢弃
刚刚写入的刷新后令牌 Codex 。
计划任务工作流示例:
name: Keep Codex auth fresh
on: schedule: - cron: "0 9 * * 1" workflow_dispatch:
jobs: keep-codex-auth-fresh: runs-on: self-hosted steps: - name: Bootstrap auth.json if needed shell: bash env: CODEX_AUTH_JSON: ${{ secrets.CODEX_AUTH_JSON }} run: | export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}" mkdir -p "$CODEX_HOME" chmod 700 "$CODEX_HOME"
if [ ! -f "$CODEX_HOME/auth.json" ]; then printf '%s' "$CODEX_AUTH_JSON" > "$CODEX_HOME/auth.json" chmod 600 "$CODEX_HOME/auth.json" fi
- name: Run Codex shell: bash run: | codex exec --json "Reply with the single word OK." >/dev/null其工作方式如下:
- 第一次运行会注入种子
auth.json - 后续运行会复用同一个文件
- 一旦缓存的会话足够旧, Codex 会在正常的
codex exec步骤期间刷新它 - 刷新后的文件会保留在磁盘上,供下一次工作流运行使用
每周计划通常已经足够,因为 Codex 在当前开源客户端中会将会话视为过期 大约 8 天后。
临时 runner:恢复、运行 Codex,并持久化更新后的文件
Section titled “临时 runner:恢复、运行 Codex,并持久化更新后的文件”如果你使用 GitHub托管的运行器、 GitLab 共享运行器,或任何其他临时 环境,运行器文件系统会在每个作业后消失。在这种设置中, 你需要一次往返:
- 从安全存储中恢复当前的
auth.json - 运行 Codex
- 将更新后的
auth.json写回安全存储
通用的 GitHub Actions 结构:
name: Run Codex with managed auth
on: workflow_dispatch:
jobs: codex-job: runs-on: ubuntu-latest steps: - name: Restore auth.json shell: bash run: | export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}" mkdir -p "$CODEX_HOME" chmod 700 "$CODEX_HOME"
# Replace this with your secret manager or secure storage command. my-secret-cli read codex-auth-json > "$CODEX_HOME/auth.json" chmod 600 "$CODEX_HOME/auth.json"
- name: Run Codex shell: bash run: | codex exec --json "summarize the failing tests"
- name: Persist refreshed auth.json if: always() shell: bash run: | # Replace this with your secret manager or secure storage command. my-secret-cli write codex-auth-json < "$CODEX_HOME/auth.json"关键要求是,写回步骤存储的是 Codex 在运行期间生成的刷新后文件,而不是原始种子。
无需单独的刷新命令
Section titled “无需单独的刷新命令”任何正常的 Codex 运行都可以刷新会话。
这意味着你有两种可行的选择:
- 让你现有的 CI/CD Codex 作业自然刷新该文件
- 如果你的实际作业运行不够频繁,请添加一个轻量级的定期维护作业,例如 GitHub 上面的 Actions 示例 。
会话过期后的第一次 Codex 运行会刷新
auth.json。
重要的运维规则
Section titled “重要的运维规则”- 每个运行器或每个串行化工作流流使用一个
auth.json。 - 不要在并发作业或多台机器之间共享同一个文件。
- 不要在每次运行时用原始种子覆盖持久运行器的刷新后文件 。
- 不要将
auth.json存储在仓库、日志或公共构件存储中。 - 如果内置刷新停止工作,请从受信任的机器重新注入种子。
刷新停止工作时的处理方式
Section titled “刷新停止工作时的处理方式”此流程减少了手动工作,但并不保证同一会话可以持续 永久有效。
如果出现以下情况,请使用新的 auth.json 重新初始化 runner:
- Codex 开始返回
401,且 runner 无法再刷新会话 - 刷新令牌被撤销或已过期
- 另一台计算机或并发作业先轮换了令牌
- 安全存储往返失败,恢复了旧文件
重新初始化的步骤:
- 在受信任的计算机上运行
codex login。 - 替换存储的 CI/CD
auth.json副本。 - 让下一次 runner 作业继续使用 Codex 的内置刷新流程。
验证 runner 是否在维护会话
Section titled “验证 runner 是否在维护会话”检查运行器是否仍有托管身份验证令牌,以及 last_refresh
是否存在:
AUTH_FILE="${CODEX_HOME:-$HOME/.codex}/auth.json"
jq '{ auth_mode, last_refresh, has_access_token: ((.tokens.access_token // "") != ""), has_id_token: ((.tokens.id_token // "") != ""), has_refresh_token: ((.tokens.refresh_token // "") != "")}' "$AUTH_FILE"如果你的运行器是持久的,你应该会看到同一个文件在多次运行之间持续存在 。如果你的运行器是临时的,请确认你的写回步骤 正在存储上一个作业更新后的文件。
如果你希望在开源客户端中验证此行为:
codex-rs/core/src/auth.rs涵盖过期令牌检测、自动刷新、401 后刷新恢复,以及 刷新后令牌的持久化codex-rs/core/src/auth/storage.rs涵盖基于文件的auth.json存储