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

71 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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/token``grant_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 claims`chatgpt_account_is_fedramp`、`chatgpt_plan_type` 参照)
3. **ヘッダ注入**: `HttpTransport``AuthRef::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.md``AuthRef` / `HttpTransport` 構造)
- `tickets/llm-scheme-openai-responses.md``/v1/responses` wire format