メインコンテンツへスキップ
鍵の置き場所:見せてよい鍵と、絶対に見せない鍵
レッスン 4 / 15|8分で読めます

鍵の置き場所:見せてよい鍵と、絶対に見せない鍵

anon keyとservice_role keyの決定的な違い、環境変数という金庫、デプロイ先での正しい鍵の渡し方。Moltbook事件を繰り返さないために。

第2回で見たMoltbook事件を、もう一度思い出してください。

150万件のAPIキーが漏れた事件。原因の一つは、万能鍵をガラス張りの場所に置いたことでした。

今回は、鍵の種類と置き場所を一枚の地図にします。

APIキーの超基礎、つまり「AIに鍵そのものを渡さない」「設定ファイルに直書きしない」は、Claude Code入門のAPIキー安全講座で扱いました。今回はその続き、公開するアプリでの鍵の運用です。

  • 同じ「キー」なのに、なぜ扱いが正反対なのか?
  • 環境変数って、結局どこにあるのか?
  • ローカルとデプロイ先で、なぜ二重に登録するのか?

この3つを解いていきます。

鍵には2種類ある

Supabaseを例にすると、プロジェクトには最初から2種類の鍵があります。

anon key(見られてよい鍵)

ブラウザ側のコードで使う前提の鍵。

例えるなら病院の入館証です。持っていれば建物には入れますが、カルテ庫は開きません。この鍵でできることは、前回かけたRLS(受付係)が全部チェックします。

だから、開発者ツールで見られても設計上は問題ない。ただしRLSが機能していれば、です。

service_role key(絶対に見せない鍵)

サーバー側だけで使う管理者鍵。

例えるならマスターキーです。RLSを素通しして、全テーブルを読み書きできます。受付係は、この鍵の前では仕事をしません。

これがブラウザに届いた瞬間、第3回で作った防御はすべて無効になります。置き場所は、次に説明する「環境変数」一択です。

第2回の3大事故のうち2つは、この表の右側の鍵が左側の場所に置かれたことで起きています。

鍵の強さと、置き場所の公開度は、反比例させる。 これが原則です。

環境変数は「サーバー側の金庫」

では「サーバー側に置く」とは、具体的にどうするのか。

答えが環境変数です。コードの外側にある入れ物に鍵を入れておき、コードには「金庫のこの引き出しを開けて」という指示だけを書きます。

// NG: 鍵そのものをコードに書く(ブラウザに届けば全公開、Gitにも残る)
const supabase = createClient(url, "eyJhbGciOiJIUzI1NiIs...");

// OK: コードには「引き出しの名前」だけを書く
const supabase = createClient(url, process.env.SUPABASE_SERVICE_ROLE_KEY);

ローカル開発では、この金庫の中身を .env というファイルに書きます(Vercelデプロイ回で登場済み)。.envGitに含めない。ここは次回の主役なので、予告だけしておきます。

視点

「NEXT_PUBLIC_」の意味を知っておく

Next.js製アプリでは、環境変数の名前が NEXT_PUBLIC_ で始まるものだけがブラウザに届きます。つまりこの接頭辞は「この変数は全世界に見せる」という宣言です。anon keyには付けてよく、service_role keyに付けたら事故。AIが書いたコードでこの接頭辞を見たら、「これは見せてよい値か?」と一度立ち止まる癖をつけてください。

デプロイ先には、デプロイ先の金庫がある

ここでつまずく人が多いポイントです。

ローカルの .env は、あなたのPCの中だけの金庫です。VercelやCloudflareにデプロイしたアプリは、あなたのPCを読みに来ません。だからデプロイ先のダッシュボードに、もう一度鍵を登録します。

場所金庫の名前特徴
自分のPC.env ファイルGitに含めない。ローカル開発用
VercelEnvironment VariablesSensitive指定にすると、登録後は値を誰も再表示できない
Cloudflare WorkersSecretsvarsと別枠。登録後は値が二度と見えない

VercelのSensitive指定やCloudflareのSecretsは、「登録した本人すら後から見られない」のが特徴です。不便に見えますが、これが正しい設計です。見る必要が出たら、元の発行元(Supabase等)で確認するか、新しい鍵に替えます。

明日のアクション

今日中にやる点検

  1. 自分のアプリのコードを service_role で検索し、フロントエンド側のファイルに出てこないことを確認する
  2. NEXT_PUBLIC_ 付きの環境変数を一覧にし、全部「見せてよい値」であることを確認する
  3. デプロイ先の環境変数登録で、秘密の鍵がSensitive(またはSecrets)になっているか確認する

今日のまとめ

3行で振り返ります。

  • 鍵には入館証(anon)とマスターキー(service_role)があり、扱いは正反対
  • 秘密の鍵はコードに書かず環境変数へ。NEXT_PUBLIC_ は「全世界に見せる」宣言
  • ローカルの .env とデプロイ先の金庫は別物。デプロイ先ではSensitive/Secrets指定を使う

次のレッスン

金庫の使い方は分かりました。残る大穴は、Gitの履歴です。うっかりコミットした鍵は、削除しても履歴に残る。次回は、混入を機械的に防ぐ仕組み(Push Protection)と、漏れてしまった日の正しい手順を覚えます。

参考・出典