はじめに
この記事は、Node.jsのスクリプトを使用し、gitのpre-commitフックの段階でAWSアクセスキーの混入を検出し、コミットを強制的に停止する手法を検証するためのものです。
問題
AWSのアクセスキーの検出とコミット防止の手段はgit-secretsがあります。このソフトは高速にコードをスキャンしアクセスキーの検出と流出防止をしてくれます。AWS-Labsで開発されていることもあり、信頼性も高いです。
導入が難しい
git-secretsはシェルスクリプトで構成されています。macの場合Homebrewで一括インストールできますが、構成はpackage.jsonに残りません。各メンバーがセットアップを行う必要があります。
git-secretsをGUIアプリケーションから操作する場合、アプリ内蔵のgitに対してシンボリックリンクを通すか、使用するgitをシステムのものに切り替える操作が必要になります。
また、グローバルにインストールした場合、アンインストールの際に注意が必要です。
リポジトリからクローンを行いyarn
を実行してくださいという一言で説明が終わる環境と比べると、導入の手間は大きいです。
huskyとバッディングする
huskyは、gitのpre-commitフックを手軽にpackage.json上で定義できるパッケージです。
▼package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"...": "..."
}
}
}
このようにgitの各種hookを定義することでpackage.json内のスクリプトを呼び出すことができます。
たとえばpretty-quickと併用することで、コミット前にstage上のファイルをPrettierで整形したあとコミットするというような使い方ができます。
しかし、このパッケージはgit-secretsとバッティングします。gitのhookファイルをインストール時に書き換えてしまうため
git secrets --install
で生成したファイルを上書きしてしまいます。この問題はhuskyに限らずhookファイルを書き換えるパッケージ全般で発生します。
もちろんhookファイルを手作業でマージすれば両方の機能を併用することはできますが、パッケージの再インストール時には破壊されてしまうため運用が難しくなります。
対策の提案
上記の問題の対策として
- node.jsで稼働するスクリプトにする(huskyとの共存)
- pre-commitフック段階でAWSのアクセスキーを検出する
- キーが存在した場合コミットの処理を強制停止する
の条件が満たせれば問題を解決できるのではないかと考えました。
検証
というわけでスクリプトを組んでみました。
動作検証の手順
- リポジトリをローカルにクローン
-
npm install
かyarn
して依存パッケージを取得 - AWSのキーを含むテキストファイルをaddする
- コミットするとpre-commitフックで蹴られる
- pretty-quickと共存して動作する
という一連の動作が確認できると思います。
CLIモジュールとしての導入方法
2018/09/12追記
こちらの記事を参考に検証スクリプトをCLIモジュールに修正、更新しました。ありがとうございます。
GitHubのURLを指定して、npmかyarnでモジュールを読み込みます。
yarn add https://github.com/MasatoMakino/node-secrets -D
node-secrets
コマンドで、npm-scriptsやhuskyから呼び出しができます。
▼package.json
"scripts": {
"secrets": "node-secrets"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged && node-secrets"
}
}
テストの際の注意
テストに本物のキーを使用するのは絶対に避けてください。
こちらの記事にあるように、git-secretsがテスト用のダミーキーを用意してくれているのでそれが引っかかるかどうかを試してください。
未検証の部分
このスクリプトでは以下の点は未検証です。
- 誤検出 / 検出すり抜けの可能性
- 大規模なリポジトリでのパフォーマンスの問題
- バイナリを正常に切り分け可能か否か
あくまで提案の検証用ですのでご注意ください。