Configurer des notifications sur un secret

Cette rubrique traite de la prise en charge des notifications d'événements dans Secret Manager.

Présentation

Les notifications d'événement envoient des informations sur les modifications apportées à vos secrets et à vos versions de secrets à Pub/Sub. Ces notifications peuvent être utilisées pour déclencher des workflows arbitraires, comme le redémarrage d'une application lorsqu'une nouvelle version de secret est ajoutée ou l'envoi d'une notification aux ingénieurs chargés de la sécurité lorsqu'un secret est supprimé. Pour en savoir plus sur l'utilisation de ces notifications pour déclencher des workflows, consultez la documentation Pub/Sub.

Fonctionnement des notifications d'événements dans Secret Manager

Les secrets peuvent être configurés avec une liste de 10 sujets Pub/Sub au maximum. Chaque fois qu'une opération modifiant le secret ou l'une de ses versions est effectuée, Secret Manager publie automatiquement un message dans chacun des sujets Pub/Sub de ce secret. Les appels Get, List et Access n'entraînent pas de publication de messages.

Les messages Pub/Sub comportent un ensemble de paires clé/valeur "attribut" contenant des métadonnées sur l'événement, ainsi qu'un champ "données" contenant une sérialisation JSON complète de la ressource secret ou SecretVersion qui a été créée ou modifiée. Il s'agit d'une chaîne au format UTF-8 qui représente la ressource Secret ou SecretVersion au format spécifié par l'API publique de Secret Manager, encodée au format JSON comme spécifié dans Mappage JSON proto3

Types d'événement

Voici une liste des types d'événements compatibles avec Secret Manager:

Type d'événement Description
SECRET_CREATE Envoyé lorsqu'un secret a bien été créé.
SECRET_UPDATE Envoyé lorsqu'un nouveau secret a bien été mis à jour.
SECRET_DELETE Envoyé lorsqu'un secret est supprimé, en raison d'une requête initiée par l'utilisateur ou de son expiration.
SECRET_VERSION_ADD Envoyé lorsqu'une nouvelle version de secret a bien été ajoutée.
SECRET_VERSION_ENABLE Envoyé lorsqu'une version de secret est activée.
SECRET_VERSION_DISABLE Envoyé lorsqu'une version de secret est désactivée.
SECRET_VERSION_DESTROY Envoyé lorsqu'une version de secret est détruite.
SECRET_VERSION_DESTROY_SCHEDULED Envoyé lorsqu'un délai de destruction est configuré sur le secret et que l'utilisateur tente de détruire la version d'un secret.
SECRET_ROTATE Envoyé lorsqu'il est temps d'alterner un secret. Pour en savoir plus, consultez la page Créer et gérer des règles de rotation sur des secrets.
TOPIC_CONFIGURED

Il s'agit d'un message de test sans corps ni attributs autres que eventType: TOPIC_CONFIGURED. Cela est envoyé lorsqu'un secret est créé ou mis à jour avec une liste de sujets Pub/Sub, mais n'indique pas que l'opération a réussi.

Un message SECRET_CREATE ou SECRET_UPDATE est envoyé immédiatement après la réussite de l'opération.

Chaque fois que des sujets sont mis à jour sur un secret, un message TOPIC_CONFIGURED est envoyé à tous les sujets du secret, y compris ceux qui étaient déjà présents.

Format des notifications

Les notifications envoyées au sujet Pub/Sub comprennent deux parties :

  • Attributs : ensemble de paires valeur/clé décrivant l'événement
  • Données : chaîne contenant les métadonnées de l'objet modifié.

Attributs

Les attributs sont des paires valeur/clé présentes dans les notifications que Secret Manager envoie à votre sujet Pub/Sub. Toutes les notifications autres que les messages de test TOPIC_CONFIGURED contiennent toujours l'ensemble de paires clé/valeur suivant, quelles que soient les données de la notification :

Nom de l'attribut Exemple Description
eventType SECRET_CREATE Type d'événement qui vient de se produire. Consultez la section Types d'événements pour obtenir la liste des valeurs possibles.
dataFormat JSON_API_V1 Format des données d'objet.
secretId projects/p/secrets/my-secret Nom complet de la ressource du secret sur lequel l'événement s'est produit.
timestamp 2021-01-20T11:17:45.081104-08:00 Heure à laquelle l'événement s'est produit.

