本主题讨论了对 Secret Manager 中的事件通知的支持。
概览
事件通知会将密钥和密钥版本的更改信息发送到 Pub/Sub。这些通知可用于触发任意工作流,例如在添加新的 Secret 版本时重启应用,或在删除 Secret 时通知安全工程师。如需详细了解如何使用这些通知触发工作流,请参阅 Pub/Sub 文档。
事件通知在 Secret Manager 中的运作方式
密文最多可配置 10 个 Pub/Sub 主题的列表。每当执行修改密文或其某个版本的操作时,Secret Manager 都会自动向该密文的每个 Pub/Sub 主题发布一条消息。Get、List 和 Access 调用不会导致消息发布。
Pub/Sub 消息具有一组“特性”键值对(包含有关事件的元数据)以及“数据”字段(包含已创建或修改的 Secret 或 SecretVersion 资源的完整 JSON 序列化)。此 JSON 是采用 UTF-8 编码的字符串,该字符串以 Secret Manager 公共 API 指定的形式表示 Secret 或 SecretVersion 资源,并按照 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 |
这是一条测试消息,不包含除
如果操作成功,系统将之后立即发送
每当在密文上更新主题时,系统都会向密文上的所有主题(包括已存在的主题)发送 |
通知格式
发送到 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 |
在其中发生事件的密文版本的名称。
此特性仅存在于 |
deleteType |
REQUESTED |
用户请求删除 (REQUESTED ) 还是由于密文过期删除 (EXPIRATION )。此特性仅存在于 SECRET_DELETE 事件通知中。 |
数据
数据字段是一个 UTF-8 字符串,其中包含发生更改的对象的元数据。数据是 Secret 或 Secret 版本。
对于 SECRET_DELETE
通知,数据字段中包含的元数据代表删除前的对象元数据。对于其他所有通知,data 字段中包含的元数据代表发生更改后的对象元数据。
限制
只能通过 Secret Manager v1
API 和 Google Cloud CLI 获得事件通知。
准备工作
您可以选择将所有资源存储在同一项目中,也可以将密文和 Pub/Sub 主题存储在不同的项目中。完成以下前提条件,以设置 Secret Manager 和 Pub/Sub:
Secret Manager:
- 创建或使用现有项目来保存您的 Secret Manager 资源。
- 如有必要,请完成 Secret Manager 指南的启用 Secret Manager API 页面中提到的步骤。
Pub/Sub:
- 创建或使用现有项目来保存您的 Pub/Sub 资源。
- 如有必要,请启用 Pub/Sub API。
向 Google Cloud 进行身份验证:
$ gcloud auth login --update-adc
创建服务代理身份
您需要为每个需要包含事件通知的密文的项目创建服务代理身份。
如需使用 Google Cloud CLI 创建服务身份,请运行以下命令:
$ gcloud beta services identity create \ --service "secretmanager.googleapis.com" \ --project "PROJECT_ID"
上述命令会按以下格式返回服务账号名称:
service-PROJECT_NUMBER@gcp-sa-secretmanager.iam.gserviceaccount.com
您将向此服务账号授予针对为密文配置的 Pub/Sub 主题进行发布的权限。
将服务账号名称保存为环境变量:
# 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 topics create "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME"
如果您要在密文上创建多个 Pub/Sub 主题,请重复此操作多次。
向 Secret Manager 的服务账号授予针对刚创建的主题进行发布的权限。您可以通过 Google Cloud 控制台或 Google Cloud CLI 执行此操作。以下命令会向服务账号授予对 my-topic
Pub/Sub 主题的 Pub/Sub Publisher 角色 (roles/pubsub.publisher
)。
$ 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 subscriptions create "projects/PUBSUB_PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_NAME" \ --topic "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME"
创建配置了主题的密文
创建一个最多配置了 10 个主题列表的密文。如果密文或其某个版本发生更改,则在密文上配置的所有主题都会收到事件通知。以下命令会创建一个配置了 my-topic
的密文。
gcloud
如需在命令行上使用 Secret Manager,请先安装或升级到 Google Cloud CLI 378.0.0 或更高版本。在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
$ gcloud secrets create SECRET_ID --topics TOPIC_NAME
API
这些示例使用 curl 来使用 API 演示。 您可以使用 gcloud auth print-access-token 生成访问令牌。在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
$ curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets?secretId=SECRET_ID" \
--request "POST" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @- <<EOF
{
"replication":{
"automatic":{}
},
"topics":{
"name": "TOPIC_NAME"
}
}
EOF
更新 Secret 主题
通过使用新的 Pub/Sub 主题资源名称更新密文,修改在密文上配置的 Pub/Sub 主题。您可以使用 Google Cloud CLI 在密文中添加或移除一个或多个主题,以及从密文中清除所有主题。
添加主题
为密文添加一个或多个主题。添加已存在的主题将无效。
$ gcloud secrets update "SECRET_ID" \ --project "PROJECT_ID" \ --add-topics "projects/PUBSUB_PROJECT_ID/topics/my-topic-2,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME"
移除主题
从密文中移除一个或多个主题。移除不存在的主题将无效。
$ gcloud secrets update "SECRET_ID" \ --project "PROJECT_ID" \ --remove-topics "projects/PUBSUB_PROJECT_ID/topics/PUBSUB_TOPIC_NAME,projects/PUBSUB_PROJECT_ID/topics/PUBSUB_OTHER_TOPIC_NAME"
清除主题
从 Secret 中移除所有主题。
$ gcloud secrets update SECRET_ID \ --project "PROJECT_ID" \ --clear-topics
通过 Cloud Run functions 使用事件通知
您可以通过创建 Cloud Run 函数来使用事件通知触发任意工作流,以便使用 Pub/Sub 消息。如需查看完整指南,请参阅 Cloud Run functions 文档。以下示例代码适用于 Cloud Functions 函数,该函数会在有事件发布到主题时输出 eventType、secretId 和元数据。您可以在此处找到 Secret Manager 的所有事件类型列表。
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 范围进行身份验证。
Java
如需了解如何安装和使用 Secret Manager 客户端库,请参阅 Secret Manager 客户端库。
如需向 Secret Manager 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
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 范围进行身份验证。
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
资源,其中包含表明发布失败的原因的消息。