シークレットの通知を設定する

このページでは、Secret Manager でシークレットのイベント通知を構成して使用する方法について説明します。

概要

Secret Manager は Pub/Sub と統合して、シークレットとシークレット バージョンの両方の変更に関するイベント通知を提供します。これらの通知を使用して、ワークフローを開始できます。たとえば、新しいシークレット バージョンが追加されたときにアプリケーションを再起動したり、シークレットが削除されたときにセキュリティ エンジニアに通知したりできます。これらの通知を使用してワークフローを開始する方法の詳細については、Pub/Sub のドキュメントをご覧ください。

Secret Manager でのイベント通知の仕組み

シークレットは、最大 10 個の Pub/Sub トピックのリストで構成できます。シークレットまたはそのバージョンの 1 つを変更するオペレーションが実行されるたびに、Secret Manager はそのシークレットのそれぞれの Pub/Sub トピックにメッセージを自動的にパブリッシュします。GetListAccess の呼び出しでは、メッセージはパブリッシュされません

Pub/Sub メッセージには、イベントに関するメタデータを含む属性の Key-Value ペアのセットと、作成または変更された Secret リソースまたは SecretVersion リソースの完全な JSON シリアル化を含むデータフィールドがあります。この JSON は、UTF-8 でエンコードされた文字列です。この文字列は、Secret Manager の公開 API(proto3 JSON マッピングで指定された JSON でエンコードされている)によって指定された形式で Secret または SecretVersion リソースを厳密に表しています。

イベントタイプ

Secret Manager でサポートされているイベントタイプのリストは次のとおりです。

イベントの種類 説明
SECRET_CREATE 新しいシークレットが正常に作成されると送信されます。
SECRET_UPDATE 新しいシークレットが正常に更新されると送信されます。
SECRET_DELETE ユーザーによって開始されたリクエスト、またはシークレットの有効期限によってシークレットが削除されると送信されます。
SECRET_VERSION_ADD 新しいシークレット バージョンが正常に追加されると送信されます。
SECRET_VERSION_ENABLE シークレット バージョンを有効にすると送信されます。
SECRET_VERSION_DISABLE シークレット バージョンが有効になると送信されます。
SECRET_VERSION_DESTROY シークレット バージョンを破棄すると送信されます。
SECRET_VERSION_DESTROY_SCHEDULED シークレットに破棄の遅延期間が構成され、ユーザーがシークレット バージョンを破棄しようとすると送信されます。
SECRET_ROTATE シークレットをローテーションするタイミングになると送信されます。詳細については、ローテーション スケジュールを作成するをご覧ください。
TOPIC_CONFIGURED

これは、eventType: TOPIC_CONFIGURED 以外の本文や属性がないテスト メッセージです。これは、シークレットが Pub/Sub トピックのリストを使用して作成または更新されるときに送信されますが、オペレーションが成功したことを示すものではありません

オペレーションが成功した場合は、直後に SECRET_CREATE または SECRET_UPDATE メッセージが送信されます。

シークレットでトピックが更新されるたびに、すでに存在しているトピックを含むすべてのシークレットのトピックに TOPIC_CONFIGURED メッセージが送信されます。

通知形式

Pub/Sub トピックに送信される通知は、次の 2 つの部分で構成されます。

  • 属性: イベントを記述する Key-Value ペア。

  • データ: 変更されたオブジェクトのメタデータを含む文字列

属性

属性は、Secret Manager から Pub/Sub トピックに送信される通知に含まれる Key-Value ペアです。TOPIC_CONFIGURED テスト メッセージ以外のすべての通知には、通知のデータに関係なく、常に次の Key-Value ペアのセットが含まれます。

属性名 説明
eventType SECRET_CREATE 発生したイベントの種類。有効な値については、イベントの種類をご覧ください。
dataFormat JSON_API_V1 オブジェクト データの形式。
secretId projects/p/secrets/my-secret イベントが発生したシークレットの完全なリソース名。
timestamp 2021-01-20T11:17:45.081104-08:00 イベントの発生時間。

また、次の Key-Value ペアのセットが通知に含まれる場合もあります。

属性名 説明
versionId projects/p/secrets/my-secret/versions/456

イベントが発生したシークレット バージョンの名前。

これは SECRET_VERSION_ADDSECRET_VERSION_ENABLESECRET_VERSION_DISABLESECRET_VERSION_DESTROY のイベント通知にのみ存在します。

