yoi/tickets/llm-auth-codex-oauth.md

4.4 KiB
Raw Blame History

Codex OAuth 認証の流用

背景

決定済み方針(docs/plan/llm_providers.mdで、ChatGPT サブスクリプションの OAuth トークンを流用して OpenAI Responses API を叩く経路を第一級サポートとする。OpenAI は Codex CLI を Apache-2.0 で公開し、ChatGPT OAuth の第三者ツール利用を service terms で名指し禁止していない(互換経路)。

Codex CLI の実装github.com/openai/codex、codex-rs/login/ 配下)から以下が確定:

  • トークンは ~/.codex/auth.json{ auth_mode, tokens: { id_token, access_token, refresh_token, account_id }, last_refresh } 形式で保存
  • リクエストは https://chatgpt.com/backend-api/v1/responses に投げるResponses API wire
  • 認証ヘッダは Authorization: Bearer <access_token> + ChatGPT-Account-ID: <account_id>+ FedRAMP 組織で X-OpenAI-Fedramp: true
  • リフレッシュは https://auth.openai.com/oauth/tokengrant_type=refresh_token, client_id=app_EMoamEEZ73f0CkXaXp7hrann, refresh_token を POST

要件

  1. AuthRef::CodexOAuth の追加: llm-model-config で定義する認証列挙型に ChatGPT OAuth バリアントを追加

  2. トークン読み取り: ~/.codex/auth.json を読み、以下を取り出す

    • tokens.access_token
    • tokens.refresh_token
    • tokens.account_id
    • last_refresh(期限判定用)
    • tokens.id_token の JWT claimschatgpt_account_is_fedrampchatgpt_plan_type 参照)
  3. ヘッダ注入: HttpTransportAuthRef::CodexOAuth を解決するとき以下を組み立てる

    • Authorization: Bearer <access_token>
    • ChatGPT-Account-ID: <account_id>
    • FedRAMP 組織なら X-OpenAI-Fedramp: true
  4. base_url の自動適用: ModelConfig.base_url 未指定時は https://chatgpt.com/backend-api を既定とする。ユーザーが明示的に https://api.openai.com を指定した場合は尊重API key 経路と共用したいケース用)

  5. トークンリフレッシュ:

    • https://auth.openai.com/oauth/token{ client_id: "app_EMoamEEZ73f0CkXaXp7hrann", grant_type: "refresh_token", refresh_token } を POST
    • 有効期限が近いaccess_token が期限切れ or 残り時間が閾値以下)とき自動更新
    • 更新後の token を ~/.codex/auth.json に書き戻す
    • 複数プロセスCodex CLI との並行実行等)を想定した排他制御
  6. scheme/openai_responses との組合せで動作: ModelConfig { scheme: OpenAIResponses, base_url: (既定), model_id: "gpt-5-codex" 等, auth: CodexOAuth } で ChatGPT 枠を使って Codex 相当の動作ができる

  7. 完了時の動作: ChatGPT アカウント保持者が codex login 済みの環境で insomnia を起動すると、追加設定なしで Codex と同じモデル(gpt-5-codex 等)が利用可能

設計課題

1. auth.json の書き戻しと競合制御

~/.codex/auth.json は Codex CLI と共用。両方が並行動作する場面で refresh token が古い値で上書きされると再認証が必要になる。ファイルロックを取るか、更新前に再読み込みして最新値で書くか。

2. refresh token の失効時の挙動

refresh token も失効するケースAnthropic のサーバ側遮断のようにサブスク側が塞ぐケースで、ユーザーにどう通知するか。insomnia CLI で codex login の再実行を促すメッセージを返す。

3. ChatGPT OAuth 専用モデル

gpt-5-codex / codex-mini-latest 等、ChatGPT backend でのみ利用可能なモデル ID がある場合、API key 経路と区別が必要。ModelCapability で「CodexOAuth でのみ有効」フラグを持つか、API 側の 401 を受けて動的にフォールバックするか。

4. セキュリティと権限

~/.codex/auth.json のパーミッション600を尊重。読み取り時にパーミッション確認 + 書き込み時にパーミッション再設定。

Scope 外

  • Claude Pro/Max OAuth 経路(方針上非採用)
  • claude -p CLI fork 経路
  • codex login 自体の実装Codex CLI に任せ、insomnia は auth.json を読むのみ)
  • ChatGPT backend の rate limit 観測Retry-After 処理は HttpTransport 共通の責務)

依存

  • tickets/llm-model-config.mdAuthRef / HttpTransport 構造)
  • tickets/llm-scheme-openai-responses.md/v1/responses wire format