Git 履歴から機密情報を完全に削除する

What I Learned

誤ってコミットされた機密情報(APIキー、秘密鍵、設定ファイルなど)は、通常の削除では Git の履歴に残り続ける。git filter-repo を使うことで Git の履歴を書き換え、機密情報を完全に削除できる。ただし、履歴から削除しても、すでに漏洩した認証情報が安全になるわけではないため、必ず該当する認証情報は失効・再発行する必要がある。

Details

背景

以前は git filter-branch を用いた方法が紹介されていたが、現在では公式ドキュメントにおいて注意喚起が行われており、新たに手順を作成する場合には git filter-repo の採用が推奨されている。

使用するツール

作業前の注意点

ケース別手順

ケース1:特定のファイルを履歴から完全に削除する

1. ミラークローン

1git clone --mirror REMOTE_URL REPO_NAME.git
2cd REPO_NAME.git

ミラークローンでは、すべてのブランチ・タグ・参照を含めて取得される。履歴を書き換えた結果をリモートへ正確に反映するため、本手順ではミラークローンを使用する。

2. 機密ファイルを履歴から削除

1git filter-repo \
2  --path SENSITIVE_PATH_1 \
3  --path SENSITIVE_PATH_2 \
4  --invert-paths

3. リモートへ反映

1git push --force --all
2git push --force --tags

ケース2:機密文字列(APIキー等)を履歴から削除・置換する

1. ミラークローン

1git clone --mirror REMOTE_URL REPO_NAME.git
2cd REPO_NAME.git

通常のクローンでは一部の参照が含まれないため、履歴改変作業ではミラークローンを使用する。

2. 置換ルールファイルを作成

1cat > replace-rules.txt << 'EOF'
2regex:SECRET_PATTERN_1==>***REDACTED***
3regex:SECRET_PATTERN_2==>***REDACTED***
4EOF

置換ルールの書式:[検索モード]:[検索するパターン]==>[置換後の文字列]

3. 履歴を書き換える

1git filter-repo --replace-text replace-rules.txt

4. リモートへ反映

1git push --force --all
2git push --force --tags

ケース3:複数の機密ファイルと文字列を同時に処理する

 1git clone --mirror REMOTE_URL REPO_NAME.git
 2cd REPO_NAME.git
 3
 4git filter-repo \
 5  --path SENSITIVE_PATH_1 \
 6  --path SENSITIVE_PATH_2 \
 7  --invert-paths \
 8  --replace-text replace-rules.txt
 9
10git push --force --all
11git push --force --tags

作業後に必ず行うこと

重要なポイント

References