Parfois, les notifications contiennent l'ensemble de paires clé/valeur suivant :

Nom de l'attribut Exemple Description
versionId projects/p/secrets/my-secret/versions/456

Nom de la version du secret pour lequel l'événement s'est produit.

Cet élément n'est présent que dans les notifications d'événements SECRET_VERSION_ADD, SECRET_VERSION_ENABLE, SECRET_VERSION_DISABLE et SECRET_VERSION_DESTROY.

deleteType REQUESTED Indique si la suppression a été demandée par un utilisateur (REQUESTED) ou en raison de l'expiration du secret (EXPIRATION). Présent uniquement pour les notifications d'événements SECRET_DELETE.

Données

Le champ de données est une chaîne UTF-8 contenant les métadonnées de l'objet modifié. Les données sont soit un secret, soit une version de secret.

Dans le cas des notifications SECRET_DELETE, les métadonnées contenues dans le champ de données représentent les métadonnées de l'objet avant sa suppression. Pour toutes les autres notifications, les métadonnées incluses dans le champ de données représentent les métadonnées de l'objet après sa modification.

Limites

Les notifications d'événements ne sont disponibles que dans l'API Secret Manager v1 et la Google Cloud CLI.

Avant de commencer

Vous pouvez choisir de stocker toutes les ressources dans le même projet ou de stocker les secrets et les sujets Pub/Sub dans des projets distincts. Remplissez les conditions préalables suivantes pour configurer Secret Manager et Pub/Sub :

  • Secret Manager :

    • Créez ou utilisez un projet existant pour stocker vos ressources Secret Manager.
    • Si nécessaire, suivez la procédure décrite sur la page Activer l'API Secret Manager du guide consacré à Secret Manager.
  • Pub/Sub

    • Créez ou utilisez un projet existant pour stocker vos ressources Pub/Sub.
    • Si nécessaire, activez l'API Pub/Sub.

Authentifiez-vous sur Google Cloud :

$ gcloud auth login --update-adc

Créer une identité d'agent de service

Vous devez créer une identité d'agent de service pour chaque projet nécessitant des secrets avec des notifications d'événements.

Pour créer une identité de service avec Google Cloud CLI, exécutez la commande suivante:

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

La commande précédente affiche un nom de compte de service au format suivant :

service-PROJECT_NUMBER@gcp-sa-secretmanager.iam.gserviceaccount.com

Vous accorderez à ce compte de service l'autorisation de publier des messages sur les sujets Pub/Sub qui seront configurés sur vos secrets.

Enregistrez le nom du compte de service sous forme de variable d'environnement :

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

Les variables d'environnement du projet Secret Manager, du projet Pub/Sub et du compte de service de Secret Manager doivent être définies pendant toute la durée de cette procédure.

Créer des sujets Pub/Sub

Suivez le guide de démarrage rapide de Pub/Sub pour créer des sujets dans votre projet Pub/Sub dans la console Google Cloud. Vous pouvez également créer des sujets à l'aide de Google Cloud CLI, comme dans cet exemple.

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

Répétez cette procédure plusieurs fois si vous souhaitez créer plusieurs sujets Pub/Sub sur le secret.

Accordez à ce compte de service Secret Manager l'autorisation de publier des messages sur les sujets que vous venez de créer. Pour ce faire, utilisez la console Google Cloud ou la Google Cloud CLI. La commande suivante attribue au compte de service le rôle Diffuseur Pub/Sub (roles/pubsub.publisher) sur le sujet Pub/Sub my-topic.

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

Créer un abonnement Pub/Sub

Pour afficher les messages publiés dans un sujet, vous devez également créer un abonnement associé à ce sujet. Suivez le guide de démarrage rapide de Pub/Sub pour créer des abonnements dans votre projet Pub/Sub dans la console Google Cloud. Vous pouvez également créer des abonnements avec Google Cloud CLI, comme dans cet exemple.

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

Créer un secret avec des sujets configurés

