# Codex CLIをSSH先・ヘッドレス環境でログイン：ブラウザなしの3経路

> ブラウザのないSSH先では--device-authのデバイスコード認証が第一候補です。使えなければ1455番ポートの転送かauth.jsonのコピーを選びます。

- URL: https://blog.laozhang.ai/ja/posts/codex-headless-login
- Published: 2026-10-02
- Updated: 2026-10-02
- Author: LaoZhang AI Team (https://blog.laozhang.ai/ja/about)
- Category: AI開発ツール
- Tags: Codex CLI, codex login, デバイスコード認証, SSH, auth.json

---
SSH接続先のサーバーやコンテナで`codex login`を実行すると、URLが表示されたまま先へ進みません。ブラウザのないマシンでChatGPTアカウントのままCodex CLIにログインする方法は3つあり、OpenAIが[認証ドキュメント](https://learn.chatgpt.com/docs/auth#login-on-headless-devices)で最初に勧めているのはデバイスコード認証です。

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

表示されたURLを手元のPCやスマートフォンのブラウザで開き、サインインして、ターミナルに出ているワンタイムコードを入力します。コードの有効時間は15分です。この方法はChatGPT側の設定でデバイスコードによるログインを有効にしておく必要があり、ワークスペースのアカウントでは管理者が許可していないと使えません。その場合は、SSHで1455番ポートを転送して通常のブラウザログインを通すか、ブラウザのあるマシンでログインして`~/.codex/auth.json`をコピーします。

以下の内容のうち、実際に動かして確かめた範囲と、そうでない範囲ははっきり分かれます。2026年10月2日にUbuntu 24.04（glibc 2.39、OpenSSH 9.6p1、Codex CLI 0.160.0）で実行して観察したのは次の5点です。

- ループバックアドレスの短縮表記`127.1`が、IPv4のループバックアドレスとして解決されること
- その表記を転送先にした実際の`ssh -L`が、IPv4のループバックだけで待ち受けるサーバーに通信を届けること
- 同じ形の転送が、`codex login`の起動したコールバック待ち受けに届くこと。認証情報を付けない素のリクエストには`400 Bad Request`と`State mismatch`が返りました
- 1455番が使用中のとき、`codex login`が1457番に切り替えて起動すること
- `codex login --device-auth`の表示文と、コードの有効期限が15分であること

これとは別に、同じ日に個人のChatGPTアカウント1つでデバイスコード認証を途中まで進めています。そのアカウントではデバイスコードログインの設定がオフで、ブラウザのページはコードの入力欄を出す前に止まり、設定を有効にしてコマンドを再実行するよう求めるメッセージが出ました。設定のスイッチがある場所と内容も、そのときの画面で見たものです。スイッチはオンにしておらず、コードも入力していません。

つまり、どの経路でもログインを最後まで完了させてはいません。ブラウザで承認したあとの画面、`auth.json`を別のマシンにコピーして使う場合の動作、トークンの更新と失効の挙動は試しておらず、これらはOpenAIのドキュメントとCodex CLI 0.160.0のソースコードに基づく説明です。Alpineなどmusl系の環境も未確認で、トンネルは両端が同じホストの構成で確かめたものです。

## `codex login`がSSH先で終わらない理由：コールバックが届かない

通常の`codex login`は、Codexを実行しているマシンの上に一時的なログイン用サーバーを立て、ブラウザで認証を済ませたあと、そのサーバーへ認証結果を戻してもらう仕組みです。ドキュメントは「サインイン後、ブラウザが認証情報をCodexに返す」と説明しています。

戻り先は、Codexが動いているマシン自身のループバックアドレスです。SSH先でURLをコピーして手元のPCのブラウザで開くと、サインインまでは進みますが、最後のリダイレクトは手元のPCのループバックアドレスに向かいます。そこでは何も待ち受けていないため、ブラウザは接続エラーになり、サーバー側のCodexは待ち続けます。

0.160.0のCLIも、この状況を前提にした案内を出します。ブラウザのないLinuxで`codex login`を実行すると、`Starting local login server on`に続けてループバックのホスト名と1455番のアドレスが表示され、次に`If your browser did not open, navigate to this URL to authenticate:`と`auth.openai.com`の認証用URLが出ました。ソースコードでは、そのあとに`On a remote or headless machine? Use codex login --device-auth instead.`という案内が続きます。

ドキュメントが通常のログインで失敗する場面として挙げているのは次の2つです。

- CLIをリモートまたはヘッドレスな環境で動かしている
- ローカルのネットワーク設定が、CodexがOAuthトークンを受け取るためのループバック宛てコールバックを遮断している

2つ目はブラウザのあるマシンでも起こります。WSLやVS CodeのRemote-SSHでコールバックが届かないという報告に対して、OpenAIはファイアウォールやVPNなどローカルのネットワーク構成が原因であることが多いとして、デバイスコード認証を案内しています（[issue #3927](https://github.com/openai/codex/issues/3927)、[issue #12263](https://github.com/openai/codex/issues/12263)）。

なお、0.160.0の`codex login --help`に出るログイン用フラグは`--with-api-key`、`--with-access-token`、`--device-auth`の3つだけです。コールバックのポートを指定するフラグや、ブラウザを開かないための`--no-browser`のようなフラグはありません。Codex CLI自体をまだ入れていない場合は、先に[Codex CLIのインストールと設定](https://blog.laozhang.ai/ja/posts/codex-cli-install)を済ませてください。

## どの経路を選ぶか：別端末・ポート転送・自動化で分かれる

判断に使う条件は4つです。ブラウザのある別の端末が手元にあるか、ChatGPTのセキュリティ設定を変えられるか、SSHのポート転送ができるか、操作するのが人か自動化か。

| 状況 | 使う経路 | 前提 | 気をつける境界 |
| --- | --- | --- | --- |
| 別の端末にブラウザがあり、ChatGPTの設定を変えられる | デバイスコード認証 | セキュリティ設定で有効化済み。ワークスペースは管理者の許可 | コードは15分で失効。ベータ扱い |
| 設定は変えられないが、手元のPCからSSHのポート転送ができる | 1455番ポートを転送して通常のログイン | 手元のPCにブラウザ。転送が禁止されていないこと | 1455が使用中なら1457に切り替わる |
| どちらもできない | 別のマシンでログインして`auth.json`をコピー | 認証情報がファイルに保存されていること | 1ファイル1マシン。元のマシンの再ログインで失効しうる |
| CIやスクリプトなど、人が操作しない | APIキー、`CODEX_API_KEY`、アクセストークン | APIの課金、または管理対象ワークスペース | ChatGPTプランの利用枠ではなくAPI料金になる |

上の3つはどれもChatGPTアカウントでのサインインで、プランに含まれる利用枠をそのまま使います。4つ目だけは認証の種類が変わり、支払いと使える機能も変わります。

![操作するのが人か、別端末のブラウザと設定変更が使えるか、SSHのポート転送ができるかの順に、APIキー、デバイスコード認証、1455番ポートの転送、auth.jsonのコピーへ分かれる判断図](https://blog.laozhang.ai/posts/ja/codex-headless-login/img/login-route-decision.webp)

## デバイスコード認証：`--device-auth`とコードの15分

サーバー側にブラウザもポート転送も要らないのがこの経路です。認証の結果をサーバーへ送り返す必要がなく、CLIの側からOpenAIへ問い合わせて完了を確認するためです。ドキュメントは「リンクをブラウザで開く」としか書いていませんが、この仕組みなら、ブラウザは手元のPCでもスマートフォンでも構わないことになります。

ドキュメントの手順は3段階です。

1. ChatGPTのセキュリティ設定でデバイスコードによるログインを有効にする。個人アカウントは自分で、ワークスペースは管理者が権限設定で行う
2. ターミナルで`codex login --device-auth`を実行する。初回起動の画面なら「Sign in with Device Code」を選ぶ
3. 表示されたリンクをブラウザで開いてサインインし、ワンタイムコードを入力する

設定の場所は、OpenAIのメンバーが[issue #2798](https://github.com/openai/codex/issues/2798)で示しています。個人アカウントは`chatgpt.com/#settings/Security`、ワークスペース管理者は`chatgpt.com/admin/permissions`です。個人アカウントのリンクを開くと、`chatgpt.com/settings/security`のアカウントのセキュリティとログインに関するページに着きます。

2026年10月2日時点の個人アカウントの画面では、スイッチはこのページの一番下、アプリのセキュリティに関するグループの最後の項目でした。ラベルは、Codex、Excel、PowerPoint、Word向けのデバイスコードログインを有効にする、という内容です。説明文には、デバイスコードはリモートやヘッドレスの環境でCodexにサインインするとき、またはExcel、PowerPoint、Wordの中のChatGPTにブラウザ経由でサインインするときに使うこと、デバイスコードはフィッシングに悪用されうるので決して他人に教えないことが書かれています。この画面は簡体字中国語の表示で見たもので、日本語表示での正確な文言は分かりません。以前のユーザー報告では、英語名は「Enable Codex Device Code Authorization」でした。Codex専用の名前を探すより、Officeアプリの名前が並んだデバイスコードの項目を探すほうが見つけやすいはずです。

ログインを始める前に、このスイッチの状態を確認してください。2026年10月2日に試したアカウントではオフでした。その状態で`codex login --device-auth`を実行し、すでにChatGPTにサインインしているブラウザで認証用のURLを開くと、アカウントの選択画面のあと、コードの入力欄が出る前に同意画面で止まりました。続行のボタンは押せない状態で、ChatGPTのセキュリティ設定でデバイスコードログインを有効にしてから`codex login --device-auth`をもう一度実行するように、というメッセージが出ました。これは1つのアカウントでの観察です。ドキュメントはこの設定の既定値を示しておらず、対象プランの記載もありません。スイッチをオンにしたあとの画面は見ていません。

0.160.0で`codex login --device-auth`を実行すると、`Follow these steps to sign in with ChatGPT using device code authorization:`に続いて、ターミナルに次の3つが出ます。ここまでは実際の表示で確かめた内容です。コードを入力する段階には進んでいないので、入力後の流れはドキュメントの説明によります。

- 認証用のURL：`https://auth.openai.com/codex/device`
- ワンタイムコードと「expires in 15 minutes」の注記
- 自分がCodexで始めたログインのときだけ続行し、Webサイトや他人から渡されたコードなら中止するように、という警告

最後の警告は読み飛ばさないでください。デバイスコードは、コードを入力した人のアカウントを、コードを発行した側の端末に結びつけます。自分で実行したのではないコードを入力すると、他人の端末に自分のアカウントでログインさせることになります。

ソースコードによると、15分以内に入力しなかった場合、CLIは`device auth timed out after 15 minutes`で終了します。もう一度実行すれば新しいコードが出ます。終わったら次のコマンドで確認します。

```bash
codex login status
```

認証情報がない状態では`Not logged in`と表示され、終了コードは1でした。ドキュメントとソースコードによれば、ChatGPTアカウントの認証情報が保存されていると`Logged in using ChatGPT`と表示され、終了コードは0になります。

`--device-auth`が安定版に入ったのは2025年10月3日の0.44.0で、ベータとして公式に案内されたのは2025年12月8日です。それより前に書かれた手順が`auth.json`のコピーだけを紹介しているのは、この経路がまだなかったためです。

ワークスペースでこの機能が無効になっていると、メンバーは利用できません。「Please contact your workspace admin to enable device code authentication」と表示されたというユーザー報告があります（[issue #9253](https://github.com/openai/codex/issues/9253)）。管理者に有効化を頼めない場合は、次の2つの経路に進みます。また、ログイン時に電話番号の確認を求められるアカウントでは、デバイスコード認証でもその確認は省略されないという報告が未解決のまま残っています。

## SSHのポート転送で通常のログイン：1455と予備の1457

手元のPCからポート転送ができるなら、通常のブラウザログインをそのまま使えます。サーバー側のログイン用サーバーが待ち受けるポートを、SSHのトンネルで手元のPCに引き出します。

手元のPCから、転送つきでサーバーに接続します。

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

そのSSHセッションの中で`codex login`を実行し、表示されたアドレスを手元のPCのブラウザで開きます。ドキュメントの説明どおりなら、認証後のリダイレクトは手元のPCの1455番に向かい、トンネルを通ってサーバー上のCodexに届きます。

![転送なしではリダイレクトが手元のPCの1455番で止まり接続エラーになる一方、ssh -Lで1455番を転送するとトンネルを通ってSSH先のCodexに届くことを比べた図](https://blog.laozhang.ai/posts/ja/codex-headless-login/img/ssh-port-forward-callback.webp)

転送先の書き方について補足します。OpenAIのドキュメントは転送先をループバックのホスト名で書いています。上のコマンドは同じ宛先を、IPv4ループバックアドレスの短縮表記である`127.1`で書いたものです。0.158.0（2026年9月28日）以降、Codexのログイン用サーバーはIPv4のループバックアドレスだけで待ち受けるようになりました（[PR #47927](https://github.com/openai/codex/pull/47927)）。ホスト名のほうはマシンによってIPv6が先に解決されることがあるため、IPv4を明示した書き方は待ち受け側の動作と一致します。

この書き方は、Ubuntu 24.04（glibc 2.39、OpenSSH 9.6p1）で次のところまで確かめられています。`getent ahosts 127.1`はIPv4のループバックアドレスを返しました。`codex login`を起動した状態で、転送先を`127.1:1455`と書いた`ssh -L`のトンネル越しに`/auth/callback`へ素のリクエストを送ると、`HTTP/1.1 400 Bad Request`と本文`State mismatch`が返り、トンネルを通さずに直接送った場合と同じ応答でした。OAuthのstateを持たないリクエストをCodexのコールバック処理が拒否した結果なので、この形の転送がCodex自身の待ち受けに届くことは分かります。ただし、分かるのはそこまでです。ブラウザでの承認を経てログインが完了するところまでは通していません。また、トンネルの両端が同じホストの構成だったので、別々のマシンの間のネットワーク経路は含まれていません。

転送先の解釈はサーバー側で行われます。Alpineなどmusl系の環境でこの短縮表記が通るかは未確認です。受け付けない環境では、OpenAIのドキュメントの書き方に置き換えてください。

ポートについては、ドキュメントとソースコードで情報の新しさが違います。

| 項目 | ドキュメントの記載 | 0.160.0のソースコード |
| --- | --- | --- |
| ポート | 既定は1455 | 1455固定。使用中なら1457に自動で切り替え（0.128.0、2026年4月30日以降）。0.160.0で実際に切り替わることを観察 |
| 待ち受けアドレス | ループバックのホスト名 | IPv4のループバックアドレスのみ（0.158.0以降） |
| ポートの変更 | 記載なし | フラグも設定キーもない。`mcp_oauth_callback_port`はMCPのOAuth専用 |

新しいのはソースコードのほうです。1457番への切り替えは[PR #19334](https://github.com/openai/codex/pull/19334)で入りました。この切り替えはソースコードの記述だけでなく、実際の動作でも確かめられています。1455番を別のプロセスで埋めた状態で`codex login`を実行すると、起動時の表示が1457番になりました。

ここから導ける注意点が1つあります。Codexが1457番で起動した場合、1455番だけを転送したトンネルにはコールバックが届かないはずです。これは挙動からの推論で、ドキュメントには書かれていません。`codex login`が表示したポート番号を見て、1457になっていたらそのポートを転送し直してください。最初から両方を転送しておく書き方も考えられます。次のコマンドは提案で、実行して確かめたものではありません。

```bash
ssh -L 1455:127.1:1455 -L 1457:127.1:1457 user@remote
```

ソースコードによると、両方のポートが使用中のときだけ、`Port … is already in use`で失敗します。前回の`codex login`が残っていないかを確認してください。

VS CodeのRemote-SSHやJetBrains Gatewayが行う自動のポート転送でこのログインが通るかどうかについて、OpenAIの公式な説明はありません。確実なのは、上のように自分で`ssh -L`を指定する方法です。

## `auth.json`をコピーする：1ファイル1マシンと再ログインの失効

デバイスコードも使えず、ポート転送も禁止されている環境では、ブラウザのあるマシンでログインを済ませ、保存された認証キャッシュをサーバーへ運びます。ドキュメントの手順は次のとおりです。

1. ブラウザのあるマシンで`codex login`を実行する
2. `~/.codex/auth.json`ができていることを確認する
3. そのファイルを、ヘッドレス側の`~/.codex/auth.json`にコピーする

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

`scp`が使えない場合の1行版もドキュメントに載っています。

```bash
ssh user@remote 'mkdir -p ~/.codex && cat > ~/.codex/auth.json' < ~/.codex/auth.json
```

Dockerコンテナへ入れる場合です。

```bash
CONTAINER_HOME=$(docker exec MY_CONTAINER printenv HOME)
docker exec MY_CONTAINER mkdir -p "$CONTAINER_HOME/.codex"
docker cp ~/.codex/auth.json MY_CONTAINER:"$CONTAINER_HOME/.codex/auth.json"
```

コピーしたあとは、サーバー側で`chmod 600 ~/.codex/auth.json`として自分だけが読めるようにしておきます。これはドキュメントにはない一般的な用心です。ドキュメントはこのファイルを「パスワードと同じように扱う」よう求めています。中身はアクセストークンなので、リポジトリにコミットしない、チケットに貼らない、チャットで共有しない、の3点です。

この経路には、手順より先に知っておくべき境界が3つあります。

**認証情報がファイルに保存されていること。** 保存先は設定`cli_auth_credentials_store`で決まります。値は`file`、`keyring`、`auto`、`ephemeral`の4つで、ドキュメントは既定値を明記していませんが、0.160.0のソースコードでは全OSで`file`です。`keyring`や`auto`に変えている場合、または管理者が保存先を指定している場合は、`auth.json`ができないことがあり、ドキュメントも「この方法は当てはまらないかもしれない」としています。環境変数`CODEX_HOME`を自分で設定している場合、ファイルの場所はそのディレクトリの直下になり、ディレクトリは事前に作っておく必要があります。

**1つのファイルは1台のマシンで使うこと。** 同じログインを2台のサーバーで使い回すことはできません。[CI/CD向けの認証ガイド](https://learn.chatgpt.com/docs/auth/ci-cd-auth)は「同じファイルを並行するジョブや複数のマシンで共有しない」と書いています。理由はトークンの更新にあります。Codexは使用中にトークンを自動で更新し、新しい値をファイルに書き戻します。同ガイドによると、更新が走るのは最後の更新からおよそ8日を過ぎたときと、401が返ったときです。2台が同じファイルを持っていると、先に更新した側が新しいリフレッシュトークンを受け取り、もう一方の手元には使用済みのトークンが残ります。OpenAIのメンバーは[issue #10332](https://github.com/openai/codex/issues/10332)で、リフレッシュトークンは1時間程度の限られた時間内なら再利用できるが、その後は完全に無効になると説明しています。2台がしばらく両方動いたあと片方だけ落ちるのは、このためです。サーバーが2台あるなら、それぞれで別々にログインします。

**元のマシンで再ログインやログアウトをすると、コピーが無効になりうること。** 2026年6月12日にマージされた[PR #27674](https://github.com/openai/codex/pull/27674)以降、`codex login`はブラウザ経由でもデバイスコードでも、開始前にそのマシンに保存されている認証情報を失効させてから消します。`codex logout`も同じく失効処理を行います。ここから先は推論で、ドキュメントに記載はなく、実際に試して確かめたものでもありません。サーバーにコピーした`auth.json`は元のマシンと同じトークンを持っているので、元のマシンで`codex login`をやり直したり`codex logout`したりすると、サーバー側のコピーも使えなくなる可能性があります。ソースコードでは、失効したリフレッシュトークンで更新しようとしたときのメッセージは次のとおりです。

```text
Your access token could not be refreshed because your refresh token was revoked. Please log out and sign in again.
```

これを避けるには、元のマシンでログインしてコピーしたあと、そのマシンでは再ログインもログアウトもしないことです。手元のPCでもCodexを使い続けるなら、コピーよりデバイスコード認証のほうが向いています。サーバーが自分でログインするので、手元のPCの認証情報と無関係になるためです。

## CIや自動実行はAPIキーかアクセストークン：課金が変わる

人が操作しない環境では、ChatGPTログインを持ち込むよりAPIキーを使うのが公式の推奨です。ドキュメントは「CI/CDジョブのようなプログラムからのCodex CLI利用にはAPIキー認証を使う」と書いています。ブラウザは要りません。

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

以前の`--api-key`フラグは廃止されていて、使うと`The --api-key flag is no longer supported.`と表示されて終了します。キーは上のように標準入力から渡します。

ただし、これはChatGPTプランをブラウザなしで使う方法ではありません。APIキーでの利用は標準のAPI料金で課金され、プランに含まれる利用枠は使われません。ChatGPTのワークスペースやクラウド側のサービスに依存する機能は制限されるか使えず、Codex cloudにはChatGPTでのサインインが必要です。どちらで払うべきかは[Codex APIキーとChatGPTサブスクの違い](https://blog.laozhang.ai/ja/posts/codex-api-key-vs-subscription)で比べられます。

非対話実行の`codex exec`は、既定では保存済みのCLI認証をそのまま使います。ログインせずにキーを渡したい場合は環境変数`CODEX_API_KEY`を使います。[非対話モードのドキュメント](https://learn.chatgpt.com/docs/non-interactive-mode)によると、この変数が使えるのは`codex exec`、`codex review`、TypeScript SDK、`codex exec-server --remote`です。対話型の`codex`は`CODEX_API_KEY`を読みません。また、環境変数の一覧に認証用として載っているのは`CODEX_API_KEY`と`CODEX_ACCESS_TOKEN`で、`OPENAI_API_KEY`を環境に置いただけでは`codex exec`の認証情報にはなりません。

管理対象のワークスペースには、もう1つの選択肢としてCodexアクセストークンがあります。ワークスペースのオーナーが権限を有効にしたうえで`chatgpt.com/admin/access-tokens`で発行し、有効期限は7日、30日、60日、90日から選べます。

```bash
printenv CODEX_ACCESS_TOKEN | codex login --with-access-token
```

対象プランの記載はOpenAIのページ間で食い違っています。認証ドキュメントは「ChatGPT Enterpriseワークスペース」、[アクセストークンのページ](https://learn.chatgpt.com/docs/enterprise/access-tokens)は「現在はChatGPT BusinessとEnterpriseのワークスペース」としています。Businessで使えるかどうかは、自分のワークスペースの管理画面で確かめてください。

どうしてもChatGPTアカウントの認証をCIで使いたい場合について、OpenAIは上級者向けの手順を用意しています。`auth.json`はファイルがないときだけ投入し、実行中の更新はCodexに任せ、更新後のファイルを次のジョブのために保存し、公開リポジトリでは使わない、という内容です。それでも自動化にはAPIキーが推奨のままです。

## ログインできないときのエラー文と`codex-login.log`

エラー文は原因をかなり具体的に示します。出どころの種類とあわせて整理します。

| 表示される文 | 出どころ | 意味と対処 |
| --- | --- | --- |
| `device code login is not enabled for this Codex server.` | ソースコード | デバイスコードの受付先が404を返した。ポート転送かファイルのコピーに切り替える |
| セキュリティ設定でデバイスコードログインを有効にして再実行するよう求める文。英語では Enable device code authorization for Codex in ChatGPT Security Settings という報告がある | ブラウザの同意画面で観察（個人アカウント1つ）。英語の文言はユーザー報告 | 設定がオフ。コードの入力欄は出ない。セキュリティ設定ページの一番下のスイッチを有効にして`codex login --device-auth`を再実行 |
| Please contact your workspace admin to enable device code authentication | ユーザー報告 | ワークスペースで無効。管理者に依頼するか別の経路へ |
| `device auth timed out after 15 minutes` | ソースコード | コードが失効。再実行して新しいコードを入力 |
| `Port … is already in use` | ソースコード | 1455と1457の両方が使用中。残っているログイン処理を終了する |
| `refresh token was revoked`を含む文 | ソースコード | 別の場所で再ログインかログアウトが行われた。ログインし直すか、コピーし直す |
| `refresh token was already used`を含む文 | ソースコード | 同じ`auth.json`を別のマシンやジョブが先に更新した。マシンごとにログインする |
| `ChatGPT login is disabled. Use API key login instead.` | ソースコード | 管理者が`forced_login_method`でAPIキーに限定している |
| `API key login is disabled. Use ChatGPT login instead.` | ソースコード | 逆に、ChatGPTログインに限定されている |

最後の2つは管理者による制限です。ドキュメントによれば、許可されていない方法でログインしていると、Codexはユーザーをログアウトさせて終了します。個人で回避する方法はなく、指定された方法に合わせることになります。

表にない失敗は、ログを見ます。`codex login`を直接実行したときのログは、既定では`~/.codex/log/codex-login.log`に書かれます。

社内のTLS検査プロキシや独自のルート証明書がある環境では、ログインの通信が証明書エラーで止まることがあります。その場合は、ログインの前にルート証明書を指定します。この変数がなければ`SSL_CERT_FILE`が使われ、ログインだけでなくHTTPSとWebSocketの通信にも適用されます。

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

ブラウザでの認証までは終わるのに、その後のトークン交換が403で終わる場合は原因が別にあります。[Codexのトークン交換が403で失敗](https://blog.laozhang.ai/ja/posts/codex-token-exchange-failed-403)で、ログイン・プロキシ・地域・認証キャッシュを順に切り分けられます。`codex login status`ではログイン済みなのに実行時に401が返る場合は、[Codexの401「Incorrect API key」](https://blog.laozhang.ai/ja/posts/codex-401-incorrect-api-key)の見分け方が当てはまります。

まとめると、最初に試すのは`codex login --device-auth`です。設定を変えられないなら1455番ポートの転送、それも無理なら`auth.json`のコピーで、コピーした場合は元のマシンで再ログインしないこと、1ファイルを1台だけで使うことの2点を守ります。どの経路でも、最後は`codex login status`の表示と終了コードで確かめられます。
