ChatGPTやClaudeにコードを書いてもらい、外部のAIサービスとつながるツールを作るとき、APIキーをコードに直書きしたままGitHubに公開してしまう事故が後を絶ちません。しかも「気づいてすぐ消した」のに手遅れになる。その理由は、Gitのコミット履歴にあります。この記事では、APIキーが漏れると何が起きるのか、漏れたときに何をすべきか(無効化・再発行)、そして環境変数・.gitignore・Secret Scanningによる再発防止までを、10ページの漫画と文章で、プログラミング未経験の方にも分かるように解説します。

「AIさん、文章を要約するツールを作って!」

そう頼めば、外部のAIサービスとつながった業務ツールが、あっという間に出来上がる時代です。前回の記事では、AIと一緒に開発するための「GitHubの基本」をお伝えしました。

今回はその続きで、AIと開発を始めた人が、ほぼ必ず一度は通る落とし穴のお話です。

  • AIが書いてくれたコードに、APIキーがそのまま入っていた
  • 気づいて「すぐ消した」のに、なぜか手遅れだった

実はこのシリーズの元記事『「すぐ消しておきました」では、手遅れです』というタイトルは、まさにこの第2条から来ています。「消したから大丈夫」が通用しない理由と、代わりに何をすべきかを、まず漫画で、そのあと文章でじっくり解説します。

まずは漫画でどうぞ(第2条:APIキー・パスワードをコードに直書きしない/10ページ)

いかがでしょうか。ここからは、漫画に出てきた考え方を順番に、もう少し丁寧に補足していきます。

APIキーとは何か ── 外部サービスを使うための「合鍵」

漫画の2ページ目で先輩が説明していたとおり、APIキーは外部サービスを呼び出すための「秘密の鍵」です。ChatGPTやClaudeのようなAIサービス、決済サービス、地図サービスなど、外部のサービスをプログラムから使うときに、「この呼び出しは、あなたのアカウントからのものです」と証明するために使います。

ここで大事なのは、鍵を持っている人は、あなたになりすまして、その鍵に与えられた権限の範囲でサービスを使えるということです。そして、AIサービスの多くは使った分だけ課金される従量制。他人があなたの鍵で使えば、請求はあなた(もしくはあなたの会社)に届きます。

つまりAPIキーは、「チャージ済みの電子マネーの番号」に近い存在です。パスワードと同じく、人に見せてはいけない秘密として扱う必要があります。

AIが生成したコードにAPIキーが直書きされる問題 ── 「動いた」と「安全」は別

3ページ目で起きていたのが、この記事でいちばん伝えたい落とし穴です。

AIにコードを頼むと、動作確認しやすいように API_KEY = "sk-..." のような形でキーを直接書き込んだサンプルを返してくることがあります。そこに本物のキーを貼り付けて「動いた!」となれば、コードの中に秘密がそのまま残った状態になります。

問題は、AIは動くコードを返すのが得意でも、「このコードは公開しても安全か」までは面倒を見てくれないことです。動いたかどうかと、安全かどうかは別の話。この確認は、人間の仕事として残ります。

そして、そのコードをGitHubの公開(Public)リポジトリに置いた瞬間から、次の段階が始まります。

APIキーが漏れるとどうなるか ── 公開された秘密は数分で拾われる

4ページ目の「虫眼鏡」は、インターネット上を自動で巡回して、APIキーやパスワードらしき文字列を探し回るプログラムの比喩です。

公開リポジトリに秘密が含まれていると、こうした自動収集によって、公開から数分で拾われることがあります。「自分のリポジトリなんて誰も見ていない」は、人間についてはそのとおりかもしれませんが、機械はそう働いていません。

拾われた鍵は、不正利用に使われ、その結果として高額な請求だけが手元に届く。「消すまで誰も見ていないはず」という前提は、残念ながら成り立たないのです。

「消してコミットした」では消えない ── Gitのコミット履歴にAPIキーが残る仕組み

