Receber e analisar mensagens do Pub/Sub sobre perfis de dados

Este documento fornece exemplos que demonstram como receber e analisar notificações sobre mudanças nos perfis de dados. A Proteção de dados sensíveis envia essas atualizações na forma de mensagens do Pub/Sub.

Visão geral

É possível configurar a Proteção de dados sensíveis para gerar automaticamente perfis sobre dados em uma organização, pasta ou projeto. Os perfis de dados contêm métricas e metadados sobre os dados e ajudam a determinar onde os dados sensíveis e de alto risco residem. A Proteção de dados sensíveis informa essas métricas em vários níveis de detalhes. Para saber mais sobre os tipos de dados que podem ser usados para criar perfis, consulte Recursos compatíveis.

Ao configurar o perfilador de dados, você pode ativar a opção de publicar mensagens do Pub/Sub sempre que ocorrerem mudanças significativas nos perfis de dados. As mensagens ajudam você a tomar medidas imediatas em resposta a essas mudanças. Confira a seguir os eventos que podem ser detectados:

  • Um recurso de dados recebe um perfil pela primeira vez.
  • Um perfil é atualizado.
  • A pontuação de risco ou sensibilidade de um perfil aumenta.
  • Há um novo erro relacionado aos seus perfis de dados.

As mensagens do Pub/Sub que o perfilador de dados publica contêm um objeto DataProfilePubSubMessage. Essas mensagens são sempre enviadas em formato binário. Portanto, você precisa escrever um código que as receba e analise.

Preços

Quando você usa o Pub/Sub, o faturamento é feito de acordo com os preços do Pub/Sub.

Antes de começar

Esta página pressupõe o seguinte:

Antes de começar a trabalhar nos exemplos, siga estas etapas:

  1. Crie um tópico do Pub/Sub e adicione uma assinatura a ele. Não atribua um esquema ao tópico.

    Para simplificar, os exemplos desta página ouvem apenas uma assinatura. No entanto, na prática, é possível criar um tópico e uma assinatura para cada evento com suporte à Proteção de dados sensíveis.

  2. Se ainda não tiver feito isso, configure o perfilador de dados para publicar mensagens do Pub/Sub:

    1. Edite a configuração da verificação.

    2. Na página Editar configuração de verificação, ative a opção Publicar no Pub/Sub e selecione os eventos que você quer detectar. Em seguida, configure as configurações de cada evento.

    3. Salve a configuração de verificação.

  3. Conceda ao agente de serviço da Proteção de dados sensíveis acesso de publicação no tópico do Pub/Sub. Um exemplo de função com acesso de publicação é o editor do Pub/Sub (roles/pubsub.publisher). O agente de serviço de proteção de dados sensíveis é um endereço de e-mail no formato:

    service-PROJECT_NUMBER@dlp-api.iam.gserviceaccount.com
    

    Se você estiver trabalhando com uma configuração de verificação no nível da organização ou da pasta, o PROJECT_NUMBER é o identificador numérico do contêiner do agente de serviço. Se você estiver trabalhando com uma configuração de verificação no nível do projeto, o PROJECT_NUMBER é o identificador numérico do projeto.

  4. Instale e configure a biblioteca de cliente da Proteção de dados sensíveis para Java ou Python.

Exemplos

Os exemplos a seguir demonstram como receber e analisar mensagens do Pub/Sub que o perfilador de dados publica. É possível reutilizar esses exemplos e implantá-los como funções do Cloud Run acionadas por eventos do Pub/Sub. Para mais informações, consulte o tutorial do Pub/Sub (2ª geração).

Nos exemplos a seguir, substitua:

  • PROJECT_ID: o ID do projeto que contém a assinatura do Pub/Sub.
  • SUBSCRIPTION_ID: o ID da assinatura do Pub/Sub.

Java

import com.google.api.core.ApiService;
import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.privacy.dlp.v2.DataProfilePubSubMessage;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class DataProfilePubSubMessageParser {

  public static void main(String... args) throws Exception {
    String projectId = "PROJECT_ID";
    String subscriptionId = "SUBSCRIPTION_ID";
    int timeoutSeconds = 5;

    // The `ProjectSubscriptionName.of` method creates a fully qualified identifier
    // in the form `projects/{projectId}/subscriptions/{subscriptionId}`.
    ProjectSubscriptionName subscriptionName =
        ProjectSubscriptionName.of(projectId, subscriptionId);

    MessageReceiver receiver =
        (PubsubMessage pubsubMessage, AckReplyConsumer consumer) -> {
          try {
            DataProfilePubSubMessage message = DataProfilePubSubMessage.parseFrom(
                pubsubMessage.getData());
            System.out.println(
                "PubsubMessage with ID: " + pubsubMessage.getMessageId()
                    + "; message size: " + pubsubMessage.getData().size()
                    + "; event: " + message.getEvent()
                    + "; profile name: " + message.getProfile().getName()
                    + "; full resource: " + message.getProfile().getFullResource());
            consumer.ack();
          } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
          }
        };

    // Create subscriber client.
    Subscriber subscriber = Subscriber.newBuilder(subscriptionName, receiver).build();
    try {
      ApiService apiService = subscriber.startAsync();
      apiService.awaitRunning();
      System.out.printf("Listening for messages on %s for %d seconds.%n", subscriptionName,
          timeoutSeconds);
      subscriber.awaitTerminated(timeoutSeconds, TimeUnit.SECONDS);
    } catch (TimeoutException ignored) {
    } finally {
      subscriber.stopAsync();
    }
  }
}

Python

from google.cloud import pubsub_v1
from concurrent.futures import TimeoutError
from google.cloud import dlp_v2


project_id = "PROJECT_ID"
subscription_id = "SUBSCRIPTION_ID"
timeout = 5.0

subscriber = pubsub_v1.SubscriberClient()
# The `subscription_path` method creates a fully qualified identifier
# in the form `projects/{project_id}/subscriptions/{subscription_id}`
subscription_path = subscriber.subscription_path(project_id, subscription_id)

def callback(message: pubsub_v1.subscriber.message.Message) -> None:
    print(f"Received {message.data}.")
    dlp_msg = dlp_v2.DataProfilePubSubMessage()
    dlp_msg._pb.ParseFromString(message.data)
    print("Parsed message: ", dlp_msg)
    print("--------")
    message.ack()

streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path} for {timeout} seconds...")

# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
    try:
        # When `timeout` is not set, result() will block indefinitely,
        # unless an exception is encountered first.
        streaming_pull_future.result(timeout=timeout)
    except TimeoutError:
        streaming_pull_future.cancel()  # Trigger the shutdown.
        streaming_pull_future.result()  # Block until the shutdown is complete.
        print("Done waiting.")

A seguir