[GCP] berglasを使って機密情報を安全にアプリケーションに受け渡す
はじめに
アプリケーションには、DBの認証情報やAPIキーなど、リポジトリにはコミットするべきではない機密情報がつきものですよね。AWSでは、情報を暗号化/復号化するための鍵を管理するAWS KMSというサービスと、鍵を使って情報を管理するためのAWS Systems Manager パラメータストアやAWS Secrets Managerというサービスが統合されており、それらを使うことで機密情報を管理することができ、他のAWSのサービスとも統合されているのでアプリケーションへの受け渡しも容易です。
GCPでは、Cloud KMSという鍵を管理するためのサービスはありますが、鍵を使って情報を管理するためのサービスはないため、GCPが開発しているOSSのBerglasというツールか、HashiCorp社のOSSであるVaultを使って管理することが推奨されています。
本記事ではBerglasについて紹介します。
Berglasとは
BerglasはGoで作られたCLIツールです。ざっくり説明してしまうと、鍵の管理にCloud KMSを使い、暗号化した情報の管理にCloud Storageを使い、それらの操作をいい感じにラップしてくれているツールです。Vaultと違って管理するサーバが無いので、容易に使うことができます。監査ログとしてはCloud KMSやCloud Storageの監査ログが使えますが、それ以上の管理機能はないので、より厳密な管理を求められる場合はVaultを使うという棲み分けになるかと思います。
セットアップ
手元の環境にCloud SDKはインストールされているものとします。
berglasはバイナリをダウンロードするか、Macであればbrewでインストールできます。
$ brew install berglas
必要なサービスを有効化します。
$ gcloud services enable --project ${PROJECT_ID} \ cloudkms.googleapis.com \ storage-api.googleapis.com \ storage-component.googleapis.com
bootstrapコマンドでCloud KMSにKeyRingとKeyが、Cloud Storageにバケットが作成されます。
$ berglas bootstrap --project $PROJECT_ID --bucket $BUCKET_ID
値の登録・取得
create
コマンド、登録したい値をKeyとValueのペアで登録します。
$ berglas create ${BUCKET_ID}/${Key} ${Value} \ --key projects/${PROJECT_ID}/locations/global/keyRings/berglas/cryptoKeys/berglas-key
grant
コマンドで、ユーザやサービスアカウントにアクセス権を付与します。
$ berglas grant ${BUCKET_ID}/${Key} --member user:${UserAccount}
Google App Engineの場合は、GAEのサービスアカウントを指定します。
$ berglas grant ${BUCKET_ID}/${Key} --member serviceAccount:${AppName}@appspot.gserviceaccount.com
access
コマンドで、値を取得します。
$ berglas access ${BUCKET_ID}/${Key}
Google App Engineで利用する
アプリケーションで利用する場合は、berglas exec
コマンドを利用すると値を復号化して環境変数にセットしてくれます。このコマンドは、特定の値がセットされている環境変数に復号化した値をセットして、子プロセスに引き継ぐことができるようになっています。
READMEのIntegrationsでは、Google App Engine(Standard環境)で利用する場合は、goランタイムのみで利用できると書かれていますが、Cloud Buildと組み合わせることでどのランタイムでも利用することができます。
まず、Cloud Buildでプロジェクトの直下にberglasのバイナリをダウンロードして配置し、実行権限を付与します。
steps: - name: gcr.io/cloud-builders/curl args: - https://storage.googleapis.com/berglas/master/linux_amd64/berglas - --output - berglas - name: ubuntu args: - chmod - "777" - berglas - name: gcr.io/cloud-builders/gcloud args: - app - deploy - app.yaml
そして、app.yaml の entrypoint
で berglas exec
を実行してアプリケーションプロセスを起動します。
以下はNode10のランタイムの例です。DBのユーザ名とパスワードはberglasで予め登録されているものとします。 app.yaml の env_variables
に以下のように berglas://{BUCKET_ID}/{KEY}
を指定します。そうすると berglas exec
が実行されたときにこの値が復号化された値に置き換わり、 npm start
のプロセスへ引き継がれます。
runtime: nodejs10 entrypoint: ./berglas exec -- npm start env_variables: NODE_ENV: 'production' DB_USERNAME: berglas://{BUCKET_ID}/db-username DB_PASSWORD: berglas://{BUCKET_ID}/db-password
【注意】プロジェクトのルートにcloudbuild.yamlとapp.yamlの両方があると、GAEのビルド時にエラーになります。GAEのビルドにもCloud Buildが使われるため、内部的にcloudbuild.yamlを配置しようとするが既にcloudbuild.yamlがあるので配置できない、ということだと思います。cloudbuild.yamlの名前を変えることで解決できます。