Git
Node.js
AWS
git-secrets

Node.jsスクリプトでAWSアクセスキーの誤コミットを防ぐ

はじめに

この記事は、Node.jsのスクリプトを使用し、gitのpre-commitフックの段階でAWSアクセスキーの混入を検出し、コミットを強制的に停止する手法を検証するためのものです。

問題

AWSのアクセスキーの検出とコミット防止の手段はgit-secretsがあります。このソフトは高速にコードをスキャンしアクセスキーの検出と流出防止をしてくれます。AWS-Labsで開発されていることもあり、信頼性も高いです。

導入が難しい

git-secretsはシェルスクリプトで構成されています。macの場合Homebrewで一括インストールすることができますが、構成はpackage.jsonに残りません。各メンバーがセットアップを行う必要があります。

git-secretsをGUIアプリケーションから操作する場合、アプリ内蔵のgitに対してシンボリックリンクを通すか、使用するgitをシステムのものに切り替える操作が必要になります。
git-secretsをSourceTree (Macintosh)で使えるようにする手順
GitHub Desktopでもgit-secretsが使いたい

また、グローバルにインストールした場合、アンインストールの際に注意が必要です。
[git] git secretsを削除する時の注意

リポジトリからクローンを行い

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のアクセスキーを検出する
  • キーが存在した場合コミットの処理を強制停止する

の条件が満たせれば問題を解決できるのではないかと考えました。

検証

というわけでスクリプトを組んでみました。
https://github.com/MasatoMakino/node-secrets

動作検証の手順

  • リポジトリをローカルにクローン
  • npm installyarnして依存パッケージを取得
  • AWSのキーを含むテキストファイルをaddする
  • コミットするとpre-commitフックで蹴られる
  • pretty-quickと共存して動作する

という一連の動作が確認できると思います。

CLIモジュールとしての導入方法

2018/09/12追記

こちらの記事を参考に検証スクリプトをCLIモジュールに修正、更新しました。ありがとうございます。
3分でできるnpmモジュール

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 を使う
の記事にあるように、git-secretsがテスト用のダミーキーを用意してくれているのでそれが引っかかるかどうかを試してください。

未検証の部分

このスクリプトでは以下の点は未検証です。

  • 誤検出 / 検出すり抜けの可能性
  • 大規模なリポジトリでのパフォーマンスの問題
  • バイナリを正常に切り分け可能か否か

あくまで提案の検証用ですのでご注意ください。