# Codexのトークン交換が403で失敗する原因と対処：ログインの段階から切り分ける

> Codexのトークン交換403では、エラー末尾を残し、ブラウザの認証とCLI側の交換を分けて確認します。許可された対処を選び、同じ実行環境と認証方式で小さな作業が通るところまで確かめます。

- URL: https://blog.laozhang.ai/ja/posts/codex-token-exchange-failed-403
- Published: 2026-07-12
- Updated: 2026-10-06
- Author: LaoZhang AI Team (https://blog.laozhang.ai/ja/about)
- Topic: 開発ツールとエージェント
- Tags: OpenAI Codex, Codex CLI, トークン交換, 403 Forbidden, OAuth, ログインエラー

---
`Token exchange failed: token endpoint returned status 403 Forbidden` が出たら、まずエラーの末尾と、Codexを動かしている場所を確認してください。ブラウザでのサインインが終わっていても、Codex側のトークン交換が成功したとは限りません。ブラウザから結果が戻らないならコールバックを、交換時に403が返るなら応答本文と通信経路を調べます。本文に地域・アカウント・ワークスペースの制限が明記されている場合は、ローカル設定を変え続けず、公式の利用条件や管理者に確認します。

手元で復旧を試す順序は、**失敗した段階を特定する → その段階に関係する設定だけを直す → 元の環境でログインと小さな作業を確認する**、です。最初から認証ファイルを消す必要はありません。

![Codexのトークン交換403で確認する認証段階と対処の分岐](https://blog.laozhang.ai/posts/ja/codex-token-exchange-failed-403/img/cover.webp)

HTTPの403は「リクエストを理解したが、処理を拒否した」という意味です。[RFC 9110の定義](https://www.rfc-editor.org/rfc/rfc9110.html#section-15.5.4)は、認証情報以外の理由でも拒否されうること、同じ認証情報で自動的に再送すべきではないことを説明しています。403という番号だけでは、OpenAIの認証サービス、途中のプロキシ、別のサービスのどこが拒否したかも決まりません。

## エラーの末尾を残し、失敗した段階を見分ける

同じ「ログインできない」でも、対処する場所が違います。

| 実際に見える状態 | 調べる段階 | 次に確認すること |
| --- | --- | --- |
| ブラウザを開けない、または認証後もCLIが待ち続ける | ブラウザからCodexへのコールバック | ブラウザとCLIが同じホストか、SSH・WSL・コンテナを挟んでいるか |
| CLIが`token endpoint returned status 403 Forbidden`を返す | トークン交換のHTTP通信 | エラー全文、応答本文、実行ホストの通信経路、明示された拒否理由 |
| `error sending request`や証明書チェーンのエラーが出る | 通信の確立・TLS検証 | HTTP応答を受け取れたか、企業TLS検査と承認済みCAの有無 |
| ログイン後、最初の作業だけが401・403で止まる | 保存済み認証を使った作業 | 認証方式、選択したワークスペース、送信先とその利用権限 |

コールバックを受け取れない状態と、トークン交換で明示的に拒否された状態を混ぜないでください。また、証明書の検証エラーはHTTP 403そのものではありません。TLSを直した後で403が残った場合は、別の拒否理由を調べる段階に進んだことになります。

![ブラウザ認証、コールバック、トークン交換、認証情報の保存、小さな作業の5段階と、段階ごとの確認先を示す概念図](https://blog.laozhang.ai/posts/ja/codex-token-exchange-failed-403/img/auth-stages.webp)

ブラウザで本人確認を終える、Codexに認証結果が戻る、コードをトークンに交換する、認証情報を保存する、その認証で作業する、という順番で考えると判断しやすくなります。[公式の認証ガイド](https://learn.chatgpt.com/docs/auth)でも、ブラウザからCodexへ認証情報を戻す流れと、保存・ログ・ヘッドレス環境の対処は別々に説明されています。

### 同じ実行ホストで記録する情報

問題の起きたターミナルで、次を確認します。Windowsホストで得た結果を、WSL内の状態として扱わないでください。

```bash
codex --version
codex login status
```

バージョン、認証方式、OS、CLI・アプリ・IDE拡張のどれで起きたか、WSL・コンテナ・SSH先かを記録します。アプリやIDEで起きた問題なら、そのクライアントのアカウント表示と実行環境も確認します。別のターミナルのCLIが正常でも、そのアプリの状態はまだ分かりません。

`codex login status`の終了コードが0になるのは、[CLIリファレンス](https://learn.chatgpt.com/docs/developer-commands#codex-login)によると**認証情報が存在するとき**です。サーバーがその認証を受け入れたことや、作業が完了できることまでは証明しません。

エラーは最後の`403`だけでなく、直前の操作、短いエラーコード、秘密を除いた応答本文、時刻とタイムゾーン、request IDを一組で残します。`unsupported_country_region_territory`のような末尾があれば、消さずに記録してください。完全なコールバックURL、authorization code、device code、access/refresh token、Cookie、API key、認証情報付きのプロキシURLは共有しません。

## トークン交換の403では、応答本文から次の対処を選ぶ

明示的な交換403がある場合は、コールバック用のポートを変更するより先に、拒否理由を読みます。

| 応答やログの手がかり | 対処 | そこで止める条件 |
| --- | --- | --- |
| 社内のブロック画面、プロキシ名、block ID | ネットワーク担当者に認証先とCodex実行ホストの経路を確認してもらう | 組織の許可を得られない場合 |
| 証明書チェーンエラー、企業TLS検査の案内 | 配布元を確認した企業CAを設定し、TLS検証を有効なまま再試行する | CA配布や通信条件が確認できない場合 |
| `unsupported_country_region_territory`など地域の拒否 | 利用中の認証方式に適用される公式の地域条件を確認し、誤判定ならSupportへ渡す | 利用条件上、対象地域で認められていない場合 |
| 許可されない認証方式・ワークスペースの案内 | 管理者に許可された方法と対象ワークスペースを確認する | 管理側の制限が明示されている場合 |
| 理由の分からない403 | 実行環境とログを保存し、許可された修正を一つだけ行って結果を比較する | 修正後も同じ拒否が続き、新しい手がかりがない場合 |

HTMLに企業名があれば有用な手がかりですが、HTMLやJSONという形式だけで拒否元を断定はできません。途中のサービスが応答を変える場合もあるため、エラー本文にある送信先のホスト名とログの発生時刻を合わせて確認します。

[OpenAI Status](https://status.openai.com/)も、障害の掲載内容と確認時刻を記録する入口になります。関連障害が掲載されている間は、その案内に従ってください。正常表示だけを根拠に個別のアカウントや通信経路が正常だとは判断できません。発生時点の障害状況と利用資格は、公式情報と対象アカウントで確認してください。

### 地域を示すエラーが出たとき

地域の拒否が明記されている場合、認証情報の削除やデバイスコードへの変更を繰り返すのをやめます。ChatGPTサインインなら[ChatGPTの対応国・地域](https://help.openai.com/en/articles/7947663-chatgpt-supported-countries)、APIキー利用なら[OpenAI APIの対応国・地域](https://help.openai.com/en/articles/5347006-openai-api-supported-countries-and-territories)を、その時点の公式情報として確認してください。日本語で利用していること自体は、接続元地域やアカウントの利用資格を示しません。

利用条件を満たしているのに拒否される場合は、時刻、実行ホストの構成、認証方式、地域を示すエラーコード、request IDを[OpenAI Help Center](https://help.openai.com/)のサポートへ伝えます。会社の出口回線が関係する疑いがあれば、ネットワーク担当者にも経路を確認してもらいます。地域制限を回避するためのVPN変更や、他人のアカウントへの切り替えは復旧確認になりません。

## プロキシと企業CAは、Codex側の環境で確認する

ブラウザがWebサイトを開けることと、WSL・コンテナ・SSH先のCodexが認証エンドポイントへ通信できることは別です。Codexを起動したプロセスにどの設定が届いているかを確認します。

環境変数の有無だけを確認したい場合、Python 3があるターミナルでは次の補助コマンドが使えます。プロキシのURLやパスワード、キーの値は出力しません。

```bash
python3 - <<'PY'
import os

names = (
    "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "NO_PROXY",
    "http_proxy", "https_proxy", "all_proxy", "no_proxy",
    "CODEX_CA_CERTIFICATE", "SSL_CERT_FILE", "CODEX_HOME",
)
for name in names:
    state = "set" if os.environ.get(name) else "unset-or-empty"
    print(f"{name}: {state}")
PY
```

これは設定値の正しさや通信の成功を検査するものではありません。OSのシステムプロキシも表示しません。[公式変更履歴](https://learn.chatgpt.com/docs/changelog)には、ログインと起動時のリクエストにシステムプロキシのフォールバックを追加した記録があります。そのため「環境変数が空なら必ず直接接続」「Codexはシステムプロキシを一切使わない」とは言えません。利用中の版とOS、起動方法をそろえて管理者に確認します。

ローカルのコールバックと外向きの認証通信にも、別の経路があります。社内ルールに従い、ループバックの扱いと認証先への外向き通信を個別に確認してください。OpenAI関連ドメインを一括で`NO_PROXY`に加えると、必須の企業プロキシを外してしまう場合があります。

証明書チェーンのエラーがあり、企業TLS検査に必要なCAが正しく配布されている場合は、公式ガイドの次の設定を使えます。パスは管理者から受け取ったPEMファイルに置き換えます。

```bash
export CODEX_CA_CERTIFICATE="/path/to/corporate-root-ca.pem"
codex login
```

[カスタムCAの公式説明](https://learn.chatgpt.com/docs/auth#custom-ca-bundles)では、`CODEX_CA_CERTIFICATE`が未設定なら`SSL_CERT_FILE`を使い、ログイン・HTTPS・安全なWebSocket通信に同じCA設定が適用されます。証明書検証の無効化で通すのではなく、検証を有効なまま交換が通るかを確認します。HTTP 403だけがある場合に、根拠なくCAを入れ替える手順ではありません。

## ブラウザから戻れない場合は、公式の別のログイン経路を使う

![コールバック、証明書、ヘッドレス機への自分の認証転送、地域・ワークスペースの拒否を分け、許可された復旧経路を示す概念図](https://blog.laozhang.ai/posts/ja/codex-token-exchange-failed-403/img/safe-recovery.webp)

この分岐は、ブラウザとCodexが別のホストにある、またはローカルのコールバックが届かない場合に使います。地域・アカウント・管理ポリシーによる拒否を解除する方法ではありません。

### デバイスコード認証

[公式ガイド](https://learn.chatgpt.com/docs/auth#login-on-headless-devices)は、ヘッドレス環境やコールバックが使えない場合に、ベータのデバイスコード認証を第一候補にしています。個人アカウントではChatGPTのセキュリティ設定、管理ワークスペースでは管理者の権限設定で有効になっている必要があります。

```bash
codex login --device-auth
```

Codexを使うホストのターミナルで実行し、表示された公式リンクをブラウザで開き、同じターミナルに出たワンタイムコードを入力します。他人から渡されたコードは入力しません。設定が無効という案内なら、先に許可の確認が必要です。デバイスコードを選んでも、Codex側の外向き通信や利用資格が拒否されていれば成功しません。

### SSHでコールバックを転送する

自分が管理する、または接続を許可されたSSH先で通常のブラウザ認証を使うなら、手元のPCからコールバック用ポートを転送する方法も公式に案内されています。

```bash
ssh -L 1455:localhost:1455 user@remote
```

`user@remote`を対象のSSH接続先に置き換え、開いたSSHセッション内で`codex login`を実行します。そのターミナルが表示した認証URLを手元のブラウザで開きます。1455は公式ガイドの既定コールバック用ポートで、プロキシのポート番号ではありません。実際の待ち受けが別のポートなら、同じ転送指定をそのまま使うことはできません。

転送ができたことだけでログイン成功とはせず、Codex側の完了と後述の作業確認まで進みます。コールバックの待ち受けをインターネットへ公開する必要はありません。

### 自分の認証キャッシュをコピーできる条件

公式ガイドには、ブラウザのあるマシンでログインし、信頼できるヘッドレス機へ自分のファイル形式の認証キャッシュを転送する代替方法もあります。ただし、これは**自分のアカウント、許可された転送先、実在するファイル形式のキャッシュ**が前提です。OSの資格情報ストアに保存されている場合、この方法はそのまま使えません。

既定の`CODEX_HOME`を使い、公式に記載された`~/.codex/auth.json`がある場合の転送例は次のとおりです。

```bash
ssh user@remote 'mkdir -p ~/.codex'
scp ~/.codex/auth.json user@remote:~/.codex/auth.json
```

両方のホストで保存先が既定どおりかを先に確認します。独自の`CODEX_HOME`や管理側の保存要件がある環境へ、この例を無条件で使わないでください。`auth.json`にはトークンが入っているため、パスワードと同じ扱いが必要です。転送した内容をログやIssueに貼らず、複数のマシンで使い回す運用は[公式のCI/CD認証ガイド](https://learn.chatgpt.com/docs/auth/ci-cd-auth)で更新・保管条件を確認してから判断します。コピーできても、転送先の通信拒否が直った証拠にはなりません。

## 認証情報を作り直す前に、保存方式と組織の制限を確認する

認証情報が古いという案内があり、許可された方式でサインインし直せる場合は、ファイルを手で探して削除するより、公式コマンドで保存済み認証を消して入り直します。

```bash
codex logout
codex login
```

この操作は現在のログインを解除します。CLIとIDE拡張はログイン情報を共有するため、片方でログアウトするともう片方も再ログインが必要になります。[認証キャッシュと保存方式の説明](https://learn.chatgpt.com/docs/auth#credential-storage)によると、保存方式は`file`、`keyring`、`auto`、`ephemeral`で異なります。`file`は`CODEX_HOME`配下の`auth.json`、`keyring`はOSの資格情報ストア、`auto`は利用可能な保存先を選択し、`ephemeral`は現在のプロセス内だけに保持します。「認証は必ず`~/.codex/auth.json`にある」と考えて全ディレクトリを削除しないでください。

ChatGPTのトークンは通常、利用中に自動更新されます。403だけを理由に毎回ログアウトする必要はありません。また、プロセスの環境がワークロードID（workload identity）を選択している場合、公式ガイドでは`codex login`と`codex logout`が拒否されます。人のログインキャッシュではなく、環境を管理する担当者に確認します。

管理ワークスペースでは、[ローカル認証の管理要件](https://learn.chatgpt.com/docs/enterprise/managed-configuration#manage-authentication-locally)が認証情報の読み込みより先に適用されます。`allowed_login_methods`、`allowed_chatgpt_workspaces`、保存方式、サービスURLの制限は、キャッシュを消しても上書きできません。選べるワークスペースが許可リストに含まれなければChatGPTサインインは利用できず、API認証も許可されている場合に限ります。期待したアカウントやワークスペースを選べないときは、管理者の修正後に同じ対象で再確認します。

### APIキーへの切り替えは、元のログインの修復とは別です

APIキーの使用が許可され、OpenAI Platformの課金を承知してローカル作業を続けるなら、公式に別の認証方法があります。既に安全に環境変数へ設定した、自分のキーを標準入力で渡します。

```bash
printenv OPENAI_API_KEY | codex login --with-api-key
```

[公式認証ガイド](https://learn.chatgpt.com/docs/auth#sign-in-with-an-api-key)では、APIキー利用はPlatformの標準API料金で、ChatGPTプランの利用枠とは別です。Codex cloudにはChatGPTサインインが必要で、一部の機能や適用ポリシーも変わります。キーをコマンドの引数や公開ログに書かないでください。

APIキーで作業が通っても、ChatGPT側のトークン交換403が直ったとは言えません。切り替えが目的に合うかは、[CodexのAPIキーとChatGPTサブスクで変わる課金経路](https://blog.laozhang.ai/ja/posts/codex-api-key-vs-subscription)を確認します。組織の制限や地域条件を回避するための切り替えは行いません。

## 復旧は、同じホスト・認証方式・作業で確かめる

ブラウザの成功画面や`codex login status`の0だけで終わらせず、次の順に確認します。

1. **問題が起きたホストでログインが完了する。** SSH先で失敗していたなら、手元のPCだけの成功では不十分です。
2. **期待した認証方式と対象である。** CLIなら`codex login status`、アプリやIDEなら対象クライアントのアカウント表示を確認します。ChatGPTなら元のアカウント・ワークスペース、APIなら元の送信先・設定をそろえます。
3. **小さな作業で応答を受け取れる。** 機密ファイルを含まない作業用ディレクトリで、同じクライアントから「ファイルを変更せず、`AUTH_OK`とだけ返してください」と依頼します。これは認証済みリクエストが通るかの確認で、利用枠やAPI料金の対象になる場合があります。
4. **元の用途で必要な機能を確認する。** 短いテキスト応答だけでは、クラウド機能、ツール実行、長い作業がすべて使えるとは限りません。

途中で401・403が出た場合は、その新しいエラーを別の段階の失敗として記録します。ログイン後の`Incorrect API key`なら[Codexの401をURLと認証方式で見分ける手順](https://blog.laozhang.ai/ja/posts/codex-401-incorrect-api-key)、独自プロバイダーでの送信先やキーの不一致なら[Codexのカスタムプロバイダー設定](https://blog.laozhang.ai/ja/posts/codex-config-toml)が次の確認先です。後者のエラーを、OpenAIのOAuth交換403として扱い続けないでください。

なお、認証先へのHEADリクエストやダミーPOST、モデル一覧の応答は、実際のOAuthコード交換が成功した証明にはなりません。診断用の通信が通ることと、元の認証・作業が通ることは区別します。ここに記載したログイン・転送・API認証のコマンドは公式手順に基づく例で、読者の環境でログイン完了を実測したものではありません。環境変数確認の補助コードは、通信せずに構文を確認しています。

## 同じ拒否が続くときは、変更した点と結果をサポートへ渡す

地域・アカウント・ワークスペース・組織ポリシーの拒否が明示された場合は、その条件を管理する窓口へ移ります。それ以外でも、根拠のある修正を一つ行い、元の環境で同じ拒否が続いて新しい手がかりがなければ、設定変更を増やすよりログを渡すほうが有用です。

直接`codex login`を実行した場合、[公式ガイド](https://learn.chatgpt.com/docs/auth#login-diagnostics)は、設定されたログ用ディレクトリの`codex-login.log`を診断に使うよう案内しています。保存先を確認し、必要なエラー周辺を秘密情報を除いて共有します。全ログや`auth.json`をそのまま添付しないでください。

```text
発生日時とタイムゾーン: <実際の日時>
クライアントとバージョン: <CLI / アプリ / IDE、版>
実行環境: <ホスト / WSL / コンテナ / SSH先>
認証方式と対象: <ChatGPT / API、対象ワークスペース>
失敗した段階: <コールバック / 交換 / 保存 / 作業>
エラー: <全文から秘密情報を除いたもの>
応答: <短いコード、request ID、秘密を除いた本文>
通信経路: <直接 / 承認済みプロキシ / 企業TLS検査 / 不明>
変更した点: <一つの修正>
再確認の結果: <同じ403 / ログイン完了 / 小さな作業も成功>
```

企業ブロックの手がかりがあればネットワーク担当者へ、認証方式やワークスペースの制限なら管理者へ、説明できないアカウント側の拒否なら[OpenAI Help Center](https://help.openai.com/)へ渡します。コールバックURL、トークン、キー、Cookie、プロキシの認証情報は、この記録にも含めません。

## よくある質問

### ブラウザではログイン成功なのに、Codexで403になるのはなぜですか？

ブラウザでの本人確認と、Codex側のトークン交換は別の段階だからです。CLIが待ち続けるならコールバック到達、交換403が明示されるなら応答本文とCodex実行ホストの通信を確認します。ブラウザの画面だけでは、Codexが認証情報を保存できたかも分かりません。

### デバイスコード認証に変えれば403は直りますか？

コールバックが届かない問題には使える選択肢ですが、すべての403には効きません。[公式のヘッドレス認証手順](https://learn.chatgpt.com/docs/auth#login-on-headless-devices)が前提とする設定・管理者の許可が必要で、外向き通信、地域、アカウントや組織の拒否は別に確認します。

### `auth.json`を削除すればいいですか？

最初の対処にはしません。保存先はファイルとは限らず、組織の制限や通信拒否は消しても変わりません。再ログインが必要という根拠があり、許可された認証方式で入り直せる場合に、`codex logout`と`codex login`を使います。workload identityが選ばれている環境では、そのコマンドではなく環境の管理者が確認します。

### `codex login status`が0なら復旧済みですか？

いいえ。[CLIリファレンス](https://learn.chatgpt.com/docs/developer-commands#codex-login)では、0は認証情報の存在を示します。同じホスト、元の認証方式・ワークスペースで、小さな認証済み作業が成功したことまで確認してください。APIキーに切り替えて成功した場合は、ChatGPTの交換403が修復された証拠にはなりません。

## 参考資料

本文で参照している外部ページを、登場順に並べています。最終更新日：2026-10-06。

- [RFC 9110の定義](https://www.rfc-editor.org/rfc/rfc9110.html) (rfc-editor.org)
- [公式の認証ガイド](https://learn.chatgpt.com/docs/auth) (learn.chatgpt.com)
- [CLIリファレンス](https://learn.chatgpt.com/docs/developer-commands) (learn.chatgpt.com)
- [OpenAI Status](https://status.openai.com/) (status.openai.com)
- [ChatGPTの対応国・地域](https://help.openai.com/en/articles/7947663-chatgpt-supported-countries) (help.openai.com)
- [OpenAI APIの対応国・地域](https://help.openai.com/en/articles/5347006-openai-api-supported-countries-and-territories) (help.openai.com)
- [OpenAI Help Center](https://help.openai.com/) (help.openai.com)
- [公式変更履歴](https://learn.chatgpt.com/docs/changelog) (learn.chatgpt.com)
- [公式のCI/CD認証ガイド](https://learn.chatgpt.com/docs/auth/ci-cd-auth) (learn.chatgpt.com)
- [ローカル認証の管理要件](https://learn.chatgpt.com/docs/enterprise/managed-configuration) (learn.chatgpt.com)
