前置き
サービスから他のサービスへ接続するための鍵情報はどこに置くべきでしょうか?
コード中に書く、というのが一番ラクではあるのですがセキュリティ的にはよろしくないですね。
GCPだと鍵のようなシークレット管理サービスとしてsecret managerがあります。
GCP secret manager 概要
基本の使い方
鍵を保存、取得してくること自体は割と簡単です。
基本的にはWeb UIから鍵を設定して、アプリ中で呼び出す、という形になるはずです。
GCP secret manager quick start
鍵の登録
まずsecret manager APIを有効にしておきます。
GCP consoleのsecret manager設定画面に行きます。
この画面から鍵の登録が出来ます。
鍵へのアクセス
pythonだと以下のようなスクリプトでアクセス可能です。
from google.cloud import secretmanager
client = secretmanager.SecretManagerServiceClient()
# ここでプロジェクト名(project_id)、鍵の名前(secret_id)、バージョン(version_id)を指定します。
# 基本は最新バージョンを使うはずですが、その場合はversion_id="latest" でアクセス可能です。
name = client.secret_version_path(project_id, secret_id, version_id)
response = client.access_secret_version(name)
# これで登録していた鍵情報が表示できれば成功です。
payload = response.payload.data.decode('UTF-8')
print('Plaintext: {}'.format(payload))
簡単ですね!基本はこのようなスクリプトをパクれば動くはずです。
しかし権限と環境によってアクセス出来たり出来なかったりするので注意が必要です。
権限と環境
「Secret Manager のシークレットアクセサー」(roles/secretmanager.secretAccessor)の権限が無いとsecret managerで管理している情報は見ることができません。
ちゃんとIAMの設定をしないとローカルだとうまくいくのにプロジェクト上では動かない、みたいなパターンが起こりえます。
ローカル環境
オーナー権限(owner)だとsecret managerにアクセス出来ますが、編集者権限(editor)だとアクセスは不可です。
あなたが「編集者」でローカルでの開発が必要なら権限を付与してもらいましょう。
ステージング、本番環境
もちろんアプリからはアクセスするでしょうからサービスアカウントにも忘れず付与しましょう。
ステージングだと設定してたのに本番のプロジェクトだと忘れてた……となってしまう可能性もあるので気をつけて。
テスト環境
CIのテストが通らない!というパターンもありえます。ここに関してはCIのエージェントに付与する、というよりはテストではsecret managerにアクセスせずにダミーの鍵で成功するようにしたほうが良いかもしれません。鍵は機密情報ですからできるだけアクセスできる範囲を狭めるべきです。
また実行環境のプロジェクトがステージング、本番と異なるのでそもそもアクセス出来ないというケースもありえます。上記スクリプトは内部でGCPに対してAPIを叩いており、そのURI中でプロジェクト名を指定しているため(引数で指定しているproject_idとは別)仮に実行元のプロジェクトが異なる場合は403エラーが返ってくるはずです。
アクセス時に上手くいかない場合はログにエラー原因や実際に叩かれていたURIが示されてるはずなので、それを頼りにコードやGCPの設定を修正しましょう。
鍵の更新
鍵を変更するぞ、となったとき、version_id="latest"にしていればコードの変更無しに、新しいバージョンを追加すればすぐ更新できます。ただアプリ側に反映されてるかは要確認です。おおよそアプリ起動時に鍵情報をconfigとして設定し、それ以降は更新しない、という実装が普通ではないでしょうか。そのためインスタンスが再起動されないと古い鍵情報のままという危険性があります。仮にアプリに新しい鍵情報が反映されてないようなら再起動が必要かもしれません。オートスケールならほっといても再起動されてるかもですが、トラフィックを切り替えてみるとかでも良いです。
最後に
実装自体は比較的簡単ですがIAMの設定に失敗するとサービスがロクに動かず大惨事……ってなことになるのでしっかり動作確認をしましょう。
もっともsecret managerに置いてるから絶対大丈夫!ってものでも無いですが、最低限機密情報をコードとは別枠で管理するように変えましょう。