この記事の目次
AIと一緒に、文章を短くまとめるアプリを作っている。画面ができて、次はAIサービスにつなぐところ。そこで、こんな案内が出てきました。
APIキーを取得して、
.envファイルに設定してください。
言われたとおりに入れたら、動いた。けれど、これでよいのでしょうか。
「.envなら外から見えない?」「公開するときも同じ設定でいい?」「AIにキーを渡して設定してもらう?」。初めてなら、ここで迷うのは自然です。
この記事は、AIに手伝ってもらいながらWebアプリを作り、初めて外部サービスのキーを設定する人に向けたものです。小さな要約アプリを例に、キーの種類、置き場所、公開前の確かめ方を順に見ていきます。

こんなところで、迷っていませんか?
「APIキーを設定して」
と言われたけれど……
どこに書く?
公開するときも、このまま?
先に一つだけ。「どのファイルに書くか」の前に、そのキーを誰に見せてよいかを確かめます。 それが分かると、設定する場所も選べるようになります。
そのキーは、何を許可するもの?
APIは、アプリから別のサービスに処理を頼むための窓口です。今回なら「この文章を要約して」と頼む窓口。APIキーは、その呼び出し元を識別したり、利用を許可したりするための値です。
ただし、「APIキー」という名前でも、役割は同じではありません。
例えばSupabaseには、ブラウザで使うことを想定した公開用のキーと、サーバー側だけで使う秘密のキーがあります。公開用のキーを使う場合も、利用者ごとにどのデータを読めるかは別に制御します。「公開用だから、データの設定を気にしなくてよい」という意味ではありません。Supabase公式:APIキーの種類
ブラウザでの使用を、提供元が認めている。
データへの権限設定は、別に必要。
利用者へ配るコードに含めず、管理する側で使う。
今回の要約アプリで扱うのはこちら。
最初にサービスの管理画面と公式の説明で、次の二つを見ます。
- 用途:ブラウザで使ってよいキーか、サーバー専用か。
- 権限:何を読めるか、変更できるか。料金が発生する処理を呼べるか。
今回の要約アプリでは、利用すると開発者の契約に料金が発生する、サーバー専用の秘密のキーを使うとします。これは架空の教材例です。自分のサービスのキーも同じ種類だと決めつけず、説明を確かめてください。
種類が分からなければ、値を貼らずに「サービス名」「管理画面にあるキーの種類の名前」「公式説明のURL」をAIや開発を手伝う人に伝えれば、確認を進められます。
画面を作るコードは、利用者にも届く
要約アプリのボタンを動かすには、利用者のブラウザへJavaScriptというプログラムを送ります。ブラウザはそれを読み、「ボタンを押したら要約する」という動作を実行します。
ここで気をつけたいのは、画面に文字として出していなくても、ブラウザに渡したプログラムの中身は調べられることです。
次は、ブラウザで動くコードに秘密のキーを直接入れてしまった例です。キーは教材用のダミー、URLは実在のAPIにつながらない例示用です。実行する必要はありません。
// ブラウザで動くコードに、秘密のキーを入れてしまった例
fetch('https://api.example.invalid/summarize', {
method: 'POST',
headers: {
Authorization: 'Bearer DEMO_SECRET_DO_NOT_USE',
},
});
Authorizationは、サービスに利用資格を伝えるための通信の項目です。このコードでは、その値を組み立てるために、ブラウザが秘密のキーを知る必要があります。
要約ボタンと、要約の結果。
キーの文字は表示していない。
ボタンを動かすコードと通信。
中にキーがあれば、そこから読める。
入力欄をパスワード表示にしたり、画面からキーの文字を隠したりしても、この構造は変わりません。利用者に渡すコードや通信に秘密のキーが入っていれば、そこから読み取られる可能性があります。
「.envに移したから大丈夫」とは限らない
.envは、設定値をまとめて書くファイルとしてよく使われます。例えば、こう書きます。
# どちらも教材用のダミー。実際のキーへ置き換えないでください。
VITE_SUMMARY_KEY=DEMO_PUBLIC_12345
SUMMARY_API_KEY=DEMO_SERVER_67890
一見、どちらも同じファイルの中です。でも、アプリを作る仕組みによっては、名前の付け方でブラウザへ渡す値が決まります。
Viteという開発ツールでは、標準設定でVITE_から始まる変数をブラウザ側のコードで参照できます。その値は、公開用のファイルを作る処理にも組み込まれます。Viteは、秘密をこの変数へ入れないよう案内しています。Vite公式ガイド
VITE_SUMMARY_KEY
DEMO_PUBLIC_12345
ビルド:公開用ファイルを作る
参照した設定値がコードに入る。
DEMO_PUBLIC_12345
ファイルを配信
届いたコードの中身を調べられる。
.envファイル自体を公開していなくても、中の値が公開用コードへ移る経路があります。
Astroでは、ブラウザ側で使える変数の接頭辞はPUBLIC_です。使っている仕組みによってルールが違うので、変数名だけを別の記事からまねしないようにします。Astro公式:環境変数
また、サーバー用の変数でも、その値をHTMLへ書き出したり、APIの応答で返したりすれば、利用者に渡ります。変数名を変えることと、値が外へ出ない設計にすることは、別の確認です。
ダミーの値が届くところを見てみる
ここは、コードを実行せずに結果まで読んでも大丈夫です。自分で試す場合は、Viteを使う練習用のアプリで、上のダミー値だけを使います。既存サービスの本物のキーや本番の設定は変更しません。
練習用アプリの画面に、ボタンと結果欄を置きます。
<button id="check">練習用の設定値を見る</button>
<p id="result"></p>
その画面から読み込むJavaScriptに、次を書きます。Viteの通常の構成なら、index.htmlから読み込むmain.jsが一例です。
// Viteで処理する、ブラウザ側のmain.js
// .envには、上のダミー値を設定したものとします。
document.querySelector('#check').addEventListener('click', () => {
const key = import.meta.env.VITE_SUMMARY_KEY;
document.querySelector('#result').textContent =
'ブラウザが読み取った値:' + key;
});
練習用アプリを起動し、ボタンを押すと、次の表示になります。
ブラウザが読み取った値:DEMO_PUBLIC_12345
.envに書いた値を、ブラウザのプログラムが読み取れました。公開用にビルドしたJavaScriptにも、このダミーの文字列が含まれます。ボタンで表示する処理をなくしても、キーを通信に使うコードがブラウザ側に残れば、秘密を渡している問題は解消しません。
この練習で確かめたのは、「設定ファイルに書く」と「利用者に渡さない」は同じではないという点です。もう一つの変数がこの例の公開用コードに含まれなかったとしても、自分のアプリ全体が安全だと証明したことにはなりません。
では、秘密のキーはどこで使う?
要約アプリでは、利用者のブラウザから、まず自分の管理するサーバーへ文章を送ります。サーバーが秘密のキーを使って要約サービスを呼び、要約結果をブラウザへ返します。
ここでいうサーバーには、クラウドの関数など、利用者へ配らずに処理を実行する場所も含みます。
秘密のキーは持たない。
文章
結果
誰が・どれだけ使えるかを確認。
秘密のキーはここで使う
ブラウザへの応答には含めない。
文章+キー
結果
文章を処理して、結果を返す。
設定の置き方は、例えば次のようになります。
自分のPCで開発するとき
→ サーバー側だけが読む、公開対象に含めない設定
公開したアプリを動かすとき
→ 公開先のサーバー用環境変数や、秘密を管理する機能
利用者のブラウザへ送るコード
→ この秘密のキーは入れない
公開先に「環境変数」の設定画面があっても、その値がサーバー専用なのか、ビルドを通じてブラウザ用ファイルへ入るのかは確認が必要です。
また、GitHub PagesはHTMLやJavaScriptなどを配信する静的サイトの公開サービスです。そこへサーバー用の処理を置くだけでは、この図のサーバーは動きません。秘密のキーが必要な処理には、別の実行先を用意するなどの構成を考えます。GitHub公式:GitHub Pagesの仕組み
サーバーを挟めば、だれでも呼べてよい?
利用者に秘密を渡さない。
↓ もう一つ確認する
利用者の権限と、回数・文章量の制限。
無制限に代理すれば、他人の利用で料金が増えることも。
↓ 許可した範囲で処理する
送る文章の扱いも、別に確認。
ここで、もう一つ落とし穴があります。
秘密のキーが見えなくても、自分のサーバーの要約窓口をだれでも無制限に呼べるなら、他人の利用で料金が増える可能性があります。
そこでサーバー側では、「この人に利用を許可するか」「どれだけの頻度や量を受け付けるか」を決めます。今回の例なら、まずはログインした利用者だけに許可し、回数や文章量を制限する設計が候補です。公開サービスとして匿名利用を許す場合も、その前提で制限や不正利用対策を決めます。
キーを見せないことと、サービスを勝手に使わせないこと。両方を確認します。
なお、ブラウザからサーバーへ送った文章は、さらに外部の要約サービスへ送られます。キーが守られていても、個人情報や仕事の文章を送ってよいかは別に考える必要があります。
自分のアプリでは、まずこの3か所を見る
- 発行元で、種類を見る
キーの種類:サーバー専用
用途・権限を公式の説明と照合。 - コードで、実行場所を見る
変数名:SUMMARY_API_KEY
値を出さず、参照ファイルを確認。 - 公開先で、渡る範囲を見る
保存先:サーバー用の設定
配信物と通信も確認。
コードを全部理解する必要はありません。まず、どこで何を確かめるかを分けます。
1. キーを発行したサービスの管理画面
キーの種類と権限を確認します。サーバー専用なら、その説明が今回の判断の出発点です。使う機能に不要な権限があれば、必要な範囲へ絞れるかも見ます。
ここは、サービスの契約やキーを管理している人が担当します。個人開発なら、自分が兼任していることも多いでしょう。
2. アプリを作っている場所
開発を手伝う人やAIには、キーの値ではなく、変数名とコードの場所を確認してもらいます。
例えば、このように依頼できます。
このアプリの
SUMMARY_API_KEYについて確認して。値は表示・出力しないでください。どのファイルで参照し、ブラウザとサーバーのどちらで動く処理か説明してください。公開するHTML、JavaScript、通信の応答に値が含まれないかも、確認した場所と方法を示してください。コードや設定の変更は、まず提案までにしてください。
「サーバー側です」という回答だけでは、確認が足りません。ファイル、実行場所、公開用ファイルや通信を確かめた結果までつなげます。AIの回答も、実物で裏付けます。
3. 公開先の設定と、公開するもの
開発用と公開先の設定が同じとは限りません。公開を担当する人が、秘密を保存する場所、公開用ファイル、キーを使う窓口の利用制限を確かめます。
ブラウザの開発者ツールにある「Network」では、ブラウザが取得したファイルや送受信した内容を調べられます。ただし、一度画面を開いてキーが見つからなかっただけで、すべての経路を確認できたことにはなりません。初めは開発を手伝う人と、キーを使う操作を一つずつ追うと整理しやすくなります。
通信の記録や画面の画像には別の秘密が含まれることもあります。調査のために、そのまま公開したりAIへ貼ったりはしません。
すでに公開したかもしれないときは
「コードから消して、もう一度公開すればよい?」と思うかもしれません。でも、古いコードやコピーが残っていれば、前のキーを使える場合があります。
GitHubも、認証情報が漏れた場合は、まず失効や交換を行うよう案内しています。履歴からの削除だけで終わらせないことが重要です。GitHub公式:漏えい時の対応
- どのキーか特定する
値を相談文へ貼らず、発行元と用途を確認。
- 旧キーの失効・交換
切り替え先と停止の影響を、公式手順で確認。
- 履歴と公開物を調べる
不審な利用と、同じ漏えい経路が残らないかを確認。
疑わしいときは、次の順で対応を進めます。
- どのサービスの、どのキーかを特定する。値を相談用のメッセージへ貼らない。
- 管理画面と公式の手順で、旧キーの失効・交換を進める。稼働中のサービスがある場合は、切り替えと停止の影響を確認する。
- 利用履歴、料金、アクセスできたデータの範囲を調べる。身に覚えのない利用や個人情報への影響があれば、サービス提供元や対応を助ける人へ相談する。
- コードや公開方法を直し、新しいキーでも同じことが起きないか確認する。
履歴を書き換える操作には、共同作業や古いコピーへの影響もあります。焦って削除コマンドを試すより、キーを使えなくする対応と、残っている公開物の整理を分けて進めます。
実際に、トークンが盗まれた事例もある
分類:事故の公表。 2022年4月、GitHubは、HerokuとTravis CIに発行されていたOAuthトークンが盗まれ、リポジトリへの不正アクセスに使われたことを公表しました。OAuthトークンは、サービス連携でアクセスを許可する認証情報の一種です。GitHubによる公表
これは、この記事の「ブラウザ用コードへAPIキーを入れた」という経路の事故ではありません。ただ、認証情報が漏れたときには、画面の修正だけではなく、その情報が与えるアクセスを止め、利用された範囲を調べる必要があることが分かります。
自分のアプリに当てはめてみよう。
図の中の発行元・アプリ・公開先を、自分が使うサービスへ置き換えてみましょう。分からないところは、次の確認に残せます。
公開前に、ここまで説明できる?
チェックの目的は、丸を付けることより、分からないところを具体化することです。
- 種類: キーの種類が分かる。 管理画面と公式の説明で、公開用か秘密かを確認した。
- 実行場所: 使う場所を指せる。 参照するファイルと、ブラウザ・サーバーのどちらで動くかを確認した。
- 公開範囲: 秘密の値を利用者へ返していない。 公開用ファイルとキーを使う通信を調べ、調べていない経路は未確認として区別した。
- 利用制限: 窓口の使わせ方が決まっている。 誰が使え、回数や量をどう制限するかを確認した。
- 交換手順: 交換するときの手順が分かる。 キーの管理者、失効する画面、交換が必要なアプリを把握した。
「種類は分かった。でも公開先でどこへ渡るかは分からない」なら、そこが次に確かめる場所です。分からないまま秘密のキーを差し替えて試す必要はありません。
次は「その人のデータだけ見えるか」へ
APIキーの設定で押さえたいのは、ファイル名を覚えることではありません。
そのキーが何を許可し、どこで使われ、だれに届くかを追えること。 これが分かると、AIに設定を頼むときも、回答を確かめやすくなります。
アプリにログインやデータの保存を加えたら、次はログインと、データを使う権限の違いを見てみましょう。キーを隠せていても、別の利用者のデータが読めてしまう問題は、別の場所に残るからです。
Node.jsで動かしているなら、実行環境も確認する。
キーの設定とは別に、アプリを動かす実行環境にも更新が必要です。Node.jsやMCPを使っている場合は、2026年10月の更新事例で、導入した版と動いている版を確認する場所を整理できます。
AIツールやMCPの実行環境を確かめたいとき
Node.jsの更新、確認するのはどこ?
PC・MCP・CI・本番を分け、更新した版と動いている版を確認します。
記事を読む一次資料
- Supabase:API keys
- Vite:Env Variables and Modes
- Astro:Using environment variables
- GitHub:What is GitHub Pages?
- GitHub:Removing sensitive data from a repository
- GitHub:Security alert — stolen OAuth user tokens
書いた人
マーケティングの現場から、AIをつくり、仕事で使う側へ。実際に試したことや、つまずいたことを、図解と具体例で伝えています。
この記事のURL:https://nekoai-lab.github.io/ai-security-playbook/learn/api-keys/
続けて読む
読む順番・ルートを見る
AIで作って公開する基本- AIに渡す情報を、送る前に分ける
- 「学習しない」AIなら、仕事の個人情報を使える?
- AIで作ったアプリの、動く場所を知る
- AIに「APIキーを設定して」と言われた。どこに入れるのが正解?
- APIキーを替えたのに、古いキーが使われている?
- ログインと、データを使う権限を分ける
- 公開したのは、本当に見せたいファイルだけ?
- コードには書いていない。名前やメールは、どこから公開される?
- 緑のチェックが付いた。その変更を公開していい?
- AIレビューが合格した。その結果を、どこまで信じていい?
- AIにデプロイを頼んだ。その認証情報は、どこまでできる?
- AIで作ったサービスを、公開する前に確かめる
- 外部サービスが止まったら、自分のアプリはどうなる?
- 漏えい・異常・消失に気づいたとき、最初にすること





