GitHubの秘密鍵漏えいを防ぐ、push後では遅い二段構え

|著者: QUASA編集チーム|2 分で読めます
GitHubの秘密鍵漏えいを防ぐ、push後では遅い二段構え

秘密鍵やAPIキーをGitHubのリポジトリへ誤って登録しないためには、開発端末のpre-commitでコミット前に検査し、GitHubのpush protectionで送信時にも止める。secret scanningのアラートは、登録後に見つかった認証情報への対応にも使う。送信を止めてもローカルのコミットに値が残るため、検査を置く段階を分ける必要がある。

設定に入る前に、リポジトリの公開範囲と契約を確認する。GitHubの利用条件では、公開リポジトリのsecret scanningは無料で自動実行され、組織所有の非公開・内部リポジトリではGitHub TeamまたはGitHub Enterprise CloudでGitHub Secret Protectionを有効にする必要がある。公開リポジトリでも、検出結果を開発者が受け取るユーザー向けアラートは、スキャンの自動実行と分けて確認する。

公開範囲とアラートの受け手を決める

公開リポジトリでは、自動スキャンが動いていることだけで設定を終えず、ユーザー向けアラートを誰が確認するか決める。検出された値がどのサービスで発行されたかを追える人がいなければ、アラートを見ても失効の判断が遅れる。管理者と認証情報の発行元を結び付けておくことが、検出後の対応を具体的にする。

組織所有の非公開・内部リポジトリでは、まずGitHub Secret Protectionを利用できる契約と対象リポジトリを確認する。利用できる場合はリポジトリの[Settings]から[Advanced Security]へ進み、[Secret Protection]を有効にする。組織で複数のリポジトリを扱うなら、セキュリティ設定の適用範囲も確認し、新しく作ったリポジトリが対象から漏れない運用にする。

secret scanningは、知られている形式の認証情報を検出する仕組みであり、任意の文字列をすべて秘密情報と判定するわけではない。独自形式の鍵や設定値を扱う場合は、検出されなかったことだけを安全の根拠にしない。鍵をソースコードへ直接書かず、実行環境で必要な値を取得する設計も併せて決めておく。

GitHubでpush protectionを有効にする

push protectionは、対応するシークレットを含むpushをリポジトリに到達する前にブロックする。リポジトリの所有者、組織の所有者、セキュリティマネージャー、管理者権限を持つ人が、GitHubの有効化手順に沿って[Settings]→[Advanced Security]を開く。[Secret Protection]が無効なら有効にし、同じ欄の[プッシュ保護]を有効にする。

ブロックされた開発者には、表示されたファイルと値の種類を確認し、実際の鍵ならコミットから除くよう伝える。誤検知や検査用の値について例外を認める場合も、理由を確認して扱う。例外を日常的な通過手段にすると、送信前に止める設定の意味が薄れる。

コマンドラインでのpush protectionは、GitHubへ送る時点で働く。ブロックの通知が出る前にローカルのコミットは作られており、秘密情報がその履歴に残っている可能性がある。また、検査は対応するパターンが対象で、すべての鍵を必ず止める保証はない。このため、コミットを作る前の検査を開発端末にも置く。

pre-commitとTrivyでコミット前に検査する

デジタル庁の実装例は、pre-commitフックからTrivyのシークレット検査を実行し、検出時には失敗としてコミットを止める構成を示している。これはGitの記録に値が入る前の防止策だ。同じ実装例は、push後に検出した鍵については速やかなローテーションが必要だとしている。

  1. リポジトリにpre-commitとTrivyの設定を置く。Trivyではシークレット検査を指定し、検出したときの終了コードを失敗にする。pre-commitにはTrivyを呼び出すローカルフックを登録する。
  2. 各開発端末でフックをインストールする。設定ファイルをリポジトリへ追加しただけでは、端末側のGitフックは有効にならない。新しい端末や作り直した開発環境にも、インストール手順を含める。
  3. 導入時には既存ファイルを対象に手動実行し、検査の範囲を確認する。安全なダミー値を使ってコミットが止まることを確かめたら、その値を作業ツリーから取り除く。

デジタル庁の例は「trivy fs」で作業ディレクトリを検査する構成で、ステージした差分だけを検査する設定ではない。未追跡のファイルや大きな生成物を含む開発環境では、実行時間と対象範囲を確かめて調整する。検査対象を狭める場合も、コミットされ得る設定ファイルや認証情報の置き場所を外さないことが重要だ。

フックが値を検出したら、表示された場所を確認してファイルから除き、改めてコミットする。共有する設定例には実際の鍵を入れず、必要な項目名だけを残す。ローカルフックは端末ごとの設定に依存するため、GitHub側のpush protectionも有効にして送信時の確認を残す。

止めた段階に応じて履歴と鍵を処理する

コミット前に検出した値は、追跡対象のファイルから取り除く。別の追跡対象ファイルへ移しただけでは、次のコミットで同じ値が記録される。アプリケーションが必要とする認証情報は、コード外の管理手段から取得する形に直す。

push protectionで送信を止めた場合は、作業ツリーの値を消すだけでなく、秘密情報を含むローカルコミットを修正する。最新のコミットに入れた値なら、そのコミットを修正してから送信し直す。さらに前のコミットに含まれる場合は、どの履歴まで修正する必要があるかを先に特定する。削除だけを新しいコミットとして積んでも、古いコミットの値は残る。

既にリポジトリへ送られた鍵は、発行元のサービスで速やかに失効またはローテーションする。新しい鍵を利用先へ反映し、古い鍵が使えなくなったことを確認する。ファイルや履歴から文字列を削除しても、発行済みの鍵そのものは無効にならない。共有済みの履歴を書き換える必要がある場合は、共同作業者の複製やブランチに値が残る可能性も踏まえて調整する。

関連記事:

共有:

ニュースレターを購読

Web3、AI、暗号資産の最新ニュースを受信箱にお届けします。

0