设置 Secret 的通知

本页介绍了如何在 Secret Manager 中为 Secret 配置和使用事件通知。

概览

Secret Manager 与 Pub/Sub 集成,可针对密钥和密钥版本的更改提供事件通知。您可以使用这些通知启动工作流,例如在添加新的 Secret 版本时重启应用,或在删除 Secret 时通知安全工程师。如需详细了解如何使用这些通知启动工作流,请参阅 Pub/Sub 文档

事件通知在 Secret Manager 中的运作方式

密文最多可配置 10 个 Pub/Sub 主题的列表。每当执行修改密文或其某个版本的操作时,Secret Manager 都会自动向该密文的每个 Pub/Sub 主题发布一条消息。GetListAccess 调用不会导致消息发布。

Pub/Sub 消息具有一组属性键值对(包含有关事件的元数据)以及“数据”字段(包含已创建或修改的 SecretSecretVersion 资源的完整 JSON 序列化)。此 JSON 是采用 UTF-8 编码的字符串,该字符串以 Secret Manager 公共 API 指定的形式表示 SecretSecretVersion 资源,并按照 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 通知,数据字段中包含的元数据代表删除前的对象元数据。对于其他所有通知,data 字段中包含的元数据代表发生更改后的对象元数据。

限制

事件通知仅在 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
        

创建服务代理身份

如需为每个需要包含事件通知的密文的项目创建服务代理身份,请按以下步骤操作:

  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

在使用下面的命令数据之前,请先进行以下替换:

  • 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 的服务账号授予针对主题发布消息的权限

您可以通过 Google Cloud 控制台或 Google Cloud CLI 向 Secret Manager 服务账号授予权限。

如需授予对 Pub/Sub 主题的 Pub/Sub Publisher 角色 (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:Secret 的 ID 或 Secret 的完全限定标识符
  • 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

更新 Secret 主题

通过使用新的 Pub/Sub 主题资源名称更新密文,修改在密文上配置的 Pub/Sub 主题。您可以使用 Google Cloud CLI 在密文中添加或移除一个或多个主题,以及从密文中清除所有主题。

添加主题

如需向密文添加一个或多个主题,请使用以下命令:

gcloud

在使用下面的命令数据之前,请先进行以下替换:

  • SECRET_ID:Secret 的 ID 或 Secret 的完全限定标识符
  • LOCATION:密钥的 Google Cloud 位置
  • PROJECT_ID:包含密文的 Google Cloud 项目 ID
  • PUBSUB_PROJECT_ID:要在其中创建订阅的项目的 ID
  • PUBSUB_TOPIC_1_NAMEPUBSUB_TOPIC_2_NAME:要添加到 Secret 的主题的名称

执行以下命令:

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

移除主题

如需从密钥中移除一个或多个主题,请使用以下命令:

gcloud

在使用下面的命令数据之前,请先进行以下替换:

  • SECRET_ID:Secret 的 ID 或 Secret 的完全限定标识符
  • LOCATION:密钥的 Google Cloud 位置
  • PROJECT_ID:包含 Secret 的 Google Cloud 项目
  • PUBSUB_PROJECT_ID:要在其中创建订阅的项目的 ID
  • PUBSUB_TOPIC_1_NAMEPUBSUB_TOPIC_2_NAME:要从 Secret 中移除的主题的名称

执行以下命令:

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:Secret 的 ID 或 Secret 的完全限定标识符
  • PROJECT_ID:包含 Secret 的 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 functions 使用事件通知

您可以通过创建 Cloud Run 函数来使用事件通知启动工作流,以便使用 Pub/Sub 消息。如需了解详情,请参阅 Cloud Run 函数文档。以下示例代码适用于 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 客户端库

如需向 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,并附带一条消息,说明发布失败的原因。

后续步骤