Créez un secret avec une liste de 10 sujets configurés au maximum. Tous les sujets configurés sur un secret reçoivent des notifications d'événement lorsque le secret ou l'une de ses versions est modifié. La commande suivante crée un secret avec my-topic configuré.

gcloud

Pour utiliser Secret Manager dans la ligne de commande, commencez par installer la Google Cloud CLI ou passer à la version 378.0.0 ou ultérieure. Sur Compute Engine ou GKE, vous devez vous authentifier avec le champ d'application cloud-platform.

$ gcloud secrets create SECRET_ID --topics TOPIC_NAME

API

Ces exemples utilisent curl pour illustrer l'utilisation de l'API. Vous pouvez générer des jetons d'accès avec gcloud auth print-access-token. Sur Compute Engine ou GKE, vous devez vous authentifier avec le champ d'application 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

Mettre à jour les sujets des secrets

Modifiez les sujets Pub/Sub configurés sur un secret en mettant à jour le secret avec les nouveaux noms de ressources du sujet Pub/Sub. La Google Cloud CLI vous permet d'ajouter ou de supprimer un ou plusieurs sujets d'un secret, et d'effacer tous les sujets du secret.

Ajouter des sujets

Ajoute un ou plusieurs sujets à un secret. L'ajout d'un sujet déjà présent n'aura aucun effet.

$ 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"

Supprimer les sujets

Supprime un ou plusieurs sujets d'un secret. La suppression d'un sujet qui n'est pas présent n'aura aucun effet.

$ 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"

Effacer les sujets

Supprimer tous les sujets d'un secret.

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

Utiliser les notifications d'événements avec Cloud Functions

Les notifications d'événements peuvent être utilisées pour déclencher des workflows arbitraires en créant des Cloud Functions qui consomment les messages Pub/Sub. Pour obtenir un guide complet, consultez la documentation Cloud Functions. L'exemple de code suivant concerne une fonction Cloud qui imprime eventType, secretId et les métadonnées chaque fois qu'un événement est publié dans le sujet. Vous trouverez ici la liste de tous les types d'événements pour Secret Manager.

C#

Pour exécuter ce code, commencez par configurer un environnement de développement C# et installez le SDK Secret Manager pour C#. Sur Compute Engine ou GKE, vous devez vous authentifier avec le champ d'application 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

Pour exécuter ce code, commencez par configurer un environnement de développement Go et installez le SDK Secret Manager pour Go. Sur Compute Engine ou GKE, vous devez vous authentifier avec le champ d'application 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

Pour savoir comment installer et utiliser la bibliothèque cliente pour Secret Manager, consultez la section Bibliothèques clientes Secret Manager.

Pour vous authentifier auprès de Secret Manager, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.


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

Pour exécuter ce code, commencez par configurer un environnement de développement Node.js, puis installez le SDK Secret Manager pour Node.js. Sur Compute Engine ou GKE, vous devez vous authentifier avec le champ d'application 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

Pour exécuter ce code, commencez par configurer un environnement de développement Python et installez le SDK Secret Manager pour Python. Sur Compute Engine ou GKE, vous devez vous authentifier avec le champ d'application 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

Pour exécuter ce code, commencez par configurer un environnement de développement Ruby et installez le SDK Secret Manager pour Ruby. Sur Compute Engine ou GKE, vous devez vous authentifier avec le champ d'application 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

Sujets mal configurés

Si des sujets Pub/Sub sont ajoutés à un secret dans une opération de création ou de mise à jour, mais que Secret Manager ne peut pas publier de messages sur le sujet en raison d'une erreur de configuration, l'opération échouera et renverra un message d'erreur indiquant pourquoi la publication a échoué. Cela peut se produire, par exemple, si le sujet n'existe pas ou si le compte de service Secret Manager n'est pas autorisé à publier.

Si l'ajout de sujets Pub/Sub à un secret est effectué, puis que le sujet est modifié et que Secret Manager ne peut plus publier de messages (par exemple, le sujet est supprimé ou les autorisations du compte de service de Secret Manager sont supprimées), Secret Manager écrit des journaux dans la ressource SecretSecret Manager avec un message indiquant pourquoi la publication a échoué.

Étapes suivantes