APIキーを環境変数に入れれば安全?公開用JavaScriptで確かめる
APIキーをコードから環境変数へ移しても、その値を公開用JavaScriptに埋め込めば、利用者に届きます。架空の文字列を使ってビルドすると、圧縮後のファイルにも値が残りました。秘密のキーをサーバー側で扱う理由を、この出力から見ていきます。
ビルド時に置き換えると、値は公開ファイルに残る
ここで扱うのは、サービスの呼び出しや課金に使う秘密のAPIキーです。実験では、本物のキーを使わず、DEMO_ONLY_NOT_A_REAL_KEY_20261024 という架空の値を用意しました。
元のブラウザ用コードは次の1行です。
globalThis.demoKey = process.env.DEMO_AI_KEY;esbuildの define でこの環境変数の参照を架空の値へ置き換え、圧縮して出力しました。生成されたJavaScriptには、その値が文字列として残りました。変数の置き場所を変えても、配信するファイルへ値を入れる処理なら、利用者が取得できます。
| 条件 | 生成JSに架空値が残るか | VMで実行した結果 |
|---|---|---|
| ブラウザ用・ビルド時に値へ置換 | 残る(67 bytes) | 値を取得できた |
| ブラウザ用・置換なし | 残らない(55 bytes) | processがなくReferenceError |
| サーバー用・実行時に値を読む | 残らない(104 bytes) | {"configured":true}を出力 |
置き換えをしないブラウザ用コードでは、ファイルに架空の値は入りませんでした。ただし、process のない実行条件では ReferenceError になりました。「値が含まれない」ことと「ブラウザで動く」ことは別です。
サーバーは、キー自体を返さずに処理する
3つ目の条件では、サーバー用コードが実行時に値を読む形にしました。今回の簡単な処理は、値が設定されているかを {"configured":true} と出力するだけです。ビルドしたコードにも、その出力にも架空の値そのものは入りませんでした。
実際のWebアプリでは、ブラウザから自分のバックエンドへ依頼を送り、バックエンドが秘密のキーを使ってAIサービスを呼び出します。APIキーは、アプリやプロジェクトを識別・認証する情報の一つです。どの権限を持つかは、サービスの仕様と設定によります。
検証範囲と再現ファイル
2026年10月24日JSTに、AIアシスタントがLinuxサーバーCPU、Node.js v22.23.3、esbuild 0.28.2で実行しました。実際に生成されたJavaScriptを調べた結果です。
コードの実行確認はNode.jsのVMで行いました。ブラウザ用にはprocessを渡さず、サーバー用には架空値だけのenvオブジェクトを渡しています。実ブラウザ、HTTPサーバー、AI API、実際の秘密値は使っていません。この比較だけで本番環境全体の安全性を確認したことにはなりません。
キーを隠すことに加え、誰が呼べるかを決める
秘密のキーを返さなくても、バックエンドが誰からでも無制限に依頼を受け付ければ、利用量や料金は増えます。利用者の認証、入力の長さ、呼び出し回数、利用量の記録を、サービスの用途に合わせて決めます。
CORSの設定だけで、あらゆるクライアントからの呼び出しを防げるわけではありません。実行する操作やデータへのアクセスも、サーバー側で判断します。権限の分け方は本番権限の記事で扱っています。
Gitやログにもキーを残さない
設定ファイルをGitの管理対象にしないようにしても、すでにコミットした内容は別に確認します。.gitignoreに書いても残る場合の手順では、手元のファイルを残して追跡から外す方法を説明しています。
ログへヘッダーや環境変数を丸ごと出すと、そこにも値が残る場合があります。障害を調べるときは、今回の configured のように、必要な状態だけを記録する方法を検討します。
漏えいしたキーは、削除より先に無効化・交換する
本物の秘密キーを公開した場合は、そのキーを停止し、新しいキーへ切り替えます。コードやGit履歴を直しても、すでに複製された値は回収できません。利用履歴と請求も確認し、どこから公開されたかを調べます。
手元からファイルを消す操作と、サービス側でキーを無効にする操作は別です。操作方法は、発行元の公式手順で確認してください。
キーを置く場所を選ぶ
APIキーの置き場所を選ぶ
サーバーで使う秘密のAPIキーを、どこへ置きますか? 実際のキーは入力しません。
選択すると、理由を確認できます。
実験を再実行する場合は、ファイル一式を展開し、npm ci の後に node run-key-lab.mjs results-local を実行します。初回はライブラリの取得に通信が必要ですが、AI APIの呼び出しはありません。実際のキーを入力せず、そのままの架空値で試せます。
参照した公式資料
- esbuild:define
ビルド時の定数置換。
- Google Cloud:APIキー管理のベストプラクティス
クライアントコードへの埋め込みやリポジトリへの登録を避ける。
- MDN:CORS
ブラウザのオリジン間通信とアクセス制御。
- 架空値のビルド実験
3条件の生成ファイルとVM実行の結果。
確認日:2026年10月24日。