deleteType REQUESTED 削除がユーザーによりリクエストされた(REQUESTED)か、シークレットの有効期限(EXPIRATION)により削除されたかのどちらか。SECRET_DELETE イベント通知のみに表示されます。

データ

データ フィールドは、変更されたオブジェクトのメタデータを含む UTF-8 文字列です。データはシークレットまたはシークレット バージョンのいずれかです。

SECRET_DELETE 通知の場合、データ フィールドに含まれるメタデータは、削除前のオブジェクトのメタデータを表します。それ以外の通知では、データ フィールドに含まれるメタデータは、変更発生のオブジェクトのメタデータを表します。

制限事項

イベント通知は、Secret Manager v1 API と Google Cloud CLI でのみ使用できます。

始める前に

すべてのリソースを同じプロジェクトに保存することも、シークレットと Pub/Sub トピックを別のプロジェクトに保存することもできます。

  1. Secret Manager を設定するには、次の操作を行います。

    • Secret Manager リソースを保持するプロジェクトを作成するか、既存のプロジェクトを使用します。

    • 必要に応じて、Secret Manager API を有効にするページに記載されている手順を完了します。

  2. Pub/Sub を設定するには、次の操作を行います。

    • Pub/Sub リソースを保持するプロジェクトを作成するか、既存のプロジェクトを使用します。

    • 必要に応じて、Pub/Sub API を有効にします

  3. 次のコマンドを使用して Google Cloud に対する認証を行います。

        $ gcloud auth login --update-adc
        

サービス エージェント ID を作成する

イベント通知を使用するシークレットが必要なプロジェクトごとにサービス エージェント ID を作成するには、次の操作を行います。

  1. Google Cloud CLI でサービス ID を作成するには、次のコマンドを実行します。

          $ gcloud beta services identity create \
              --service "secretmanager.googleapis.com" \
              --project "PROJECT_ID"
        

    このコマンドは、次の形式でサービス アカウント名を返します。

        service-PROJECT_ID@gcp-sa-secretmanager.iam.gserviceaccount.com
        
  2. シークレットに構成される Pub/Sub トピックに対して、パブリッシュする権限をこのサービス アカウントに付与します。

  3. 次のコマンドを使用して、サービス アカウント名を環境変数として保存します。

        # This is from the output of the command above
        $ export SM_SERVICE_ACCOUNT="service-...."
        

Secret Manager プロジェクト、Pub/Sub プロジェクト、Secret Manager サービス アカウントの環境変数は、この手順を完了するまで設定したままにする必要があります。

Pub/Sub トピックを作成する

Pub/Sub クイックスタートに従って、Google Cloud コンソールの Pub/Sub プロジェクトにトピックを作成します。または、次のコマンドを使用して Google Cloud CLI でトピックを作成します。

gcloud

後述のコマンドデータを使用する前に、次のように置き換えます。

  • PROJECT_ID: シークレットを含む Google Cloud プロジェクト ID
  • PUBSUB_PROJECT_ID: サブスクリプションを作成するプロジェクトの ID
  • PUBSUB_TOPIC_NAME: トピックの名前

次のコマンドを実行します。

Linux、macOS、Cloud Shell

gcloud pubsub topics create "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME"

Windows(PowerShell)

gcloud pubsub topics create "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME"

Windows(cmd.exe)

gcloud pubsub topics create "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME"

シークレットに複数の Pub/Sub トピックを作成する場合は、この手順を複数回繰り返します。

トピックに対してパブリッシュする権限を Secret Manager のサービス アカウントに付与する

Secret Manager のサービス アカウントに権限を付与するには、Google Cloud コンソールまたは Google Cloud CLI を使用します。

Pub/Sub トピックに Pub/Sub パブリッシャーのロール(roles/pubsub.publisher)を付与するには、次のコマンドを使用します。

gcloud

後述のコマンドデータを使用する前に、次のように置き換えます。

  • PUBSUB_TOPIC_NAME: トピックの名前

次のコマンドを実行します。

Linux、macOS、Cloud Shell

gcloud pubsub topics create add-iam-policy-binding PUBSUB_TOPIC_NAME \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/pubsub.publisher"

Windows(PowerShell)

