retlat's blog

Secret Manager のベストプラクティスはちゃんと読んだ方が良いという話

これは Google Cloud Platform Advent Calendar 2021 4 日目の投稿です。

今日は Secret Manager についてです。
今年は無料枠に追加されるなどアップデートがありました。
ただその中にはベストプラクティスでは使うのは避けた方が良いとされているものがあります。

例えば Cloud Run および Cloud Functions では、 Secret を

  • 環境変数に設定する
  • ファイルとしてマウントする

という機能が提供されるようになりました

ところがこれらは

ファイル システムでシークレットにアクセスできると、攻撃者がシークレット マテリアルを読み取ることができるため、ディレクトリ トラバーサル攻撃などのアプリケーションの脆弱性が深刻化する可能性があります。

環境変数を介してシークレットが使用されると、デバッグ エンドポイントの有効化やプロセス環境の詳細をログに記録する依存関係などの構成ミスにより、シークレットが漏洩する可能性があります。

という理由で可能な限り避けるように書かれています。

ただ現実として環境変数で設定できると開発者ごとの違いを吸収しやすいのは事実です。
そこで Cloud Run には実行するコンテナに自動で設定される環境変数があるので、

package main

import (
	"context"
	"os"

	secretManager "cloud.google.com/go/secretmanager/apiv1"
	secretManagerPB "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
)

func FetchPassword() string {
	// Cloud Run のみに存在する環境変数をチェックして
	_, ok := os.LookupEnv("K_SERVICE")
	if !ok {
		// 未設定の場合には環境変数から取得
		return os.Getenv("PASSWORD")
	}

	// 設定されている場合には Secret Manager にアクセス
	ctx := context.Background()
	c, _ := secretManager.Client(ctx)
	r := &secretManagerPB.AccessSecretVersionRequest{ Name: "1" }
	s, _ := c.AccessSecretVersion(ctx, r)
	return s.Payload.Data
}

といった形で使っていくのが良さそうだと思っています。

ということで良い機能だなと思っても 1 回立ち止まってベストプラクティスを読んでみる方が良いというお話でした (自戒を込めて)。