ここが漫画5ページ目の山場であり、シリーズのタイトルの由来です。

前回の記事で、コミットを「ゲームのセーブポイント」に例えました。いつでも過去の状態に戻れる、便利で心強い仕組みです。ところが、この便利さがそのまま裏目に出ます。

コードからキーを削除してコミットしても、それは「キーを消した」という新しいセーブポイントが増えただけです。「キーを書いた」ときのセーブポイントは、そのまま残っています。履歴をさかのぼれば、キーは今も読める状態にあるということです。

  • commit 1:キーを書いた(キーが残っている)
  • commit 2:別の修正(キーが残っている)
  • commit 3:キーを消した(現在の状態)

これが「すぐ消しました」が手遅れになる理由です。削除は新しい記録であって、過去の記録の取り消しではありません。

APIキーを漏らしたときの対処法 ── 削除ではなく無効化・再発行

では、うっかり公開してしまったら何をすべきか。6ページ目の内容を、順番に整理します。

  1. 古いキーを無効化する:管理画面から該当のキーを削除(Revoke)します。拾われた鍵も、使えなくしてしまえば実害は止まります。「落とした鍵を探しに行く」のではなく「鍵穴ごと交換する」発想です。
  2. 新しいキーを発行し、アプリの設定を更新する:無効化すると自分のツールも動かなくなるので、新しいキーに差し替えます。このとき、後述する環境変数の形に直しておくと再発を防げます。
  3. 利用履歴と請求を確認する:無効化するまでの間に不正利用されていないか、サービス側のダッシュボードで確認します。
  4. 責任者に報告する:会社のキーであれば、隠さず速やかに報告してください。早ければ早いほど、被害の範囲を小さくできます。

パスワードが漏れた場合も同じで、まずは変更が先です。

なお、Gitの履歴からキーの痕跡を消す作業(履歴の書き換え)は技術的には可能ですが、共同作業中のリポジトリでは影響が大きく、単独で行うと別のトラブルを招くことがあります。漫画で先輩が「担当者と相談しよう」と言っていたのはそのためです。順番としては、まず無効化、履歴の整理はそのあとで落ち着いて、が鉄則です。

再発防止①:環境変数と.envファイルでAPIキーをコードの外に出す

根本的な対策は、そもそもコードの中に秘密を書かないことです。7ページ目の考え方を整理します。

環境変数から受け取る

コードには「環境変数 API_KEY からキーを受け取る」とだけ書き、キーの実体はコードの外に置きます。こうしておけば、コードを公開してもキー本体は含まれません。

.envファイルは「設定ファイル」であって「暗号化」ではない

開発中は、.env というファイルにキーを書いておき、そこから環境変数として読み込む方法がよく使われます。ただし勘違いしやすいのですが、.env はただのテキストファイルです。中身が守られているわけではないので、このファイル自体をGitに記録してしまえば、直書きと同じことになります(対策は次の項で)。

本番の秘密は、サーバー側のシークレット管理で

実際に運用するサービスでは、クラウドやホスティング環境が提供している「シークレット管理」の機能を使い、秘密をサーバー側に置きます。手元のファイルではなく、権限を持つ人だけが触れる場所で管理するのが基本です。

ブラウザに配るコードには、秘密を入れない

もうひとつ見落としやすいのが、Webページの見た目を動かすコード(ブラウザ側で動くコード)です。これは利用者のブラウザにそのまま届くので、ここにキーを書くと「公開する」のと同じです。外部サービスの呼び出しはサーバー側に置き、ブラウザはサーバーに頼む形にします。

再発防止②:.gitignoreで.envをGitの記録対象から外す

8ページ目で主人公が自分で気づいたとおり、「.envもコミットしたら同じでは?」というのはそのとおりです。

.gitignore は、Gitに「このファイルは記録しないでください」と伝えるためのリストです。ここに .env を書いておけば、コミットの対象から外れ、うっかり公開する事故を防げます。秘密は、最初からGitの記録に乗せない。これが鉄則です。

