跳转到内容

在 CI/CD 中维护 Codex 账户身份验证(高级)

身份 非官方简体中文镜像
翻译状态 AI 翻译 / AI 审校
来源版本 官方未提供
同步日期 2026-07-26
官方原文 learn.chatgpt.com

本指南介绍如何在受信任的 CI/CD runner 上保持 ChatGPT 管理的 Codex 身份验证正常工作,而无需自行调用 OAuth 令牌端点。

自动化身份验证的正确方式是使用 API key。仅当你明确需要以自己的 Codex 账户运行工作流时,才使用本指南。

模式如下:

  1. 在受信任的计算机上使用 codex login 创建一次 auth.json
  2. 将该文件放到 runner 上。
  3. 正常运行 Codex。
  4. 当会话变得过期时,让 Codex 刷新会话。
  5. 保留刷新的 auth.json,供下一次运行使用。

这是面向企业和其他受信任私有自动化环境的高级工作流。对于大多数 CI/CD 作业,仍建议使用 API key。

请将 ~/.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”。

仅当以下条件全部满足时,才使用本指南:

  • 你需要 ChatGPT 管理的 Codex 身份验证,而不是 API key
  • codex login 无法在远程 runner 上运行
  • runner 是受信任的私有基础设施
  • 你可以在多次运行之间保留刷新的 auth.json
  • 每个 auth.json 副本只会由一台计算机或串行作业流使用

本指南适用于 Codex 管理的 ChatGPT 身份验证(auth_mode: "chatgpt")。

本指南不适用于:

  • API key 身份验证
  • 外部令牌主机集成(auth_mode: "chatgptAuthTokens"
  • Codex 之外的通用 OAuth 客户端

如果你的凭据存储在操作系统密钥环中,请先切换为文件存储。请参阅凭据存储

在可以进行浏览器登录的受信任计算机上:

  1. 将 Codex 配置为在文件中存储凭据:
cli_auth_credentials_store = "file"
  1. 运行:
Terminal window
codex login
  1. 验证文件内容是否为 ChatGPT 管理的身份验证:
Terminal window
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_tokentrue

然后,将 auth.json 的内容放入 CI/CD 密钥管理器,或将其复制到受信任的持久化 runner。

推荐模式:在自托管 runner 上使用 GitHub Actions

Section titled “推荐模式:在自托管 runner 上使用 GitHub Actions”

最简单的全自动设置是使用带有持久化 CODEX_HOME 的自托管 GitHub Actions runner。

这种模式运行良好的原因:

  • runner 可以在不同作业之间将 auth.json 保留在磁盘上
  • Codex 可以直接更新该文件
  • 后续作业会自动获取刷新的令牌
  • 你只需在引导或重新初始化时使用原始密钥

关键在于,仅当 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 托管的 runner、GitLab 共享 runner 或任何其他临时环境,runner 的文件系统会在每个作业结束后消失。在这种设置下,你需要完成一次往返流程:

  1. 从安全存储中恢复当前的 auth.json
  2. 运行 Codex
  3. 将更新后的 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 在本次运行中生成的刷新后文件,而不是原始初始化文件。

任何正常的 Codex 运行都可以刷新会话。

这意味着你有两种可行的选择:

  • 让现有的 CI/CD Codex 作业自然地刷新文件
  • 如果实际作业运行得不够频繁,则添加一个轻量级的计划维护作业,例如上面的 GitHub Actions 示例

会话变得过期后的第一次 Codex 运行会刷新 auth.json

  • 每个 runner 或每个串行工作流流使用一个 auth.json
  • 不要在并发作业或多台计算机之间共享同一个文件。
  • 不要在每次运行时都使用原始初始化文件覆盖持久化 runner 上已刷新的文件。
  • 不要将 auth.json 存储在代码库、日志或公共工件存储中。
  • 如果内置刷新停止工作,请从受信任的计算机重新初始化。

此流程可以减少手动操作,但无法保证同一个会话永久持续。

如果出现以下情况,请使用新的 auth.json 重新初始化 runner:

  • Codex 开始返回 401,且 runner 无法再刷新
  • 刷新令牌被撤销或已过期
  • 另一台计算机或并发作业先轮换了令牌
  • 安全存储往返失败,恢复了旧文件

重新初始化的步骤:

  1. 在受信任的计算机上运行 codex login
  2. 替换存储的 CI/CD auth.json 副本。
  3. 让下一次 runner 作业继续使用 Codex 的内置刷新流程。

检查 runner 是否仍然具有由 ChatGPT 管理的身份验证令牌,以及是否存在 last_refresh

Terminal window
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"

如果 runner 是持久化的,你应该会看到同一个文件在多次运行之间持续存在。如果 runner 是临时的,请确认写回步骤存储的是上一个作业生成的更新后文件。

如果你希望在开源客户端中验证此行为: