セキュリティ●●○○○

APIキー

API Keyえーぴーあいきー

API呼び出し元を識別する簡易な資格情報。手軽さと漏洩リスクが表裏一体。

概要

APIキーは、API の呼び出し元を識別するために発行される長いランダム文字列です。サービスの管理画面で「キーを発行」を押すと sk-a1b2c3... のような文字列が得られ、以降のリクエストにこれを添えると、サーバは「このリクエストはあのアカウントのものだ」と判別できます。外部サービスのAPIを使ったことがあれば、ほぼ確実に最初に出会う資格情報です。

その最大の魅力は手軽さです。OAuth のようなリダイレクトの往復も、トークンの有効期限管理も要らず、発行された文字列をヘッダに付けるだけで使い始められます。一方でその手軽さは、「この1本の文字列さえあれば誰でもあなたとしてAPIを呼べる」という危うさと表裏一体です。APIキーは、利便性を最優先した最も素朴な資格情報である — この位置づけを理解することが、この語彙の核心です。

なぜ生まれたか

Web API が公開され始めた2000年代、提供者側には「誰が呼んでいるかを知りたい」という切実な事情がありました。完全に匿名のAPIでは、利用量の集計も課金もできず、暴走したクライアントを止めるレート制限も「全員まとめて」しかかけられません。かといって、機械同士の通信にユーザー名とパスワードを毎回送らせるのは筋が悪く、ユーザーの代理でアクセスするための委譲プロトコル(後の OAuth)は、そもそもまだ整備されておらず、「開発者が自分のプログラムから呼ぶ」という単純な用途には大げさでもありました。

そこで採られたのが、「開発者ごとにランダムな文字列を1本発行し、それを名札として付けてもらう」という最小限の仕組みです。提供者はキーごとに利用量を集計し、課金し、制限をかけ、悪用があればそのキーだけを無効化できます。Google Maps API などの初期の公開APIがこの方式を広め、以来「まずAPIキーを発行してもらう」は開発者体験の定番になりました。

詳細

識別なのか、認証なのか

APIキーを理解する上で重要なのが、「識別(identification)」と「認証(authentication)」の間のどこに位置するかという論点です。Google Maps のようにブラウザ側に埋め込む前提のキーは、実質的に「どのプロジェクトの利用かを仕分ける名札」であり、秘密として守れないため認証の役には立ちません。一方、サーバ側だけで保持する秘密のキーは「キーを知っていること」をもって呼び出し元を確かめる認証手段として機能します。ただしその場合でも、キーが表すのは通常「アカウントやプロジェクト」であって、操作している人間個人ではありません。「誰の権限で・何を許すか」をきめ細かく制御したい場面では、スコープと有効期限を持つ OAuth のトークンや、署名で改ざんを検知できる JWT、通信路ごと相互に証明する mTLS といった、より強い仕組みが選ばれます。

保証が強い・仕組みが重い手軽・保証は弱い公開キー型利用の仕分け・集計用の名札秘密キー型知っていること = 本人アカウント単位の認証漏れたら即なりすましOAuth / JWT / mTLSスコープと有効期限署名による検証短命トークンで被害を限定「識別の名札」から「認証の鍵」までの階段
APIキーの位置づけ — 手軽さと保証の強さのトレードオフ

使われ方の実際

典型的な流れはこうです。開発者がサービスの管理画面でキーを発行すると、サーバ側はそのハッシュ値(もしくは暗号化した値)をアカウントに紐づけて保存します(ハッシュで保存するのはパスワードと同じ理由で、データベースが漏れてもキー本体が流出しないようにするためです)。クライアントはリクエストのたびに Authorization: BearerX-API-Key といった HTTP ヘッダにキーを載せ、サーバは照合して呼び出し元を特定し、そのアカウントの権限・プラン・レート制限を適用します。キーは平文のまま送られるため、HTTPS が絶対の前提です。URL のクエリパラメータに載せる方式も歴史的には多用されましたが、アクセスログやブラウザ履歴にキーが残ってしまうため、現在はヘッダで送るのが原則です。

定番の事故 — リポジトリへのコミット

APIキーの事故として圧倒的に多いのが、ソースコードへの直書きと Git リポジトリへのコミットです。「後で消したから大丈夫」は通用しません。Git の履歴には過去のコミットがすべて残り、公開リポジトリは攻撃者のボットが常時スキャンしています。GitHub に AWS のアクセスキーを push すると数分以内に不正利用が始まり、暗号通貨の採掘で数百万円の請求が届いた — という事故は毎年のように報告されています。対策は多層的で、キーをコードでなく環境変数やシークレット管理サービスから注入する、コミット前にスキャンするツール(git-secrets、Gitleaks など)を CI/CD に組み込む、そして GitHub とプロバイダが連携してコミットされたキーを自動失効させる secret scanning に頼る、という組み合わせが現在の標準です。

ローテーションと運用設計

キーは「漏れるかもしれない」前提で運用します。核となる実践がローテーション(定期的・緊急時の交換)です。ここで効くのが、1アカウントに複数キーを併存させられる設計で、新キーを発行 → 利用側を順次切り替え → 旧キーの利用がゼロになったのを確認して失効、という手順なら無停止で交換できます。逆に1本しか持てない設計だと、交換の瞬間に必ず断が生じ、結果として「怖くて何年も替えられない」キーが生まれます。あわせて、キーごとに権限を絞る(読み取り専用キー、特定リソース限定キー)、接続元IPを制限する、利用状況をモニタリングして異常な呼び出しを検知する、といった多層防御を重ねるのが実務の型です。手軽に始められるのがAPIキーの美点ですが、本番運用に載せた瞬間から、それは立派な「秘密情報のライフサイクル管理」の対象になるのです。