ただし2つ注意点があります。

  • すでに追跡しているファイルには効かない:.gitignore に追加する前に一度でもコミットしたファイルは、そのままでは追跡され続けます。
  • 過去の履歴は消えない:前の項で説明したとおりです。すでに記録してしまった秘密は、無効化で対処します。

だからこそ、コミットする前に「今回、どのファイルが記録に入るのか」を確認する習慣が効きます。ステージング中のファイル一覧に .env が混ざっていないか、ひと目見るだけで防げる事故はたくさんあります。

再発防止③:AIへの指示と、GitHubのSecret Scanning/Push Protection

9ページ目は、日々の運用で効く3つのコツです。

AIへの最初の一言

AIにコードを頼むとき、「APIキーは環境変数から読み込む形にして。秘密をコードに入れないで」と一言添えてください。これだけで、最初から直書きのないコードが返ってきやすくなります。頼み方ひとつで、AIも安全なコードを書いてくれます。

Secret Scanning:記録された秘密を検知する

GitHubには、リポジトリの中にAPIキーらしき文字列が含まれていないかを自動で検知し、警告してくれる機能があります。公開リポジトリでは無料で有効化できます(非公開リポジトリでの利用条件はプランによるので、お使いの環境で確認してください)。

Push Protection:送信時に見つけて止める

こちらは、GitHubに送信(push)する時点で秘密を検知し、その送信自体をブロックする機能です。「記録されてから気づく」のではなく「記録される前に止める」ので、より手前で事故を防げます。

ただし、検知の対象は主要なサービスの既知のキー形式が中心で、あらゆる秘密を漏れなく見つけてくれるわけではありません。自動検知はあくまで補助輪。最後は人の確認とセットで運用してください。

よくある質問(APIキー管理のQ&A)

Q. 非公開(Private)リポジトリなら、キーを直書きしてもいいですか?

A. おすすめしません。公開設定は後から変わることがありますし、リポジトリに招待した全員がキーを見られる状態になります。また、リポジトリごとコピーされたり、別のサービスと連携したりした先で漏れることもあります。非公開でも「秘密はコードに書かない」は同じです。

Q. 自分しか使わないツールなら、気にしなくていい?

A. 漏れたときに困るのは「誰が使うか」ではなく「そのキーで何ができるか」です。課金されるサービスのキーなら、自分ひとりのツールでも同じ対策をしてください。

Q. キーを無効化したら、ツールが止まってしまいます

A. 止まります。だからこそ、新しいキーの発行とアプリ設定の更新をセットで行います。数分の停止と、不正利用による請求では、比べるまでもありません。

Q. 漏らしたことを、正直に報告すべきですか?

A. はい。漏洩は珍しいことではなく、対応の速さがすべてです。「黙って消しておいた」が最悪の選択になるのは、この記事で説明したとおり、消しても残るからです。

まとめ:APIキーとパスワードを守る4原則

最後の10ページ目のチェックリストを、もう一度。

  1. コードにキーを直書きしない(環境変数から受け取る)
  2. 秘密をGitに記録しない(.gitignore に .env、コミット前に確認)
  3. 漏れたら、削除ではなく無効化・再発行
  4. 自動検知(Secret Scanning/Push Protection)と、人の確認をセットで

AIのおかげで「作る」ハードルは下がりました。だからこそ、AIが書いたコードを人が確認する場所として、GitHubとこの4原則を手元に置いておいてください。

次回は第3条「デプロイしたツールの公開範囲を確認する」を、同じく漫画でお届けします。


株式会社Four Youでは、生成AIの導入支援から、AI開発における安全な運用体制づくりまで、企業のAI活用を伴走支援しています。「AIに開発を任せたいが、セキュリティが不安」という方は、お気軽にご相談ください。
#APIキー #GitHub #ChatGPT #ClaudeCode #セキュリティ #生成AI #AI開発 #バイブコーディング #プログラミング初心者 #漫画でわかる