機密情報の流出は「うっかり」から始まる
GitHubへの機密情報流出は、悪意ある攻撃者よりも開発者自身の不注意から起きるケースがほとんどです。AWSのシークレットキーをコードに直書きしたままコミットしてしまった、.envファイルを誤ってpushしてしまった——こうした事例は、ベテランエンジニアでも経験することがあります。
問題をさらに深刻にするのが、GitHubの性質です。一度コミット履歴に含まれた情報は、ファイルを削除しても歴史に残り続けます。リポジトリがパブリックであれば、GitHubのクローラーや第三者のアーカイブサービスが数分以内に内容を取得することも珍しくありません。「気づいてすぐ消した」では手遅れになるケースが多いのです。
まず「何が機密情報か」を整理する
どのような情報をリポジトリに含めてはいけないかを、最初に明確にしておきましょう。
| 種別 | 具体例 |
|---|---|
| クラウド認証情報 | AWS Access Key / Secret Key、GCPサービスアカウントキー |
| データベース接続情報 | ホスト名、ポート、ユーザー名、パスワード |
| APIキー・トークン | Stripe、Twilio、GitHub Personal Access Token など |
| 暗号化キー | JWT署名シークレット、セッションキー、SSL秘密鍵 |
| 環境設定ファイル | .env、config.yml、application.properties の実体 |
これらに共通するのは「漏洩したら即座に実害が発生しうる」という点です。APIキーが流出した場合、攻撃者がクラウドリソースを大量消費して高額な課金を発生させる「クレデンシャル窃取→クラウド課金被害」は、近年急増しています。
予防策1:.gitignore を正しく設定する
最もベーシックかつ効果的な対策です。見落とされがちなのが「ファイルを追加する前に設定していない」ケースで、.gitignore に記載する前にステージングしてしまうと、その後ルールを追加しても追跡が解除されません。
GitHubが公式提供している github/gitignore には各言語・フレームワーク向けテンプレートがあります。プロジェクト開始時に必ず使いましょう。すでにトラッキングされているファイルを除外したい場合は、以下のコマンドが必要です。
git rm --cached .env
git commit -m "Remove .env from tracking"
.gitignore に追記するだけでは不十分な点に注意してください。
予防策2:シークレットスキャンツールを導入する
.gitignore だけでは防ぎきれないケースに備えて、コミット前に機密情報を検出するツールの導入を強くおすすめします。
gitleaks はGo製で動作が高速かつ設定が柔軟です。.toml 形式の設定ファイルで検出ルールをカスタマイズでき、GitHub Actionsへの統合も容易で、現在最も広く使われているシークレットスキャンツールの一つです。
git-secrets はAWSが提供するオープンソースのツールで、コミット前にシークレットが含まれていないかを自動チェックするgit hookを設定できます。AWSキーのパターンはデフォルトで検出対象です。
brew install git-secrets
git secrets --install
git secrets --register-aws
これらのツールをローカルのpre-commitフックとして設定することで、コミット時点でブロックできます。さらにGitHub Actionsと組み合わせてCI上でも動かすことで、二重のチェック体制を作れます。
予防策3:環境変数を外部から注入する設計にする
コードに機密情報を直書きしないための根本的なアプローチは、設定を「外部から注入する」設計にすることです。
開発環境では .env ファイルに記載し、dotenvライブラリで読み込む方法が一般的です。.env ファイル自体はリポジトリに含めず、値を空にした .env.example だけをコミットすることで、必要な設定項目を他の開発者に伝えられます。
本番環境では、クラウドプロバイダーのシークレット管理サービスを使うのが最善です。AWS Secrets Manager、GCP Secret Manager、Azure Key Vaultなどがあり、アプリケーションが実行時に認証情報を取得します。ECSのタスク定義やKubernetesのSecretオブジェクトを通じて環境変数を注入するのが現代的なアプローチです。
予防策4:GitHubのビルトイン機能を活用する
GitHubはプラットフォームレベルでシークレット漏洩対策の機能を提供しています。
Secret scanning はパブリックリポジトリでデフォルト有効で、AWSキー・GitHubトークン・Stripeキーなど200種類以上のシークレットパターンを自動検出します。検出された場合はリポジトリオーナーにメール通知が届き、対象サービスプロバイダーへの自動通知で無効化を促すパートナープログラムも動いています。
Push protection を有効にすると、シークレットを含むコミットのpushをブロックできます。2023年以降、パブリックリポジトリではデフォルトで有効化されました。リポジトリの「Settings → Security → Code security and analysis」から確認できます。
万が一流出してしまった場合の対応手順
予防措置を講じていても、流出が起きてしまう可能性はゼロではありません。最初にやるべきことは該当の認証情報を即座に無効化・ローテーションすることです。削除やリポジトリのプライベート化よりも必ず先に行ってください。AWSキーであればIAMコンソールで無効化、GitHub TokenであればSettings → Tokensから削除します。「まずファイルを消す」という行動は誤りで、「まずキーを無効化する」が正しい順番です。
その後、git filter-repo ツールを使ってコミット履歴から機密情報を削除します。かつては git filter-branch が使われていましたが、現在は git filter-repo が推奨されています。リポジトリの歴史を書き換える操作なので、チームメンバーへの周知と再クローンが必要です。
チームで根付かせるべき運用習慣
個人の予防策だけでは限界があります。コードレビュー時にシークレットのハードコードを確認するチェックリストを設けること、PRテンプレートに「機密情報の混入がないか確認した」という項目を追加するだけでも意識が変わります。
また、新しいメンバーのオンボーディングでシークレット管理の方針と設定方法を必ず伝えることも欠かせません。ルールが文書化されていないと、善意のエンジニアでも誤った運用をしてしまいます。
「自分は大丈夫」という過信が、最大のリスクです。インシデントが起きたときのリカバリーコストと比べれば、今日から始める予防策への投資はごくわずかなものです。