ローテーション スケジュールについて

このトピックでは、シークレットのローテーションのコンセプトについて説明します。始める前に、プラットフォームの概要を確認して、Google Cloud の全体像を把握することをおすすめします。また、Secret Manager プロダクトの概要もご覧ください。

はじめに

定期的なローテーションは、次のことに役立ちます。

  • シークレットの漏洩が発生した場合の影響を制限する。
  • シークレットへのアクセスが不要になった個人に対して、古いシークレット値の使用を継続できないようにする。
  • ローテーション フローを継続的に実施し、緊急ローテーションが発生した場合の停止の可能性を軽減する。

Secret Manager には、シークレットシークレット バージョンローテーション スケジュールのコンセプトがあります。これは、ローテーションされたシークレットをサポートするワークロードを構築するための基盤となります。

このトピックでは、Secret Manager に保存されているシークレットのローテーションに関する推奨事項について説明します。以降のセクションでは、次のメリットとトレードオフについて説明します。

シークレット バージョンへのバインディング

Secret Manager のシークレットには、複数のシークレット バージョンを含めることができます。シークレット バージョンには不変のペイロード(実際のシークレットのバイト文字列)が含まれ、順序と番号が付けられます。シークレットをローテーションするには、既存のシークレットに新しいシークレット バージョンを追加します。

シークレットに最近追加されたシークレット バージョンは、latest エイリアスを使用して参照できます。latest エイリアスは、開発には便利ですが、本番環境ワークロードで問題になる可能性があります。これは、不正な値がすぐにロールアウトされ、サービス全体の停止につながる可能性があるためです。次のシナリオでは、シークレット バージョンへのバインディングの代替方法について説明します。

段階的なロールアウト

段階的なロールアウトは、以下のシナリオの指針になります。シークレットのロールアウトをより遅くすることで、破損のリスクを低減できますが、復旧にかかる時間もより遅くなります。一部のシークレットは、外部システム(有効なシークレット値を追跡する API やデータベースなど)で無効になる可能性があります。これらの外部システムは、ロールアウトが必要な場合に、自分で制御と復元ができる場合とできない場合があります。

手動または自動のローテーション中に、不適切な Secret がロールアウトされる可能性があります。強力なローテーション ワークフローでは、破損(HTTP エラー率など)を自動的に検出し、(以前の構成のデプロイによって)古いシークレット バージョンを使用するようにロールバックできる必要があります。

新しいシークレット バージョンのロールアウトは、シークレットがアプリケーションにバインドされる方法によって異なります。

アプローチ 1: 既存のリリース プロセス中に解決する

シークレット バージョンを解決して、アプリケーションのリリースにバインドします。ほとんどのデプロイの場合、これには、最新のシークレット バージョンを完全なシークレット バージョンのリソース名に解決し、フラグとしてアプリケーションで、または構成ファイルでロールアウトすることが含まれます。ローテーション時にシークレット バージョンの名前を解決して、リソース名を耐久性のある場所(Git への commit など)に保存し、デプロイがブロックされるのを防ぐために、push 時にバージョン名をデプロイ構成に入れることをおすすめします。

アプリケーションの起動時に、特定のシークレット バージョン名を指定して Secret Manager を呼び出し、シークレット値にアクセスします。

この方法には次のメリットがあります。

  • 再起動後も同じシークレット バージョンが使用されるため、予測可能性が向上し、運用の複雑さが軽減されます。
  • ロールアウトとロールバックの既存のチェンジ マネジメント プロセスを、シークレットのローテーションとシークレット バージョンのデプロイに再利用できます。
  • 値を段階的にロールアウトして、不正な値のデプロイの影響を軽減できます。

アプローチ 2: アプリの起動時に解決する

アプリケーションの起動時に最新のシークレット ペイロードを取得し、アプリケーションの存続期間中は、そのシークレットの使用を継続します。

このアプローチの利点は、シークレット バージョンの解決に CI/CD パイプラインを変更する必要がないことですが、不正なシークレットがロールアウトされると、インスタンスの再起動時やサービスのスケールアップ時にアプリケーションの起動に失敗し、サービス停止につながる可能性があります。

アプローチ 3: 継続的に解決する

アプリケーションで最新のシークレット バージョンに対して継続的にポーリングし、新しいシークレット値をすぐに使用します。

このアプローチでは、新しいシークレット値を段階的に採用しないため、サービス全体がすぐに停止するリスクがあります。

