gitのclean filterとsmudge filterを使ったCloud KMSのよる透過的な暗号化

HoteKanの開発担当者です。

gitで管理するプロジェクトに秘密情報が入ったファイルを配置する場合、暗号化してgitリポジトリに含めるという選択肢があります。

前回の記事(cloud-buildでのgithub連携とファイルの暗号化・復号化)ではそられのファイルをcloud KMSを使って暗号化し、Cloud Buildでのビルド中に復号する方法を紹介しました。

今回はそれらのファイルをgit管理する際に暗号化、複合化を意識することなく透過的に行う方法を紹介します。

gitのclean filterとsmudge filter

gitにはcleanフィルタ、smudgeフィルタという機能があります。これらのフィルタを使えば特定のパスにフィルタを設定し、ステージングの直前とチェックアウトの直前に処理を行うスクリプトを設定できます。

フィルタをかける対象の指定とフィルタの指定は.gitattributesファイルで行い、フィルタの内容自体はgit configで設定します。

cleanフィルタに暗号化、smudgeフィルタに復号化のスクリプトを設定すれば、ワーキングツリー内では復号化したファイルとして扱いながら、インデックス、リポジトリでは暗号化した状態で管理できます。

秘密情報ファイルを更新するたびにいちいち暗号化を自分で行う必要はなくgitに任せることもできます。

cloud KMSを使った暗号化・復号化をgitのフィルタに設定する

以下では上記のフィルタでCloud KMSを使って特定のファイルの暗号化・復号化の方法を紹介します。

.git/configにフィルタを定義します。

[filter "cloud-kms"]
  smudge = .gitencrypt/smudge_filter_cloud-kms
  clean = .gitencrypt/clean_filter_cloud-kms

.gitattributesファイルでフィルタをかける対象とフィルタの名前を指定します。

* filter=cloud-kms

.gitencrypt/smudge_filter_cloud-kmsではCloud KMSでファイルの中身を復号化します。

#!/bin/bash

gcloud kms decrypt \
  --ciphertext-file=- \
  --plaintext-file=- \
  --location=global \
  --keyring=[KEYRING-NAME] \
  --key=[KEY-NAME]

smudgeフィルタでは対象ファイルの内容が標準入力からインプットされます。またフィルタ後の内容は標準出力にアウトプットする必要があります。gcloud kms decryptコマンドでは--ciphertext-file=-で入力として標準入力を、--plaintext-file=-で出力として標準出力を指定できます。

.gitencrypt/clean_filter_cloud-kmsではCloud KMSでファイルの中身を暗号化します。

#!/bin/bash

gcloud kms encrypt \
  --plaintext-file=- \
  --ciphertext-file=- \
  --location=global \
  --keyring=[KEYRING-NAME] \
  --key=[KEY-NAME]

cleanフィルタでも標準入力からインプットされ、標準出力にアウトプットします。gcloud kms encryptコマンドでも-で標準入出力を指定できます。

上記の設定でステージングの際に暗号化、check outの際に復号化が自動で行われます。ワーキングツリーでは暗号化を気にせず編集できます。

git diffでは復号化された状態で比較したい

上記設定後もgit diffではバイナリファイルとして処理されて変更点は見えません。git diffでも復号化した状態を利用したい場合は以下の設定を行います。

.gitattributesでは上で説明したフィルタの設定に加えdiffの設定を追記します。

* filter=cloud-kms diff=cloud-kms

.git/configではtextconv属性を設定します。

[diff "cloud-kms"]
  textconv = cat

.git/configファイルではファイル名が引数として与えられます。ここではそのファイル内容をそのまま表示しています。

リファレンスにも書いてある箇所は見つけられなかったのですが、diff.driver.textconvにコマンドが与えられると、textconvが適用される前にsmudgeが適用されます。

そのためここではファイルの内容がすでに復号化された状態なので、内容をそのまま出力します。diff.driver.textconvにコマンドが設定されていないとsmudgeフィルタの適用もないので、この設定が必要になります。

注意すべき点

新規にcheck outしたり、indexを作り直した際に何も変更していなくても、暗号化対象ファイルがmodifiedなになることがあります。

そのため秘密ファイルを扱うローカルリポジトリは1つにして、後のローカルリポジトリでは暗号化された状態で扱うのがいいのかもしえません。

とはいえ、上記に注意すればかなり便利に使えます。

関連記事

  1. CSS/UIフレームワークに対応したAdobe XDのUIキット一覧

  2. Cloud BuildでのGitHub連携とファイルの暗号化・復号化

  3. webpackがモジュールのimportを解決する仕組み

  4. firebase Javascript SDK をIE11対応にする

  5. アプリ設計におけるUI検討の難しさとAdobe XD

  6. VS Codeでprettier拡張機能を使ってvueファイルをフォー…

PAGE TOP