設定密鑰通知

本頁說明如何設定及使用 Secret Manager 中密鑰的事件通知。

總覽

Secret Manager 與 Pub/Sub 整合,可針對密鑰和密鑰版本的變更提供事件通知。您可以利用這些通知啟動工作流程,例如在新增密鑰版本時重新啟動應用程式,或在刪除密鑰時通知安全工程師。如要進一步瞭解如何使用這些通知啟動工作流程,請參閱 Pub/Sub 說明文件

Secret Manager 中的事件通知運作方式

您最多可以為密鑰設定 10 個 Pub/Sub 主題。每當執行修改密鑰或其中一個版本的作業時,Secret Manager 會自動將訊息發布至該密鑰的每個 Pub/Sub 主題。GetListAccess 呼叫不會導致訊息發布。

Pub/Sub 訊息有一組屬性鍵/值組合,其中包含事件的中繼資料,以及包含所建立或修改SecretSecretVersion資源完整 JSON 序列化的資料欄位。這個 JSON 是採用 UTF-8 編碼的字串,代表 SecretSecretVersion 資源,格式完全符合 Secret Manager 公開 API 的規定,並採用 proto3 JSON 對應中指定的 JSON 編碼。

事件類型

以下是 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_CREATESECRET_UPDATE 訊息。

每當密碼的主題更新時,系統會將 TOPIC_CONFIGURED 訊息傳送至密碼的所有主題,包括已存在的主題。

通知格式

傳送至 Pub/Sub 主題的通知分為以下兩部分:

  • 屬性:用於說明事件的鍵/值組合。

  • 資料:包含已變更物件中繼資料的字串。

屬性

屬性是 Secret Manager 傳送至 Pub/Sub 主題的通知中包含的鍵/值組合。除了TOPIC_CONFIGURED測試訊息以外,所有通知都會包含以下鍵值組合,無論通知資料為何:

屬性名稱 範例 說明
eventType SECRET_CREATE 最新發生事件的類型,如需可能值的清單,請參閱事件類型一節。
dataFormat JSON_API_V1 物件資料的格式。
secretId projects/p/secrets/my-secret 發生事件的密鑰完整資源名稱。
timestamp 2021-01-20T11:17:45.081104-08:00 事件發生的時間。

此外,通知有時會包含以下鍵/值組合:

屬性名稱 範例 說明
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。

事前準備

您可以選擇將所有資源儲存在同一個專案中,也可以將 Secret 和 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
        

建立服務代理身分

如要為每個需要事件通知的專案建立服務代理程式身分,請按照下列步驟操作:

  1. 如要使用 Google Cloud CLI 建立服務身分,請執行下列指令:

          $ 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

使用下方的任何指令資料之前,請先替換以下項目:

  • 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 服務帳戶在主題上發布內容的權限

您可以透過 Google Cloud 控制台或 Google Cloud CLI,將權限授予 Secret Manager 服務帳戶。

如要在 Pub/Sub 主題上授予 Pub/Sub 發布者角色 (roles/pubsub.publisher),請使用下列指令:

gcloud

使用下方的任何指令資料之前,請先替換以下項目:

  • PUBSUB_TOPIC_NAME:主題名稱

執行下列指令:

Linux、macOS 或 Cloud Shell

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

Windows (PowerShell)

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

Windows (cmd.exe)

gcloud pubsub topics 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 或密鑰的完整 ID
  • PUBSUB_TOPIC_NAME:主題名稱

執行下列指令:

Linux、macOS 或 Cloud Shell

gcloud secrets create SECRET_ID --topics PUBSUB_TOPIC_NAME

Windows (PowerShell)

gcloud secrets create SECRET_ID --topics PUBSUB_TOPIC_NAME

Windows (cmd.exe)

gcloud secrets create SECRET_ID --topics PUBSUB_TOPIC_NAME

REST

使用任何要求資料之前,請先替換以下項目:

  • PROJECT_ID:專案 ID Google Cloud
  • SECRET_ID:密鑰的 ID 或密鑰的完整 ID
  • TOPIC_NAME:主題名稱

HTTP 方法和網址:

POST https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets?secretId=SECRET_ID

JSON 要求主體:

{
  "replication":{
    "automatic":{}
  },
  "topics":{
    "name": "TOPIC_NAME"
  }
}

如要傳送要求,請選擇以下其中一個選項:

curl

將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets?secretId=SECRET_ID"

PowerShell

將要求主體儲存在名為 request.json 的檔案中,然後執行下列指令:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets?secretId=SECRET_ID" | Select-Object -Expand Content

您應該會收到如下的 JSON 回應:

{
  "name": "/projects/my-project/locations/me-central2/secrets/my-drz-secret",
  "createTime": "2024-03-25T08:24:13.153705Z",
  "etag": "\"161477e6071da9\""
}

更新私密主題

如要修改在密鑰上設定的 Pub/Sub 主題,請使用新的 Pub/Sub 主題資源名稱更新密鑰。您可以使用 Google Cloud CLI 從密鑰新增或移除一或多個主題,也可以清除密鑰中的所有主題。

新增主題

如要為密鑰新增一或多個主題,請使用下列指令:

gcloud

使用下方的任何指令資料之前,請先替換以下項目:

  • SECRET_ID:密鑰的 ID 或密鑰的完整 ID
  • 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 \
  --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 `
  --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 ^
  --project PROJECT_ID ^
  --add-topics projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_1_NAME,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_2_NAME

移除主題

如要從密鑰中移除一或多個主題,請使用下列指令:

gcloud

使用下方的任何指令資料之前,請先替換以下項目:

  • SECRET_ID:密鑰的 ID 或密鑰的完整 ID
  • PROJECT_ID:包含密碼的 Google Cloud 專案
  • PUBSUB_PROJECT_ID:要在其中建立訂閱項目的專案 ID
  • PUBSUB_TOPIC_1_NAMEPUBSUB_TOPIC_2_NAME:要從密鑰中移除的主題名稱

執行下列指令:

Linux、macOS 或 Cloud Shell

gcloud secrets update SECRET_ID \
  --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 `
  --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 ^
  --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 或密鑰的完整 ID
  • PROJECT_ID:包含密碼的 Google Cloud 專案

執行下列指令:

Linux、macOS 或 Cloud Shell

gcloud secrets update SECRET_ID \
  --project PROJECT_ID \
  --clear-topics

Windows (PowerShell)

gcloud secrets update SECRET_ID `
  --project PROJECT_ID `
  --clear-topics

Windows (cmd.exe)

gcloud secrets update SECRET_ID ^
  --project PROJECT_ID ^
  --clear-topics

透過 Cloud Run functions 接收事件通知

您可以建立 Cloud Run 函式來接收 Pub/Sub 訊息,藉此啟動工作流程。詳情請參閱 Cloud Run functions 說明文件。以下範例程式碼適用於 Cloud Run 函式,每當事件發布至主題時,就會列印 eventTypesecretId 和中繼資料。

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 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。


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,並附上訊息說明發布失敗的原因。

後續步驟