アプリでAPIキーを安全に保つ方法
APIキーを安全に保つには、ホスティングサービスのシークレットまたは環境変数として保存し、サーバー側のコードでのみ使い、チャット、コードファイル、スクリーンショット、Gitリポジトリには絶対に貼り付けないでください。各キーには必要最小限の権限だけを与え、提供者側で支出上限を設定しましょう。キーが漏えいしたら、単にどこに出たかを隠すのではなく、ローテーションしてください。新しいキーを作り、古いキーを削除します。
APIキーは、サービスにとってのパスワードです。OpenAIのキーがあれば誰かがAIの利用料を使えますし、Stripeのシークレットキーがあれば誰かが返金を発行できますし、メール送信サービスのキーがあれば誰かがあなたになりすましてメールを送れます。AIアプリビルダーはこれらを組み込むのが得意ですが、キーがどこに行き着くかに常に注意を払うとは限りません。このガイドでは、キーを安全に保つ方法と、その確認方法を扱います。
公開キーとシークレットキー
すべてのキーが秘密というわけではありません。違いを知っていれば、間違ったキーを必要以上に心配したり、正しいキーを見逃したりすることを防げます。
| 種類 | 例 | ブラウザに置いてよいか |
|---|---|---|
| 公開可能キー / 公開キー | Stripeの pk_… キー、自分のドメインに制限したマップのキー、一部のアナリティクスID | はい。そのように設計されています |
| シークレットキー | Stripeの sk_…、OpenAIやAnthropicのキー、メール送信サービスのキー、データベースのパスワード | いいえ。決して置かない |
| サービス用・管理用キー | ホスティングされたデータベースのアクセスルールを回避できるキー | いいえ。最も機密性の高いものとして扱う |
どちらのキーか分からない場合は、提供者のドキュメントを確認してください。迷ったら、シークレットとして扱いましょう。
ステップ1:キーはコードではなく、シークレットとして保存する
キーは、ホスティングサービスの環境変数やシークレットの設定に保存します。コードは実行時に名前で読み込みます(例:process.env.OPENAI_API_KEY)。そのため、値がファイルに現れることはありません。背景については、環境変数とシークレットとはを参照してください。
コードに書かれているすべてのAPIキーを環境変数に移してください。見つけたキーごとに、どのファイルにあったか、使った変数名を一覧にしてください。値は表示しないでください。
その後、何も残っていないことを確認します。
設定ファイルや .env ファイルを含め、プロジェクト全体で、APIキーやパスワードのように見えるものを検索してください。報告するのはファイル名と行番号だけにして、値は表示しないでください。
ステップ2:シークレットキーはサーバーでのみ使う
これが最も重要なルールです。ブラウザが受け取るものは、訪問者が誰でも読めます。ページのソースやJavaScriptファイルは、開発者ツールで見えてしまいます。
つまり、アプリがOpenAIを呼び出す必要がある場合、ブラウザは自分のサーバーを呼び出し、サーバーがキーを使ってOpenAIを呼び出します。キーがサーバーの外に出ることはありません。
チャット機能は、ブラウザから直接OpenAIを呼び出しています。その呼び出しを、環境変数 OPENAI_API_KEY を読み込むサーバーのAPIルートに移してください。ブラウザはこちらのルートだけを呼び出すようにしてください。このルートにはログインを必須にしてください。
フロントエンドのフレームワークでよくある罠に注意してください。Viteでは VITE_、Next.jsでは NEXT_PUBLIC_ といった公開用の接頭辞が付いた変数は、意図的にブラウザのコードに組み込まれます。シークレットキーにこの接頭辞が付いていれば、「環境変数に入れてある」としても、そのキーは公開されてしまいます。
ステップ3:何も漏れていないかテストする
うまくいったと思い込まず、公開中のサイトで確認してください。
- ブラウザで、公開したアプリを開きます。
- 開発者ツールを開き、Sources(ソース)またはNetwork(ネットワーク)タブを表示します。
- 各シークレットキーの先頭の数文字(例:
sk_やsk-)を、すべてのファイルから検索します。 - アプリが行うネットワークリクエストを確認します。ブラウザから有料のAIプロバイダーに直接リクエストが飛んでいたら、危険信号です。
シークレットキーが見つかったら、サーバー側に移し(ステップ2)、ローテーションしてください(ステップ6)。すでに公開されていたからです。
ステップ4:各キーにできることを制限する
多くのプロバイダーでは、キーの権限を制限できます。
- スコープ付き、または制限付きのキー。 アプリに必要なことだけができるキーです。例えばStripeは、特定の権限を持つ制限付きキーに対応しています。
- ドメインやIPによる制限。 マップのキーのように公開せざるを得ないキーに使います。
- アプリごと、環境ごとに別のキー。 1つが漏えいしても、すべてが露出しないようにし、1つを無効化しても他に影響しないようにします。
- 開発中はテスト用キー、公開したアプリでのみ本番用キー。
ステップ5:被害に上限を設ける
適切に守られたキーでも、アプリ自体を通じて悪用されることがあります。例えば、誰かがAI機能を何千回も繰り返し呼び出すような場合です。
- すべての有料プロバイダーで、支出の上限またはアラートを設定してください。
- 1回ごとに料金がかかる機能には、ログインを必須にしてください。
- ユーザーごとのレート制限を追加してください。レート制限とはを参照してください。
/api/chat へのAIリクエストを、ユーザーごとに1時間あたり30件に制限してください。上限に達したら、わかりやすいメッセージを返してください。ログインしていないユーザーからのリクエストは拒否してください。
ステップ6:漏えいしたキーはローテーションする
シークレットキーが、本来あってはならない場所に現れたら(チャットのメッセージ、コミット、スクリーンショット、サポートのチケット、ブラウザのコードなど)、侵害されたと想定してください。
- 提供者の側で新しいキーを作成します。
- アプリの設定で、シークレットを更新します。
- 再デプロイまたは再公開して、公開中のアプリが新しいキーを使うようにします。
- 提供者の側で古いキーを削除します。
- 提供者の利用ログで、心当たりのない活動がないか確認します。
チャットのメッセージやGitのコミットを削除するだけでは不十分です。Gitの履歴には古いバージョンが残ります。公開されたものは、すでにコピーされているかもしれません。
よくあるミス
- キーをプロンプトに貼り付ける。 チャットの履歴に残ってしまいます。代わりにシークレットのフォームを使ってください。
- シークレットの変数に公開用の接頭辞を付ける。
VITE_OPENAI_API_KEYは、すべての訪問者にキーを配ってしまいます。 - .env ファイルをコミットする。 最初のプッシュの前に、
.gitignoreに入っていることを確認してください。 - 1つのキーを何にでも使う。 テスト用と本番用、そしてアプリごとに別のキーを使ってください。
- 支出の上限がない。 漏えいしたキーや悪用されたキーに上限がないと、気づく前に大きな請求が発生することがあります。
- 隠すだけで、ローテーションしない。 一度漏えいしたキーを解決できるのは、新しいキーだけです。
- スクリーンショットにキーが写っている。 助けを求めて共有する前に、設定画面をトリミングするかぼかしてください。
チェックリスト
- すべてのキーは、コードではなく、シークレットまたは環境変数として保存している。
- .env ファイルやキーをGitにコミットしていない。
- シークレットキーは、サーバー側のコードでのみ使っている。
- シークレットの変数に、
VITE_やNEXT_PUBLIC_のような公開用の接頭辞がない。 - 公開サイトのJavaScriptを、各キーの接頭辞で検索して、何も見つからなかった。
- 提供者が許す場合は、キーをスコープまたは制限している。
- テスト用キーと本番用キーを分けている。
- 有料機能はログインを必須にし、ユーザーごとの上限がある。
- 有料の各プロバイダーに、支出の上限またはアラートがある。
- 各キーのローテーション方法を知っており、一度でも漏えいしたキーはローテーション済み。
Mythexでのキーの守り方
Mythexは、キーをコードとチャットの外に置くために、2つの仕組みを用意しています。
- シークレットのリクエストカード。 エージェントがキーを必要とすると、チャットにカードを表示します。値はメッセージ入力欄ではなく、フォームの入力欄に入れ、プロジェクトのシークレットとして保存されます。チャット内のシークレットを参照してください。
- プロジェクト設定 → シークレット、またはチャットの
/secretsで、自分でキーを追加・変更できます。環境変数とシークレットを参照してください。
公開中のアプリでシークレットを変更したら、再公開して、ライブのアプリに反映させてください。エクスポートしたプロジェクトにはシークレットは含まれないため、コードを次に実行する場所で、シークレットを再度追加してください。キーがチャットに現れてしまったら、提供者の側でローテーションしてください。
公開前のセキュリティ確認の残りは、AIで作ったアプリのセキュリティチェックリストで進めてください。AI機能を追加するなら、LLM APIの使い方で、キーと料金についてさらに詳しく扱っています。
よくある質問
フロントエンドのコードにAPIキーを入れても安全ですか?
そのキーが公開されることを前提に、提供者が設計したものである場合に限ります。例えば、Stripeの公開可能キーや、自分のドメインに制限したマップのキーです。お金を使えるキーや、非公開のデータを読めるキーは、必ずサーバー側に置いてください。ブラウザに送られたものは、誰でも読めるからです。
APIキーをチャットや公開リポジトリに貼り付けてしまったら、どうすればよいですか?
キーをローテーションしてください。提供者の側で新しいキーを作成し、アプリのシークレットを更新して、再公開し、古いキーを削除します。メッセージやコミットを削除するだけでは不十分です。コピーがすでに存在しているかもしれないからです。
APIキーはどこに保存すべきですか?
ホスティングサービスの環境変数やシークレットの設定に保存し、サーバー側のコードが実行時に読み込むようにしてください。ソースファイルに書いたり、Gitにコミットしたり、スクリーンショットに含めたりしてはいけません。
自分のWebサイトでAPIキーが漏えいしていないか、どう確認すればよいですか?
公開中のサイトを開き、ブラウザの開発者ツールでページのソースとJavaScriptファイルを表示して、キーの先頭の文字列を検索してください。見つかったら漏えいしているので、サーバー側に移してローテーションしてください。