gitに秘密情報を漏らさないために。26の実例集leak-museumで学ぶ回避策
対象の目安: アプリケーション開発者や運用担当 / 実務

APIキーやデータベースのパスワード、秘密鍵をうっかりgitに含めてしまう事故は、いまも数の多い漏洩の入口です。公開リポジトリならクローンした誰もが手にでき、非公開でも過去のコミットや共同作業者を通じて広がります。厄介なのは、ファイルを消しても履歴には残り、削除しただけでは無かったことにできない点です。
この記事では、こうした「やってはいけない」を実例で集めた教育用リポジトリleak-museum(printemps-tokyoが公開)を題材に、gitへの秘密情報の混入がなぜ致命的なのか、どう防ぐのか、そして万一コミットしてしまったときにどう対処するのかを、秘密情報の衛生という観点で整理します。leak-museumに置かれた認証情報はすべて実サービスでは無効で、例示用の値や、意図的に壊したトークン、このリポジトリ専用に生成してどこにも登録していないデモ鍵で構成され、学習と秘密スキャナの試験のために作られています。本記事でも具体的な鍵の値は扱わず、パターンと対策に絞ります。
leak-museumが集めた26のアンチパターン
leak-museumは、開発者が秘密情報をgitへ漏らす古典的な方法を一か所に集めた展示です。各展示は小さなディレクトリになっていて、悪い例のファイルと、その被害と直し方を説明するREADMEが対になっています。扱う範囲は、コミットされた.env、クラウドの鍵、SSHやTLSの秘密鍵、データベースのダンプ、KubernetesのSecretマニフェスト、Terraformのstate、CIのログ、そして忘れがちな残りかすまで広く及びます。
同時にleak-museumは、秘密スキャナを試すためのコーパスとしても使えます。gitleaksやtrufflehogのようなスキャナを向けて、仕込まれた秘密をいくつ見つけられるかを確かめられます。printemps-tokyoのredactは、標準入力や単一ファイルのテキストから秘密や個人情報を検出して伏せ字にするツールで、ログなどのマスキングの確認に使えます。どの展示に何を仕込んだかは、答え合わせ用の一覧(PLANTED.md)にまとめられています。組織全体でGitHubのプッシュ保護を有効にしているため、検知されやすいプロバイダのトークンは、公開できるよう壊した形で置かれています。
正しくやり直したgood-exampleディレクトリと、対策を一枚にまとめたDO-THIS-INSTEAD.mdのチェックリストも同梱されており、悪い例と良い例を並べて見比べられる構成です。
あわせて読みたい
シークレット管理の実務。APIキー・認証情報をハードコードせず、Vaultやマネージドサービスで守りローテーションする
なぜ一度の混入が致命的になるのか
展示を通して繰り返し示されるのは、秘密情報がコードと同じ経路で広がるという構造です。ハードコードされた鍵は、リポジトリだけでなくフォークやビルド成果物、各開発者の端末にまで載ります。クラウドのアクセスキーが漏れると、そのキーに許可された操作を第三者に実行される恐れがあります。広い権限を持つキーなら、リソースの不正な起動や課金、データの読み取りにまで及びます。公開リポジトリに現れたこうしたパターンを、ボットが絶えず走査している点も見逃せません。
いくつかの展示は、思い込みが事故を生む場面を具体的に示します。KubernetesのSecretやbase64でエンコードした値を「暗号化した」と錯覚する例では、base64は誰でも元に戻せる符号化であって暗号ではないことが要点です。フロントエンドのバンドルに鍵を含める例では、ブラウザに配られるJavaScriptやソースマップから鍵が読み取れてしまいます。そして「消したはず」の展示では、ツリーから削除しても、その鍵がgitの履歴に残り続けることが示されます。JWTを弱い既知の秘密で署名する例のように、スキャナが素通ししやすい落とし穴も含まれています。JWTの署名と秘密の扱いは、関連記事も参考になります。
あわせて読みたい
JWTの仕組みと実装の落とし穴。署名検証とアルゴリズム混同を基礎から
漏らさないための実践
leak-museumのDO-THIS-INSTEAD.mdは、すべての展示の裏返しを一枚にまとめたものです。要点は、gitに入れない、正しい保管先を使う、混入を事前に止める、の三つに整理できます。
秘密情報を漏らさないための基本
- 1
.env や *.key、id_ed25519、.aws/、*.tfstate といった危険なパスを、最初のコミットから .gitignore で除外する
- 2
本物の .env はコミットせず、キー名と空の値だけを持つ .env.example を置く
- 3
実行時は環境変数や秘密管理サービス(Vault、各クラウドの秘密マネージャー、1Password、Doppler など)から読む
- 4
秘密管理サービスを第一候補にしつつ、リポジトリ内で暗号化するなら用途に合う専用ツールを使う。汎用の設定ファイルは age や KMS と組み合わせた SOPS、Kubernetes のGitOpsは Sealed Secrets が向く。git-crypt は失効や鍵ローテーションを扱えず対象も限られる。base64 は暗号化ではない
- 5
長期間有効な鍵より、短命で最小権限の資格情報や OIDC を優先する
事前に止める仕組みも欠かせません。コミット前に走るpre-commitフックとしてgitleaksやtrufflehogのようなスキャナを組み込むと、検知できる形の鍵はコミットされる前に止められます。GitHubのプッシュ保護のような、ホスト側で検知して押し戻す機能もあわせて有効にします。スキャンはソースファイルだけでなく、ツリーと履歴の全体を対象にCIで回すと、検出の範囲を広げられます。ただしスキャナは万能ではありません。leak-museum自身が、弱い汎用パスワードや設定次第で見えにくい形式など、スキャナがすり抜けやすい展示を用意しています。フックはスキップでき、プッシュ保護も設定によっては回避されます。スキャナは最後の安全網ではなく、入れないための一層と捉えるのが適切です。こうした自動化を開発の流れに組み込む考え方は、関連記事でも扱っています。
あわせて読みたい
DevSecOps入門。CI/CDにセキュリティを組み込むSAST・DAST・SCA・シークレットスキャン
秘密情報の衛生チェックリスト
- 危険なパスを .gitignore に初手で登録している
- .env は非コミットで、.env.example にキー名と空値だけを置いている
- 秘密は環境変数か秘密管理サービスから実行時に読み込んでいる
- リポジトリ内暗号化は SOPS や git-crypt など専用ツールを使い、base64 で済ませていない
- pre-commit スキャナとホストのプッシュ保護を有効にしている
- CI でツリーと履歴の全体をスキャンしている
- 長期鍵より短命で最小権限の資格情報や OIDC を優先している
万一コミットしてしまったときの手順
すでに秘密情報をコミットしてしまった場合、対応には順序があります。leak-museumのチェックリストは、まず無効化から始めるよう促しています。
秘密情報をコミットしてしまったときの復旧
- 1
漏れた秘密をローテーションする。高リスクなら即時に無効化し、停止影響がある場合は新しい資格情報を発行して切り替えてから旧値を失効する。削除しても露出は取り消せない
- 2
漏洩の範囲を特定し、依存するサービスの設定を更新し、プロバイダの監査ログで不正利用の有無を確認する
- 3
ツリーから該当ファイルを削除し、.gitignore の規則を追加する
- 4
必要なら git filter-repo や BFG で全ブランチとタグの履歴を書き換え、関係者と調整のうえフォースプッシュし、古いクローンを破棄して各所で再クローンする
順序を守る理由は、ある展示が示すとおり、削除やファイルの移動だけでは過去のコミットに秘密が残るからです。履歴の書き換えは有効な手段ですが、共有済みのクローンやフォーク、GitHub上のキャッシュやプルリクエストの参照にまで自動では手が届きません。フォークは所有者との調整が要り、残ったキャッシュの削除にはホストへの依頼が必要になる場合もあります。だからこそ、確実にリスクを断つのは値そのものの無効化です。
注意
コミットしてしまった秘密は「消せば大丈夫」ではありません。露出した瞬間から、その値は漏れたものとして扱います。最初にやるべきは、鍵やパスワードのローテーション(無効化と再発行)です。履歴からの除去は、そのあとの後始末と考えてください。
スキャナの実力を測るベンチマークとして
leak-museumのもう一つの使い道が、秘密スキャナの挙動を確かめる小さなコーパスとしての活用です。自組織で使うスキャナをこのリポジトリに向け、仕込まれた秘密をどう扱うかを、答え合わせ用の一覧と突き合わせられます。ここで単純な検知数で順位づけしないことが大切です。答え合わせ用の一覧には意図的に壊したトークンも含まれ、有効性を検証するタイプのスキャナがそれらを無効と判定するのは正しい挙動だからです。検知したものを、有効、不明、無効に分けて見て、履歴を走査するかどうかや誤検知の傾向もあわせて評価します。26の展示だけで一般的な再現率を測れるわけではないため、導入前の確認や設定の回帰試験として位置づけるのが実際的です。ツールを入れて終わりにせず、実際に何をどう扱うかを確かめる発想が、秘密情報の衛生を運用として根づかせます。
leak-museumが26のアンチパターンを実サービスでは無効な認証情報とともに集めた教育リポジトリであること、秘密スキャナの試験コーパスを兼ねること、一部の展示がスキャナに見えにくい形であること、答え合わせ用の一覧(PLANTED.md)や正しい例(good-example)とチェックリスト(DO-THIS-INSTEAD.md)を同梱すること、対策として.gitignoreの初手設定や.env.exampleの運用、秘密管理サービスでの保管、pre-commitスキャナとプッシュ保護、コミット後のローテーション優先を挙げていることは、printemps-tokyoのleak-museumの記載に基づきます。redactは同組織のテキストのマスキングツールです。gitleaksとtrufflehogによる検出、履歴書き換えのgit-filter-repo、SOPSとSealed Secretsによる暗号化は各公式リポジトリ、GitHubのプッシュ保護と漏洩時の対応や履歴からの削除はGitHub公式ドキュメントに基づきます。掲載した認証情報がいずれも実サービスでは無効であることはleak-museumの明示に基づきます。
gitへの秘密情報の混入は、ありふれているぶん被害も広がりやすい事故です。leak-museumは、その「やってはいけない」を偽の認証情報で安全に並べ、なぜ危険かと何をすべきかを対で見せてくれます。守りの筋道は明快で、gitに入れない、正しい保管先を使う、事前に止める、そして混入したら真っ先に無効化する、の四つに集約されます。展示を一巡し、自分のリポジトリとgood-exampleを見比べるところから、秘密情報の衛生を運用に落とし込んでいくとよいでしょう。
出典・参考
関連する記事
シークレット管理の実務。APIキー・認証情報をハードコードせず、Vaultやマネージドサービスで守りローテーションする
APIキーやDB認証情報などのシークレットを、ハードコード回避・集中管理・ローテーション・最小権限という4つの軸で守る方法を、Vaultやクラウドのマネージドサービス、動的シークレットまで実務目線で解説します。
DevSecOps入門。CI/CDにセキュリティを組み込むSAST・DAST・SCA・シークレットスキャン
セキュリティを開発の最後の検査にせず、CI/CDに自動チェックとして組み込む考え方を解説します。SAST・DAST・SCA・シークレットスキャンの役割の違いと、シフトレフトを現場で回す導入順序・判断基準を具体的にまとめます。
JWTの仕組みと実装の落とし穴。署名検証とアルゴリズム混同を基礎から
JWT(JSON Web Token)の構造と署名の役割を基礎から整理します。header.payload.signatureの3パート、HS256とRS256の違い、alg:noneやアルゴリズム混同といった検証まわりの落とし穴、有効期限と失効の設計、保存場所によるXSS/CSRFの注意点まで、一次仕様に沿って実装者向けに解説します。