gcloud pubsub topics create add-iam-policy-binding PUBSUB_TOPIC_NAME `
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" `
    --role "roles/pubsub.publisher"

Windows(cmd.exe)

gcloud pubsub topics create add-iam-policy-binding PUBSUB_TOPIC_NAME ^
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" ^
    --role "roles/pubsub.publisher"

Pub/Sub サブスクリプションの作成

トピックにパブリッシュされたメッセージを表示するには、そのトピックへのサブスクリプションも作成する必要があります。Pub/Sub クイックスタートに従って、Google Cloud コンソールの Pub/Sub プロジェクトにサブスクリプションを作成します。または、次のコマンドを使用して Google Cloud CLI でトピックを作成します。

gcloud

後述のコマンドデータを使用する前に、次のように置き換えます。

  • PUBSUB_PROJECT_ID: サブスクリプションを作成するプロジェクトの ID
  • PUBSUB_SUBSCRIPTION_NAME: サブスクリプションの名前。
  • PUBSUB_TOPIC_NAME: トピックの名前

次のコマンドを実行します。

Linux、macOS、Cloud Shell

gcloud pubsub subscriptions create projects/PUBSUB_PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_NAME \
  --topic projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME

Windows(PowerShell)

gcloud pubsub subscriptions create projects/PUBSUB_PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_NAME `
  --topic projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME

Windows(cmd.exe)

gcloud pubsub subscriptions create projects/PUBSUB_PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_NAME ^
  --topic projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME

トピックが構成されたシークレットの作成

最大 10 個のトピックのリストを構成してシークレットを作成します。シークレットまたはシークレットのバージョンのいずれかが変更されると、シークレットで構成されているすべてのトピックがイベント通知を受信します。

gcloud

後述のコマンドデータを使用する前に、次のように置き換えます。

  • SECRET_ID: シークレットの ID またはシークレットの完全修飾識別子
  • PUBSUB_TOPIC_NAME: トピックの名前
  • LOCATION: シークレットの Google Cloud ロケーション

次のコマンドを実行します。

Linux、macOS、Cloud Shell

gcloud secrets create SECRET_ID --topics PUBSUB_TOPIC_NAME --location=LOCATION

Windows(PowerShell)

gcloud secrets create SECRET_ID --topics PUBSUB_TOPIC_NAME --location=LOCATION

Windows(cmd.exe)

gcloud secrets create SECRET_ID --topics PUBSUB_TOPIC_NAME --location=LOCATION

シークレット トピックを更新する

新しい Pub/Sub トピックのリソース名でシークレットを更新し、シークレットで構成されている Pub/Sub トピックを変更します。Google Cloud CLI を使用すると、シークレットへの 1 つ以上のトピックの追加、またはシークレットからトピックの削除に加えて、シークレットからすべてのトピックの消去を行うことができます。

トピックの追加

1 つ以上のトピックをシークレットに追加するには、次のコマンドを使用します。

gcloud

後述のコマンドデータを使用する前に、次のように置き換えます。

  • SECRET_ID: シークレットの ID またはシークレットの完全修飾識別子
  • LOCATION: シークレットの Google Cloud ロケーション
  • PROJECT_ID: シークレットを含む Google Cloud プロジェクト ID
  • PUBSUB_PROJECT_ID: サブスクリプションを作成するプロジェクトの ID
  • PUBSUB_TOPIC_1_NAMEPUBSUB_TOPIC_2_NAME: シークレットに追加するトピックの名前

次のコマンドを実行します。

Linux、macOS、Cloud Shell

gcloud secrets update SECRET_ID --location=LOCATION \
  --project PROJECT_ID \
  --add-topics projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_1_NAME,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_2_NAME

Windows(PowerShell)

gcloud secrets update SECRET_ID --location=LOCATION `
  --project PROJECT_ID `
  --add-topics projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_1_NAME,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_2_NAME

Windows(cmd.exe)

gcloud secrets update SECRET_ID --location=LOCATION ^
  --project PROJECT_ID ^
  --add-topics projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_1_NAME,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_2_NAME

トピックの削除

シークレットから 1 つ以上のトピックを削除するには、次のコマンドを使用します。

gcloud

後述のコマンドデータを使用する前に、次のように置き換えます。

  • SECRET_ID: シークレットの ID またはシークレットの完全修飾識別子
  • LOCATION: シークレットの Google Cloud ロケーション
  • PROJECT_ID: シークレットを含む Google Cloud プロジェクト
  • PUBSUB_PROJECT_ID: サブスクリプションを作成するプロジェクトの ID
  • PUBSUB_TOPIC_1_NAMEPUBSUB_TOPIC_2_NAME: シークレットから削除するトピックの名前

次のコマンドを実行します。

Linux、macOS、Cloud Shell

gcloud secrets update SECRET_ID --location=LOCATION \
  --project PROJECT_ID \
  --remove-topics "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_1_NAME,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_2__NAME

Windows(PowerShell)

gcloud secrets update SECRET_ID --location=LOCATION `
  --project PROJECT_ID `
  --remove-topics "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_1_NAME,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_2__NAME

Windows(cmd.exe)

gcloud secrets update SECRET_ID --location=LOCATION ^
  --project PROJECT_ID ^
  --remove-topics "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_1_NAME,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_2__NAME

トピックのクリア

シークレットからすべてのトピックを削除するには、次のコマンドを使用します。

gcloud

後述のコマンドデータを使用する前に、次のように置き換えます。

  • SECRET_ID: シークレットの ID またはシークレットの完全修飾識別子
  • PROJECT_ID: シークレットを含む Google Cloud プロジェクト
  • LOCATION: シークレットの Google Cloud ロケーション

次のコマンドを実行します。

Linux、macOS、Cloud Shell

gcloud secrets update SECRET_ID --location=LOCATION \
  --project PROJECT_ID \
  --clear-topics

Windows(PowerShell)

gcloud secrets update SECRET_ID --location=LOCATION `
  --project PROJECT_ID `
  --clear-topics

Windows(cmd.exe)

gcloud secrets update SECRET_ID --location=LOCATION ^
  --project PROJECT_ID ^
  --clear-topics

Cloud Run 関数でのイベント通知の使用

イベント通知を使用すると、Pub/Sub メッセージを使用する Cloud Run 関数を作成し、ワークフローを開始できます。詳細については、Cloud Run functions のドキュメントをご覧ください。次のサンプルコードは、イベントがトピックに公開されるたびに eventTypesecretId、メタデータを出力する Cloud Run functions 用です。

C#

このコードを実行するには、まず C# 開発環境を設定し、Secret Manager C# SDK をインストールします。Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Cloud.PubSub.V1;
using System;
using System.Threading;
using System.Threading.Tasks;

// Triggered from a message on a Cloud Pub/Sub topic.
// The printed value will be visible in Cloud Logging
// (https://cloud.google.com/functions/docs/monitoring/logging).
namespace PubSubSample
{
    public class Function : ICloudEventFunction<MessagePublishedData>
    {
        public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
        {
          string eventType = data.Message.Attributes["eventType"];
          string secretId = data.Message.Attributes["secretId"];
          string secretMetadata = data.Message.TextData;
          Console.WriteLine($"Received {eventType} for {secretId}. New metadata: {secretMetadata}.");
          return Task.CompletedTask;
        }
    }
}

Go

このコードを実行するには、まず Go 開発環境を設定し、Secret Manager Go SDK をインストールします。Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。

import (
	"context"
	"fmt"
)

// PubSubMessage is the payload of a Pub/Sub event.
type PubSubMessage struct {
	Attributes PubSubAttributes `json:"attributes"`
	Data       []byte           `json:"data"`
}

// PubSubAttributes are attributes from the Pub/Sub event.
type PubSubAttributes struct {
	SecretId  string `json:"secretId"`
	EventType string `json:"eventType"`
}

// ConsumeEventNotification demonstrates how to consume and process the Pub/Sub
// notification from Secret Manager.
func ConsumeEventNotification(ctx context.Context, m PubSubMessage) (string, error) {
	// The printed value will be visible in Cloud Logging:
	//
	//     https://cloud.google.com/functions/docs/monitoring/logging
	//
	eventType := m.Attributes.EventType
	secretID := m.Attributes.SecretId
	data := m.Data

	return fmt.Sprintf("Received %s for %s. New metadata: %q.",
		eventType, secretID, data), nil
}

Java

Secret Manager 用のクライアント ライブラリをインストールして使用する方法については、Secret Manager クライアント ライブラリをご覧ください。

Secret Manager に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


import java.util.Base64;
import java.util.Map;
import java.util.logging.Logger;
import lombok.Data;

// Demonstrates how to consume and process a Pub/Sub notification from Secret Manager. Triggered
// by a message on a Cloud Pub/Sub topic.
// Ideally the class should implement a background function that accepts a Pub/Sub message.
// public class ConsumeEventNotification implements BackgroundFunction<PubSubMessage> { }
public class ConsumeEventNotification {

  // You can configure the logs to print the message in Cloud Logging.
  private static final Logger logger = Logger.getLogger(ConsumeEventNotification.class.getName());

  // Accepts a message from a Pub/Sub topic and writes it to logger.
  public static String accept(PubSubMessage message) {
    String eventType = message.attributes.get("eventType");
    String secretId = message.attributes.get("secretId");
    String data = new String(Base64.getDecoder().decode(message.data));
    String log = String.format("Received %s for %s. New metadata: %s", eventType, secretId, data);
    logger.info(log);
    return log;
  }

  // Event payload. Mock of the actual Pub/Sub message.
  @Data
  public static class PubSubMessage {

    byte[] data;
    Map<String, String> attributes;
    String messageId;
    String publishTime;
    String orderingKey;
  }
}

Node.js

このコードを実行するには、まず Node.js 開発環境を設定し、Secret Manager Node.js SDK をインストールします。Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。

/**
* Triggered from a message on a Cloud Pub/Sub topic.
* The printed value will be visible in Cloud Logging
* (https://cloud.google.com/functions/docs/monitoring/logging).
*
* @param {!Object} event Event payload.
* @param {!Object} context Metadata for the event.
*/
exports.smEventsFunction = (event, context) => {
  const eventType = event.attributes.eventType;
  const secretID = event.attributes.secretId;
  const secretMetadata = Buffer.from(event.data, 'base64').toString();
  console.log(`Received ${eventType} for ${secretID}. New metadata: ${secretMetadata}.`);
};

Python

このコードを実行するには、まず Python 開発環境を設定し、Secret Manager Python SDK をインストールします。Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。

import base64


def consume_event_notification(event: dict, unused_context: None) -> str:
    """
    consume_event_notification demonstrates how to consume and process a
    Pub/Sub notification from Secret Manager.
    Args:
          event (dict): Event payload.
          unused_context (google.cloud.functions.Context): Metadata for the event.
    """
    event_type = event["attributes"]["eventType"]
    secret_id = event["attributes"]["secretId"]
    secret_metadata = base64.b64decode(event["data"]).decode("utf-8")
    event_notification = (
        f"Received {event_type} for {secret_id}. New metadata: {secret_metadata}"
    )
    print(event_notification)
    return event_notification

Ruby

このコードを実行するには、まず Ruby 開発環境を設定し、Secret Manager Ruby SDK をインストールします。Compute Engine または GKE では、cloud-platform スコープを使用して認証する必要があります。

require "functions_framework"
require "base64"

# Triggered from a message on a Cloud Pub/Sub topic.
# The printed value will be visible in Cloud Logging
# (https://cloud.google.com/functions/docs/monitoring/logging).
FunctionsFramework.cloud_event "sm_events_function" do |event|
  message = event.data["message"]
  event_type = message["attributes"]["eventType"]
  secret_id = message["attributes"]["secretId"]
  message_data = Base64.decode64 message["data"]
  FunctionsFramework.logger.info "Received %s for %s. New metadata: %s." % [event_type, secret_id, message_data]
end

すべてのイベントタイプの一覧については、イベントタイプをご覧ください。

正しく構成されていないトピック

作成または更新オペレーションで Pub/Sub トピックがシークレットに追加されたものの、構成ミスにより Secret Manager がトピックにメッセージをパブリッシュできない場合、パブリッシュ エラーの理由を示すエラー メッセージが表示され、オペレーションは失敗します。たとえば、トピックが存在しない場合や、Secret Manager のサービス アカウントにパブリッシュの権限がない場合などに、このエラーが発生することがあります。

Pub/Sub トピックをシークレットに追加し、その後、Secret Manager がメッセージをパブリッシュできないようにトピックが変更された場合(たとえば、トピックが削除された場合や、Secret Manager のサービス アカウントの権限が削除された場合など)、Secret Manager は Secret Manager Secret に、パブリッシュに失敗した理由を示すメッセージとともにログを書き込みます。

次のステップ