🎧 Listen to this article: English
🌍 Read this in your language: हिंदी · தமிழ் · తెలుగు · ಕನ್ನಡ · മലയാളം · ଓଡ଼ିଆ · 日本語 · 中文
今週、誰かに「あの本番用設定ファイルはどこにあるの?」という退屈な質問をされました。その20分後、私はGitリポジトリに置かれた、チーム全員や過去にクローンしたことのある人なら誰でも読み取れる状態の有効なクラウドアクセスキーを眺めていました。
今日は2026年9月29日ですが、非常に現代的な理由からこのような事態が頻発しています。各チームは既存の製品にAI機能を組み込もうと急いでおり、新しい統合を行うたびに、モデルのAPIキー、クラウドサービスアカウント、ストレージの認証情報といった新しいキーが増えていきます。これらのキーはどこかに保存する必要があり、最も手軽な場所がアプリケーションの設定ファイルなのです。そのファイルがすでにGitで追跡されている場合、誰かがコミットした瞬間にシークレットが公開されてしまいます。
この記事の主旨は「シークレットをコミットしてはいけない」ということではありません。そんなことは誰もが知っています。重要なのは、シークレットを発見したときにどうすべきかということです。なぜなら、誰もが思いつく直感的な行動は間違っているからです。
それは退屈な質問から始まりました
私はある .NET アプリケーションを見ていました。問題の設定ファイルは appsettings.Production.jsonで、これは .NET アプリが本番環境の設定を保存する標準的な場所です。ファイルは同時に3つの異なる場所に存在するため、疑問は単にどのコピーが信頼できるものかということでした:
- ソースツリー内、つまりリポジトリの中
- 実行中のコンテナ内、デプロイされたパス
- デプロイ時にビルドパイプラインによって書き換えられ、データベースの接続文字列が注入されたもの
この3つ目が重要です。パイプラインが 一部の 値をデプロイ時に上書きするため、 すべての 値を上書きすると勘違いしやすいのです。しかし実際は違います。パイプラインが注入しないものは、コミットされたそのままの状態で使用されます。
最初に確認すべきは、ファイルが追跡されているかどうかです
これは1行で確認でき、不確かな設定ファイルがあれば実行しておく価値があります:
git ls-files --error-unmatch path/to/appsettings.Production.json
このコマンドが成功した場合、ファイルは追跡されています。つまり、リポジトリとその履歴の中に存在しています。私のケースでは成功し、 .gitignore には設定ファイルに関するルールが全くありませんでした。
中には、データベース接続文字列、複数のパスワード、Webプッシュ通知キー、AIモデルのAPIキー、クラウドアクセスキーのペアなど、およそ十数のシークレットが含まれていました。
なぜ「削除すればいい」が通用しないのか
ここで人々が驚く事実があります。ファイルからシークレットを削除し、その変更をコミットしても、シークレットは削除されません。
Gitは現在の状態だけでなく、履歴を保存します。古いコミットはまだ存在しているのです。誰でも次のように実行できます:
git log --oneline -- path/to/appsettings.Production.json
git show <old-commit>:path/to/appsettings.Production.json
そして、元の値を読み取ることができます。リポジトリのすべてのクローンは、その完全な履歴を保持しています。そのため、昨年プロジェクトをクローンした開発者のノートパソコンには、あなたがシークレットを「削除」した後であっても、依然としてシークレットが残っているのです。
専用のツールを使って履歴を書き換えることは可能ですが、それにはフォースプッシュが必要であり、既存のすべてのクローンを破壊し、決定的なことに、すでに人々が持っているコピーに対しては何も対処できません。履歴の書き換えはクリーンアップ(整理)であって、レメディエーション(修復)ではありません。
漏洩を実際に無効化する唯一の行動は、シークレット自体を変更することです。
誰が実際にそれを持っているかを把握する
この問題の緊急度を判断する前に、所持者の数を正直に数えてみましょう。一般的な小規模チームでも、そのリストは見た目より長くなります:
- リポジトリへのアクセス権を持つ現在のすべての開発者
- 過去にクローンしたことがあり、あなたがもう管理していないノートPCを持つ、元開発者や請負業者全員
- ビルドエージェントの作業ディレクトリとそのキャッシュ
- サーバーおよび仮想マシンのバックアップとスナップショット
- リポジトリのすべてのミラー
最後のグループは忘れがちです。バックアップは永続的に保存されるように設計されていますが、これは漏洩した認証情報にとってはまさに最悪の性質です。
そのキーで実際に何ができるのかを調べる
深刻度は漏洩の事実にあるのではありません。特権にあります。1つのストレージバケットの読み取り専用キーと、管理キーとでは、問題の性質が大きく異なります。
ここでのユーザーアカウントは、まるでストレージ専用アカウントのような名前が付けられていました。しかし違いました。実際の権限を確認すると、別の事実が判明しました:
aws iam list-attached-user-policies --user-name app-s3
aws iam list-user-policies --user-name app-s3
aws iam list-groups-for-user --user-name app-s3
すべてのバケットにわたる完全なストレージアクセス権、本番環境で実行されているコンピュートサービスの完全な制御を付与するグループへのメンバーシップ、および会社のドメインとしてメールを送信する権限を持っていました。範囲が狭いことを暗示する名前の裏に、広範な権限があったのです。
そして、タイムラインを決定づける質問です:
aws iam get-access-key-last-used --access-key-id AKIAEXAMPLEKEYID
それはその日の朝に使用されていました。つまり、そのキーは忘れ去られた残留物ではなかったのです。本番環境の何かがそれに依存しており、即座に削除すればシステム障害を引き起こしていたことを意味します。
ただ無効化するのではなく、ローテーションする
この最後の詳細によって計画が変わります。現在使用中で有効な認証情報には、突然の無効化ではなくロールオーバーが必要です。本番環境を壊すことなく脆弱性を塞ぐ手順は以下の通りです。
ステップ 1: キーが有効であることを確認し、その影響範囲を特定する
上記の権限確認と最終使用チェックを実行します。キーの名前ではなく、キーで何ができるかに基づいて緊急度を判断します。
ステップ 2: 最初のキーと並行して2つ目のキーを作成する
ほとんどのクラウドプロバイダーは、安全にロールオーバーできるように、ユーザーごとに2つの有効なアクセスキーを許可しています。
aws iam create-access-key --user-name app-s3
まだ古いキーには触れないでください。
ステップ 3: 新しいキーをリポジトリ以外の場所に配置する
パイプラインがすでに使用しているシークレットストアに移動します。ほとんどのチームはすでにそれを持っていますが、単に一貫して使用していないだけです。ビルドからそれを参照し、デプロイ時に値が注入されるようにして、ソースに書き込まれないようにします。
ステップ 4: デプロイと検証
再デプロイし、キーを使用していた機能が引き続き動作することを確認します。私のケースでは、送信メールとファイルストレージのチェックを意味しました。無効化する前に検証してください。決して無効化の後に検証してはいけません。
ステップ 5: 古いキーを非アクティブ化する
最初に削除するのではなく非アクティブ化します。なぜなら、コンシューマーを見落としていた場合でも、非アクティブ化であればすぐに元に戻せるからです。
aws iam update-access-key --user-name app-s3 --access-key-id AKIAEXAMPLEKEYID --status Inactive
数日間エラーを監視し、その後削除します。
ステップ 6: ここで初めて、リポジトリをクリーンアップする
git rm --cached path/to/appsettings.Production.json
echo "appsettings.Production.json" >> .gitignore
このステップは意図的に最後にしています。これは次の漏洩を防ぐためです。今回の漏洩を修正するものではありません。
ステップ 7: ついでに権限を厳格化する
ストレージ用と名付けられたアカウントが本番環境のコンピュートを制御していたなら、それも修正してください。過剰な権限を持つキーをローテーションしても、新しい過剰な権限を持つキーが手に入るだけです。
結論
Gitでシークレットを発見したときの直感は、それを削除して安心することです。その直感は、見た目がきれいなリポジトリと変わらないリスクを生み出します。履歴は永続的であり、クローンは至る所にあり、バックアップは物事を永久に保存するように作られています。真に役立つ唯一の方法は、認証情報を置き換えることであり、しかも途中で本番環境をダウンさせない順序で行うことです。それが有効であるかを確認し、何ができるかを測定し、新しいキーをロールインして検証し、古いキーをオフにします。リポジトリのクリーンアップは最後のステップであり、最初ではありません。
メリット
- 検出チェックは単一のコマンドで、どのリポジトリでも機能する
- ファイルの削除や履歴の書き換えとは異なり、ローテーションは恒久的な修正である
- 2つ目のキーを使用したロールオーバーにより、稼働中のシステムのダウンタイムが発生しない
- ローテーション中に権限を監査することで、過剰な権限を持つアカウントが判明することがよくある
- シークレットを既存のシークレットストアに移動する場合、通常、新しいツールは不要である
- 最終的な削除まで、プロセス全体は元に戻すことができる
デメリット
- ローテーションにはキーのすべてのコンシューマーを見つける必要があり、それが文書化されていることは稀である
- 最初の漏洩を取り消すことはできず、その価値を制限することしかできない
- 履歴の書き換えは既存のクローンを破壊し、チームにとって混乱を招く
- すでにノートパソコンやバックアップにコピーされたシークレットは管理外となる
- クリーンアップは機能開発と時間を奪い合い、後回しにされやすい
- 一部の古いシステムでは、認証情報のローテーションが非常に厄介な場合がある
注意
この記事は教育目的であり、あなたの環境への処方箋ではなく、一般的なアプローチを説明しています。ここにあるすべてのコマンド、ファイルパス、アカウント名、キー識別子はプレースホルダーであり、あなた自身のシステムのシステム値に置き換える必要があります。コンシューマーを見逃すと、認証情報のローテーションにより稼働中のサービスが中断される可能性があるため、まず非本番環境で各手順を検証し、キーを非アクティブ化する前に何がキーに依存しているかを確認し、ここに書かれていることを鵜呑みにする前に、クラウドプロバイダーとツールの最新のドキュメントを確認してください。
よくある質問
- Gitリポジトリからシークレットを削除すれば、それは削除されますか? — いいえ。その値はコミット履歴や既存のすべてのクローンに残るため、リポジトリを持っている人なら誰でも依然として読むことができます。
- 漏洩したシークレットを修正するには、Gitの履歴を書き換えるだけで十分ですか? — いいえ。リポジトリはクリーンアップされますが、人々がすでにクローンしたコピーに対しては何もできないため、やはり認証情報をローテーションする必要があります。
- 設定ファイルがGitで追跡されているかどうかはどうやって確認しますか? — 以下を実行します:
git ls-files --error-unmatch <path>。成功した場合、ファイルは追跡されており、その内容は履歴に存在します。 - 漏洩したキーはすぐに削除すべきですか? — それが使用されていない場合のみです。本番環境の何かがそれに依存している場合は、まず代わりのものを作成してデプロイし、検証してから古いものを非アクティブ化します。
- 漏洩したクラウドキーがまだ使用されているかどうかはどうすればわかりますか? — ほとんどのプロバイダーはアクセスキーの最終使用タイムスタンプを公開しており、コンシューマーがまだそれに依存しているかどうかがわかります。
- 代わりに、アプリケーションのシークレットはどこに置くべきですか? — シークレットストア、またはビルドシステムの認証情報ストアに置き、デプロイ時に注入して、値がソース管理に表示されないようにします。
- なぜデプロイメントパイプラインはシークレットを保護しなかったのですか? — パイプラインはデータベース接続文字列などの一部の設定のみを注入し、その他のすべての値はコミットされたとおりに残すことがよくあります。
- このようなことが再び起こらないようにするにはどうすればよいですか? — 設定ファイルを以下に追加し、
.gitignore、リポジトリで自動シークレットスキャンを有効にし、漏洩したキーの価値が可能な限り低くなるように権限を見直します。
タグ
#Security #DevOps #Git #SecretsManagement #CloudSecurity #IAM #KeyRotation #DevSecOps #ConfigManagement #InfrastructureAsCode
Incident Response: First Hour
A calm, evidence-preserving checklist for establishing control, bounding impact, communicating clearly, and containing an incident safely.
Free. No spam — unsubscribe in one click.


Responses
Sign in to leave a response.