CI/CD で Codex アカウント認証を維持する(上級者向け)
Codex の組み込み更新フローを使用し、信頼できる CI/CD ランナーで auth.json を継続して利用する
このガイドでは、OAuth トークンエンドポイントを自分で呼び出すことなく、信頼できる CI/CD ランナーで ChatGPT が管理する Codex 認証を維持する方法を説明します。
自動化の適切な認証方法は、API key を使用することです。このガイドは、ワークフローを自分の Codex アカウントとして実行する必要がある場合にのみ使用してください。
このパターンは次のとおりです。
- 信頼できるマシンで
codex loginを使用してauth.jsonを一度作成します。 - そのファイルをランナーに配置します。
- Codex を通常どおり実行します。
- セッションが古くなったら、Codex に更新させます。
- 更新された
auth.jsonを次回の実行用に保持します。
これは、エンタープライズ環境などの信頼できるプライベートな自動化向けの高度なワークフローです。ほとんどの CI/CD ジョブでは、引き続き API key が推奨されます。
この方法が機能する理由
Codex には、ChatGPT が管理するセッションを更新する仕組みがすでに備わっています。
現在のオープンソースクライアントでは、次のように動作します。
- Codex は
auth.jsonからローカルの認証キャッシュを読み込みます last_refreshが約 8 日より古い場合、Codex は実行を続ける前にトークンバンドルを更新します- 更新に成功すると、Codex は新しいトークンと新しい
last_refreshをauth.jsonに書き戻します - リクエストで
401が返された場合も、Codex には更新して再試行する組み込みパスがあります
つまり、サポートされている CI/CD 戦略は「更新 API を自分で呼び出す」ことではありません。「Codex を実行し、更新された auth.json を永続化する」ことです。
使用する場面
このガイドは、次の条件をすべて満たす場合にのみ使用してください。
- API key ではなく、ChatGPT が管理する Codex 認証が必要である
- リモートランナーで
codex loginを実行できない - ランナーが信頼できるプライベートインフラストラクチャである
- 更新された
auth.jsonを実行間で保持できる - 特定の
auth.jsonのコピーを使用するのが、1 台のマシンまたは直列化された 1 つのジョブストリームだけである
このガイドは、Codex が管理する ChatGPT 認証(auth_mode: "chatgpt")に適用されます。
次の認証には適用されません。
- API key 認証
- 外部トークンを使用するホスト統合(
auth_mode: "chatgptAuthTokens") - Codex 外部の汎用 OAuth クライアント
認証情報が OS のキーチェーンに保存されている場合は、まずファイルベースのストレージに切り替えてください。認証情報の保存を参照してください。
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 のシークレットマネージャーに保存するか、信頼できる永続ランナーにコピーします。
推奨パターン:セルフホスト GitHub Actions ランナー
完全自動化された最もシンプルな構成は、永続的な CODEX_HOME を持つセルフホスト GitHub Actions ランナーです。
このパターンが適している理由は次のとおりです。
- ランナーはジョブ間で
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を初期設定します - 2 回目以降は同じファイルを再利用します
- キャッシュ済みセッションが十分に古くなると、通常の
codex execステップ中に Codex が更新します - 更新されたファイルは、次回のワークフロー実行用にディスク上に残ります
現在のオープンソースクライアントでは、Codex は約 8 日後にセッションを古いとみなすため、通常は週 1 回のスケジュールで十分です。
一時的なランナー:復元し、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 が生成した更新済みファイルを書き戻しステップで保存することです。
個別の更新コマンドは不要
通常の Codex 実行でセッションを更新できます。
したがって、次の 2 つの方法を選択できます。
- 既存の CI/CD Codex ジョブでファイルを自然に更新する
- 実際のジョブの実行頻度が十分でない場合は、上記の GitHub Actions の例のように、軽量なスケジュール済みメンテナンスジョブを追加する
セッションが古くなった後の最初の Codex 実行で、auth.json が更新されます。
重要な運用ルール
- ランナーごと、または直列化されたワークフローストリームごとに 1 つの
auth.jsonを使用してください。 - 同じファイルを複数の並行ジョブや複数のマシンで共有しないでください。
- 永続ランナーの更新済みファイルを、実行のたびに元の初期設定ファイルで上書きしないでください。
auth.jsonをリポジトリ、ログ、または公開アーティファクトストレージに保存しないでください。- 組み込みの更新が機能しなくなった場合は、信頼できるマシンから再初期設定してください。
更新が機能しなくなった場合の対処
このフローは手作業を減らしますが、同じセッションが永久に継続することを保証するものではありません。
次の場合は、新しい auth.json でランナーを再初期設定してください。
- Codex が
401を返し始め、ランナーで更新できなくなった - リフレッシュトークンが失効または期限切れになった
- 別のマシンまたは並行ジョブが先にトークンをローテーションした
- セキュアストレージとの往復処理に失敗し、古いファイルが復元された
再初期設定するには、次の手順を実行します。
- 信頼できるマシンで
codex loginを実行します。 - CI/CD に保存されている
auth.jsonのコピーを置き換えます。 - 次のランナージョブで Codex の組み込み更新フローを引き続き使用します。
ランナーがセッションを維持していることを確認する
ランナーに ChatGPT 管理の認証トークンがまだ存在し、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ストレージを扱っています