シークレットをローテーションする

シークレットを動的に更新できる場合(たとえば、シークレットを検証する外部システムが Admin API を提供する場合)は、定期的に実行するローテーション ジョブを設定することをおすすめします。一般的な手順については、次のセクションでサンプルのコンピューティング環境として Cloud Run を使用して、概要を説明します

シークレットにローテーション スケジュールを構成する

シークレットのローテーション スケジュールを設定します。シークレットをローテーションするときに、通知を受け取るように、シークレットに Pub/Sub トピックを構成する必要があります。シークレットにトピックを構成するには、イベント通知のガイドをご覧ください。

Cloud Run を起動して新しいシークレット バージョンを作成する

ローテーション通知を受信してローテーション手順を実施するには、Cloud Run サービスを作成して構成します。

  1. 外部システム(データベース、API プロバイダなど)で新しいシークレットを取得または作成します。

    既存のワークロードが影響を受けないように、この操作によって既存のシークレットが無効化されないようにしてください。

  2. 新しいシークレットを使用して Secret Manager を更新します。

    Secret Manager で新しい SecretVersion を作成します。これにより、latest エイリアスが更新され、新しく作成されたシークレットを参照するようになります。

再試行と同時実行

ローテーション プロセスはいつでも終了できるため、Cloud Run サービスはプロセスを中断した時点から再開できる(リエントラントである)必要があります。

失敗したローテーションまたは中断されたローテーションを再実行できるように、Pub/Sub で再試行を構成することをおすすめします。さらに、Cloud Run サービスで最大同時実行数最大インスタンス数を構成して、同時ローテーション実行が相互に干渉する可能性を最小限に抑えます。

リエントラントなローテーション ファンクションを構築するには、ローテーション プロセスを再開できるように状態を保存すると便利です。これに役立つ Secret Manager の機能が 2 つあります。

  • シークレットのラベルを使用して、ローテーション中に状態を保存します。シークレットにラベルを追加して、ローテーション ワークフロー中の最後に正常に追加されたバージョン(例: ROTATING_TO_NEW_VERSION_NUMBER=3)の数を追跡します。ローテーションが完了したら、ローテーション トラッキング ラベルを削除します。
  • ETag を使用して、ローテーション ワークフロー中に他のプロセスによってシークレットが同時に変更されていないことを確認します。詳細については、シークレットとシークレット バージョンの ETag をご覧ください。

Identity and Access Management の権限

ローテーション プロセスには、新しいシークレット バージョンを追加するための secretmanager.versions.add 権限が必要です。また、以前のシークレット バージョンを読み取るには secretmanager.versions.access が必要になる場合があります。

デフォルトの Cloud Run サービス アカウントには編集者のロールがあります。このロールには、シークレット バージョンの追加権限が含まれていますが、アクセス権限はありません。最小権限の原則に沿って、デフォルトのサービス アカウントは使用しないことをおすすめします。代わりに、必要に応じて付与された Secret Manager のロール(1 つまたは複数でもかまいません)を使用して、Cloud Run サービスの個別のサービス アカウントを設定します。

  • roles/secretmanager.secretVersionAdder
  • roles/secretmanager.secretVersionManager
  • roles/secretmanager.secretAdmin
  • roles/secretmanager.secretAccessor

新しい SecretVersion をワークロードにロールアウトする

新しく有効な SecretVersion が外部システムに登録され、Secret Manager に保存されたので、アプリケーションにロールアウトします。このロールアウトは、シークレット バインディングへのアプローチによって異なります(シークレット バージョンへのバインディングを参照)。一般的には、手動での操作は必要ありません。

古いシークレット バージョンをクリーンアップする

すべてのアプリケーションで古いシークレット バージョンがローテーションされると、シークレット バージョンを安全にクリーンアップできます。クリーンアップ プロセスはシークレットのタイプによって異なりますが、通常は以下のようになります。

  1. 新しいシークレット バージョンがすべてのアプリに完全にロールアウトされていることを確認します。
  2. Secret Manager の古いシークレット バージョンを無効にし、アプリケーションが破損していないことを確認します(無効の操作でコンシューマが破壊された場合、人が介入できるような合理的な時間待機します)。
  3. 外部システムから古いシークレット バージョンを削除または登録解除します。
  4. Secret Manager で古いシークレット バージョンを破棄します。

次のステップ