CLI 認証の正しい方法:4つの方法の完全ガイド
重要な4つの CLI 認証方式、その GitHub、AWS、および AI ツールによる実装方法、そして避けるべきセキュリティの落とし穴に関する解説。
重要な4つの CLI 認証方式、その GitHub、AWS、および AI ツールによる実装方法、そして避けるべきセキュリティの落とし穴に関する解説。
すべての開発者 CLI は最初のコマンドとして login を備えています。しかし、認証(auth)の仕組みは CLI ごとに異なります。
GitHub はコードを表示し、ブラウザを開いてその認証を求めます。AWS は PKCE ベースのSSO用にブラウザを開きます。Stripe はダッシュボードでペアリングコードの確認が必要です。新しい AI ツール(Claude Code、OpenAI Codex CLI、Cursor)もそれぞれ独自の方式を採用しています。
CLI を開発する際、認証は最初に考えるべき機能のひとつです。認証方式を誤れば、ユーザーの不満やセキュリティ監査につながることもあります。さらに、最近はプログラムから CLI ツールを呼び出す AI コーディングエージェントも登場しており、そのリスクはより高くなっています。いまや人間だけでなく、自律プロセスにも認証情報を渡す場面があるのです。
ここでは、重要な4つの認証方式、それぞれの主要ツールでの実装例、また避けるべき失敗例を解説します。
まずはざっくり比較表です。
| 方式 | 最適な用途 | セキュリティ | ブラウザは必要? |
|---|---|---|---|
| OAuth デバイスコードフロー | ヘッドレス環境, SSH | 高い | 不要(同じマシン上の場合) |
| ブラウザベース OAuth(localhost リダイレクト) | ローカル開発 | 最も高い | 必要 |
| API キー / PAT | オートメーション, CI/CD, プロトタイピング | 中程度 | 不要 |
| クライアントクレデンシャル | サービス間通信 | 高い | 不要 |
それぞれ一長一短があります。以下で順に詳しく解説します。
この方式では CLI が ABCD-1234 のようなコードと URL を表示し、任意のデバイスでその URL を開いてコードを入力してもらう仕組みです。
採用例: GitHub CLI(デフォルト)、Azure CLI(--use-device-code)、Vercel CLI(2025年よりデフォルト)、OpenAI Codex CLI(β機能)
cli login を実行client_id とスコープも送る)device_code(内部識別子)、user_code(ユーザー入力用短縮コード)、verification_uri(入力サイトのURL)最大の利点:どこでも使えること。リモートサーバーへの SSH セッションでも、Docker 内部でも、ローカルブラウザがない Cloud IDE でも動きます。ブラウザは CLI と同じマシンである必要がありません。
また、企業の認証(SAML、OIDC、MFA)にもフル対応(ブラウザ上で実施)。CLI がパスワード等に触れることはありません。
デバイスコードフローにはフィッシングリスクがあります。攻撃者は自分用にデバイスコードを発行し、被害者にコード入力させることで攻撃者セッションを正規認証させられます。この攻撃は現実に報告されており、AWS SSO デバイスコード認証でも確認されています。
これを受けて AWS はデフォルトを変更。AWS CLI v2.22.0 から aws sso login の初期フローは PKCE ベースの認証コードフローとなり、デバイスコードフローは --use-device-code 明示時のみ利用可となりました。
一方で、マイクロソフト自身のテナントでは条件付きアクセスでデバイスコードフロー自体を遮断し始めています。これは彼らが高リスクの認証方式と見なしている強いサインです。
こうして面白い分岐が起きています。Vercel は 2025年9月からデフォルトでデバイスコードフローを採用。一方 AWS はこれを避ける形です。本当にブラウザが開けない環境には有用ですが、ローカルでブラウザ利用可能なら PKCE の方が安全です。
また認証プロバイダー側の対応も進んでおり、Logto も v1.38.0 で OAuth 2.0 Device Authorization Grant をリリースしました(OSS & クラウドで利用可能)。RFC 8628 の正しい実装(コード有効期限、レート制限、ポーリング、UX設計など)は手間がかかるため、プロバイダー任せにできるのは大きなメリットです。
expires_in は認証サーバーが設定(RFC例は1800秒=30分、必須値ではない)interval が指定されない場合は 5秒 デフォルトslow_down エラー時は 5 秒追加開発者ローカルPC上で最も一般的なパターン。login でブラウザが開き認証、認証後は一時的ローカル HTTP サーバーにリダイレクトされてトークンをやり取りします。最新方式は必ず PKCE(読み「ピクシー」)を重ね、流出耐性を高めています。
採用例: Claude Code, gcloud CLI, Terraform CLI, AWS CLI v2.22+(SSO で PKCEデフォルト)
cli login を実行http://127.0.0.1:8742)http://127.0.0.1:8742/callback?code=XXXX&state=YYYY にブラウザがリダイレクトUX は「何も書かずクリックだけで完了」と非常に滑らかです。
CLI がブラウザを開いたり、localhost にバインドできない場合は不可:
多くのツールがデフォルトでブラウザ OAuth を使いつつ、代替手段としてデバイスコードフローや API キーサポートを提供しています。
落とし穴1:127.0.0.1 でなく 0.0.0.0 でバインドする
最もよくある重大ミス。全ネットワークでコールバックサーバーが公開されてしまい、だれでも認可コードを傍受可能。
多くの HTTP サーバーライブラリのデフォルトが 0.0.0.0 であるため、特に注意。
落とし穴2:state パラメータの検証不足
state パラメータは CSRF 対策です。これがないと攻撃者が偽セッションで認証コードを CLI に渡せます。
落とし穴3:PKCE を使わない
OAuth フローが PKCE(Proof Key for Code Exchange)を使っていないと、認可コードを傍受された場合にリプレイ攻撃が成立します。
PKCE では:
code_verifier を生成code_challenge を作成code_verifier を送信攻撃者は認可コードだけでは code_verifier を持たないため、トークン交換が不可能です。
これが AWS CLI v2.22+ で PKCE をデフォルト化した理由です。ローカルでブラウザが使えるならブラウザ OAuth + PKCE が最良の UX と最高セキュリティを両立。デバイスコード方式はどうしても同一マシンでブラウザが使えない場合(SSH、コンテナ、リモート開発など)向きです。
最も単純明快な方式。Web ダッシュボードでトークンを発行し、CLI 設定や環境変数に貼り付けて準備完了。
採用例: Stripe CLI(ログインオプション)、npm、pip、多くの AI コーディングツール(Claude Code= ANTHROPIC_API_KEY、OpenAI = OPENAI_API_KEY など)、Aider
sk_live_, ghp_, npm_)~/.config/stripe/config.toml、~/.aws/credentials)または環境変数へ保存CLI は起動時にこれを読み取り、APIリクエスト時の Authorization ヘッダーに Bearer トークンとして追加します。
自動化用途なら API キーは極めて便利。CI/CD やコンテナ、スクリプト、cron, あらゆる環境で環境変数から読み込めます。ブラウザ不要。インタラクティブなプロンプト不要。トークン更新不要。
特に AI エージェント用途では API キーが最短統合路。「Claude Code」や「Cursor」などが API を叩くとき、環境変数にAPIキーがあれば一発です。
最善策は「APIキー→短命な一時トークンに交換」して使うこと。
AWS の STS(Security Token Service)方式が代表例。長期クレデンシャルは一時クレデンシャル発行時のみ使用、1時間で失効。「aws-vault」などツールで自動化できます。
API キー運用でもこのパターン追加を検討しましょう。漏洩リスクが「気づくまで有効」→「1時間だけ」に大幅減します。
OAuth 2.0 のサービス間認証用フロー。人間不要、完全に自動化。
利用例: CI/CD パイプライン、バックグラウンドサービス、自動ツール
サービス自身の client_id と client_secret を認証サーバーへ送信し、短命アクセス・トークンを取得します。ブラウザやユーザー操作、リダイレクトは不要。
人間認証用途では利用しないでください。MFAやSSO等をサポートしません。
公式ドキュメント・ソースコードに基づく正確な一覧。
| CLI ツール | デフォルト方式 | フォールバック | トークン保存先 |
|---|---|---|---|
GitHub CLI (gh) | デバイスコードフロー(ブラウザ) | PAT(--with-token)、環境変数(GH_TOKEN) | OS キーチェーン(なければ平文ファイル) |
| AWS CLI v2 | PKCE 認証コードフロー(SSO) | デバイスコード(--use-device-code)、クレデンシャルファイル | ~/.aws/sso/cache/ |
Azure CLI (az) | WAM(Windows)、ブラウザ認証コード(Linux/macOS) | デバイスコード(--use-device-code) | ~/.azure/msal_token_cache.* |
| Vercel CLI | デバイスコードフロー (新デフォルト, 2025年9月) | API トークン(--token, 環境変数) | ~/.local/share/com.vercel.cli/auth.json |
| Stripe CLI | ブラウザベースペアリングフロー | API キー(--interactive, --api-key 或いは環境変数) | ~/.config/stripe/config.toml |
| gcloud CLI | ブラウザ OAuth | --no-browser 手動フロー | ~/.config/gcloud/ |
| Claude Code | ブラウザ OAuth | API キー(環境変数, apiKeyHelper) | OS キーチェーン / ~/.claude/.credentials.json |
| OpenAI Codex CLI | ブラウザ OAuth | デバイスコード(β)、API キー | ~/.codex/auth.json / OS キーリング |
| Terraform CLI | ブラウザ OAuth | トークン貼り付け | ~/.terraform.d/credentials.tfrc.json |
トレンドは明らかです:ローカル開発ではブラウザベース OAuth がデフォルト、ヘッドレス環境ではデバイスコードをフォールバック、CI/CD や自動化には API キーが採用。 PKCE が最も安全なオプションとして普及中です。
正しい認証設計も、保存がズサンならすべて台無しです。
各OSには暗号化クレデンシャルストア:
OS側で暗号化・アクセス制御・ハードウェア連携してくれるので、CLI が暗号処理を持つ必要なし。
キーチェーン未対応環境(コンテナ、最小 Linux 等)では、権限制限付きファイル保存推奨:
平文トークンファイル。 一見当たり前ですが、まだ多数のツールが実際に使っています。ユーザー権限の全プロセス・バックアップツールが読み取れます。
長期保存目的の環境変数。 環境変数はプロセス一覧で見えたり、クラッシュレポーターにログ出力されたりします。CI/CDでは(CI側が秘匿管理するため)OKですが、ローカル開発ではリスク大。
ブラウザ localStorage。 CLI に Web コンポーネントがある場合、トークンを localStorage に保存しないこと。XSS脆弱性=トークン流出となります。
短命運用を推奨(1時間が標準)。期限切れ時は CLI が自動更新すべきで、日常利用で再ログインは不要です。
長寿命の更新用クレデンシャル。新しいアクセス・トークン発行時に利用。攻撃価値が高いため最重要ターゲットでもあります(通常は数日〜数ヶ月有効)。
最新の認証システムはリフレッシュトークンを毎回ローテーションします:
これにより盗難時の影響を封じ込め。万が一盗まれたリフレッシュトークンが流用されてもサーバー側が検知し、トークンファミリー全体を無効化します。被害者と不正利用者両方で再認証が必要となり、攻撃者の持続利用を阻止。
前述と重複ですが再強調:127.0.0.1 固定、絶対に 0.0.0.0 は使わない。
想像以上によく発生しています。デバッグログやリクエストヘッダーのダンプ、サポート用の verbose モード等で表に出ます。
Docker イメージは秘密の保管場所ではない。全レイヤーが抽出可能。
途中で期限切れ→例外&クラッシュではなく、自動リフレッシュ or 再認証プロンプトにすべき。
本当に必要な範囲(例:repo:read)だけをリクエストしましょう。admin:* 等の広すぎる権限要求は厳禁。AI エージェントが CLI を使う場合、その原則はさらに重要です。
2026年のいま、CLI は人間のコマンド入力専用ではありません。Claude Code や Codex、Cursor の agent mode など、AI コーディングエージェントがプログラムから CLI ツールを叩いています。このことで新たな認証課題が生まれています:
権限委譲。 Claude Code が gh pr create を呼ぶとき、それは「あなたの」GitHub 認証情報を使います。しかし AI エージェントがあなたと同じ権限でよいのでしょうか?最小権限原則上 NG ですが、多くのツールはまだエージェント専用の権限分離機能を持ちません。
クレデンシャル漏洩リスク。 API キーが環境変数にある場合、全サブプロセスが参照可能で AI エージェントの子プロセスからも読めます。Claude Code など一部ツールは短命トークンを生成する apiKeyHelper スクリプトで改善済みですが、普及には至っていません。
エージェントのヘッドレス認証。 サンドボックス環境で動作する AI エージェントはブラウザを開けません。この場合デバイスコードフローが便利ですが、API キーは一切のユーザー操作不要のため、今はそちらが主流です。
監査ログと責任の所在。 AI エージェントに「あなた」名義の認証情報を渡すと、API の監査ログも「人間」と「エージェント」を区別できなくなります。現時点でこの識別方法は標準化されていません。
今後も進化必至の分野ですが、今できるベストプラクティス:
認証方式を選ぶときの簡易指針:
「ユーザーはローカルPCの開発者」 → PKCE付ブラウザOAuth(最良セキュリティ+スムーズUX)
「CLI が SSH 環境やコンテナでも動作する必要あり」 → ブラウザOAuthを基本、フォールバックにデバイスコード
「CI/CDなど人手無し自動実行」 → クライアントクレデンシャル or 権限制限APIキー
「最速実装だけが目的」 → API キー(後で必ずトークンローテーション追加を検討!)
「企業利用でSSOやMFAが必須」 → 任意OAuth方式(デバイスコード or ブラウザどちらもOK)、全エンタープライズ認証に対応
「AIエージェントにもCLI利用を想定」 → APIキー(エージェント統合目的)+ブラウザOAuth(人間用)の両対応、scope分離+短命トークンを組み合わせ
ほとんどの攻撃には十分安全ですが、フィッシング脆弱性があります。攻撃者がデバイスコードを発行してユーザーに認証させればセッション乗っ取りが可能。AWS が SSO のデフォルトを PKCE に移行した一因です。PKCE が現実的に使えないヘッドレス環境ではなお有力ですが、フィッシングリスクには留意。
CI/CD用途:OK(CI側が暗号化管理&ランタイム注入のため)。ローカル開発用途:NG。OSキーチェーン推奨。環境変数はプロセス一覧やログでどうしても漏洩リスクが高い。
ほとんど機能差なし。両者とも長寿命API認証情報。多くはプロジェクト/アプリ単位=APIキー、ユーザー紐付け型=個人用アクセストークンという分類。多くのサービスでは実質同義に扱われます。
アクセストークン:1時間以内ごとの自動更新。 リフレッシュトークン:毎回ローテーション(サーバー側で対応)。 APIキー:最低でも90日ごと、あるいは流出疑い即座更新。 実際にはインシデント後にしかAPIキーをローテーションしない組織も多いですが、本来は事前対応がベストです。
優先順位順で:
docker run -e API_KEY=${API_KEY} でCI/CD用)docker run -v ~/.config/tool:/root/.config/tool:ro)(ローカル開発用)絶対にイメージ内へのクレデンシャル埋め込みは避けてください。
MCPはAIエージェントが外部ツールやサービスに接続するための新標準です。ここでも新しい認証課題が生まれます:エージェント自身の MCP サーバー接続認証情報、さらにそのMCPから各種APIへの認証…。標準化は発展途上。現状ほぼAPIキーやOAuthトークンを MCP 設定ファイル経由で連携しています。今後急速に進化する分野です。
CLI認証は急速に進化中。2年前のベストプラクティス(デバイスコードデフォルトや平文ファイル保存)はすでに陳腐化しています。これから認証実装するなら人間向けはブラウザOAuth+PKCE、自動化にはAPIキー、いずれはAIエージェントが主要ユーザーになる日を見据えて設計してください。