Inspecciona el almacenamiento y las bases de datos de Google Cloud en busca de datos sensibles

La administración correcta de los datos sensibles almacenados en un repositorio de almacenamiento comienza con la clasificación del almacenamiento: identifica dónde están los datos sensibles en el repositorio, de qué tipo de datos sensibles se trata y cómo se usan. Esta información te ayuda a establecer de manera correcta el control de acceso y los permisos para compartir y puede ser parte de un plan de supervisión constante.

Sensitive Data Protection puede detectar y clasificar datos sensibles almacenados en una ubicación de Cloud Storage, un tipo de Datastore o una tabla de BigQuery. Cuando se analizan archivos en ubicaciones de Cloud Storage, Sensitive Data Protection admite el análisis de archivos de objetos binarios, de texto, de imagen, de Microsoft Word, Microsoft Excel, Microsoft PowerPoint, PDF y Apache Avro. Los tipos de archivos que no se reconocen se analizan como archivos binarios. Para obtener más información sobre los tipos de archivos admitidos, consulta Tipos de archivos admitidos.

Para inspeccionar el almacenamiento y las bases de datos en busca de datos sensibles, especifica la ubicación de los datos y el tipo de datos sensibles que Sensitive Data Protection debe buscar. La Protección de datos sensibles inicia un trabajo que inspecciona los datos en la ubicación determinada y, luego, proporciona detalles sobre los infoTypes que se encontraron en el contenido, los valores de probabilidad y mucho más.

Puedes configurar la inspección de almacenamiento y bases de datos con Sensitive Data Protection en la Google Cloud consola, a través de la API de DLP de RESTful o de manera programática en varios lenguajes con una biblioteca cliente de Sensitive Data Protection.

En este tema se incluye lo siguiente:

  • Prácticas recomendadas para configurar análisis de repositorios de almacenamiento y bases de datos Google Cloud
  • Instrucciones para configurar un análisis de inspección con Sensitive Data Protection en la consola de Google Cloud y, de manera opcional, programar análisis de inspección periódicos
  • Muestras de código y JSON para cada tipo de repositorio de almacenamiento Google Cloud (Cloud Storage, Firestore en modo Datastore [Datastore] y BigQuery)
  • Una descripción detallada de las opciones de configuración para los trabajos de análisis
  • Instrucciones sobre cómo recuperar los resultados de los análisis y cómo administrar los trabajos de análisis que se crean en cada solicitud exitosa

Prácticas recomendadas

Identifica y prioriza el análisis

Es importante evaluar primero tus elementos y especificar cuáles tienen la prioridad más alta para el análisis. Cuando recién comienzas, es posible que tengas una gran cantidad de datos acumulados que necesiten clasificación y será imposible analizarlos de inmediato. En primer lugar, elige los datos que presenten el riesgo más alto posible, por ejemplo, datos a los que se accede con frecuencia, a los que se puede acceder con facilidad o que se desconocen.

Asegúrate de que Sensitive Data Protection pueda acceder a tus datos

Sensitive Data Protection debe poder acceder a los datos que se analizarán. Asegúrate de que la cuenta de servicio de Protección de datos sensibles tenga permiso para leer tus recursos.

Limita el alcance de tus primeros análisis

Para obtener mejores resultados, limita el alcance de tus primeros trabajos en lugar de analizar todos los datos. Comienza con una tabla, un depósito o algunos archivos y usa el muestreo. Como limitaste el alcance de los primeros análisis, puedes determinar mejor qué detectores habilitar y qué reglas de exclusión podrían ser necesarias para reducir los falsos positivos a fin de que los hallazgos sean más significativos. Evita activar todos los Infotipos si no los necesitas a todos, ya que los falsos positivos o los resultados inutilizables pueden hacer que sea más difícil evaluar el riesgo. Si bien son útiles en ciertos casos, los Infotipos como DATE, TIME, DOMAIN_NAME y URL coinciden en una amplia gama de resultados y pueden no ser útiles para activarlos en análisis de datos grandes.

Cuando tomes una muestra de un archivo estructurado, como un archivo CSV, TSV o Avro, asegúrate de que el tamaño de la muestra sea lo suficientemente grande como para abarcar el encabezado completo del archivo y una fila de datos. Para obtener más información, consulta Cómo analizar archivos estructurados en el modo de análisis estructurado.

Programa tus análisis

Usa los activadores de trabajo de Sensitive Data Protection para ejecutar análisis automáticamente y generar resultados de forma diaria, semanal o trimestral. Estos análisis también se pueden configurar para inspeccionar solo los datos que cambiaron desde el último análisis, lo que puede ahorrar tiempo y reducir los costos. La ejecución de análisis con regularidad puede ayudarte a identificar tendencias o anomalías en los resultados de los análisis.

Latencia del trabajo

No hay objetivos de nivel de servicio (SLO) garantizados para los trabajos ni los activadores de trabajos. La latencia se ve afectada por varios factores, como la cantidad de datos que se analizarán, el repositorio de almacenamiento que se analiza, el tipo y la cantidad de Infotipos que se buscan, la región en la que se procesa el trabajo y los recursos de procesamiento disponibles en esa región. Por lo tanto, la latencia de los trabajos de inspección no se puede determinar con anticipación.

Para ayudar a reducir la latencia del trabajo, puedes probar con las siguientes opciones:

  • Si el muestreo está disponible para tu trabajo o activador de trabajo, habilítalo.
  • Evita habilitar Infotipos que no necesites. Si bien los siguientes son útiles en ciertas situaciones, estos infoTypes pueden hacer que las solicitudes se ejecuten mucho más lentamente que las solicitudes que no los incluyen:

    • PERSON_NAME
    • FEMALE_NAME
    • MALE_NAME
    • FIRST_NAME
    • LAST_NAME
    • DATE_OF_BIRTH
    • LOCATION
    • STREET_ADDRESS
    • ORGANIZATION_NAME
  • Especifica siempre los Infotipos de forma explícita. No uses una lista de Infotipos vacía.

  • Si es posible, usa otra región de procesamiento.

Si sigues teniendo problemas de latencia con los trabajos después de probar estas técnicas, considera usar solicitudes de content.inspect o content.deidentify en lugar de trabajos. Estos métodos están cubiertos por el Acuerdo de Nivel de Servicio. Para obtener más información, consulta el Acuerdo de Nivel de Servicio de Sensitive Data Protection.

Antes de comenzar

En las instrucciones proporcionadas en este tema, se supone lo siguiente:

La clasificación del almacenamiento requiere el siguiente alcance de OAuth: https://www.googleapis.com/auth/cloud-platform. Para obtener más información, consulta Autenticación en la API de DLP.

Inspecciona una ubicación de Cloud Storage

Puedes configurar una inspección de Sensitive Data Protection de una ubicación de Cloud Storage con la Google Cloud consola, la API de DLP a través de solicitudes de REST o RPC, o de manera programática en varios lenguajes con una biblioteca cliente. Para obtener información sobre los parámetros incluidos con los siguientes JSON y muestras de código, consulta “Configura la inspección de almacenamiento” más adelante en este tema.

Sensitive Data Protection se basa en las extensiones de archivos y los tipos de medios (MIME) para identificar los tipos de archivos que se analizarán y los modos de análisis que se aplicarán. Por ejemplo, la Protección de datos sensibles analiza un archivo .txt en modo de texto sin formato, incluso si el archivo está estructurado como un archivo CSV, que normalmente se analiza en modo de análisis estructurado.

Para configurar un trabajo de análisis de un bucket de Cloud Storage con Sensitive Data Protection, sigue estos pasos:

Console

En esta sección, se describe cómo inspeccionar un bucket o una carpeta de Cloud Storage. Si también deseas que Sensitive Data Protection cree una copia desidentificada de tus datos, consulta Cómo desidentificar datos sensibles almacenados en Cloud Storage con la consola de Google Cloud .

  1. En la sección Protección de datos sensibles de la consola de Google Cloud , ve a la página Crear trabajo o activador de trabajo.

    Ir a Crear trabajo o activador de trabajo

  2. Ingresa la información del trabajo de Protección de datos sensibles y haz clic en Continuar para completar cada paso:

    • En Elige los datos de entrada, asígnale un nombre al trabajo ingresando un valor en el campo Nombre. En Ubicación, elige Cloud Storage en el menú Tipo de almacenamiento y, luego, ingresa la ubicación de los datos que deseas analizar. La sección Muestreo está preconfigurada para ejecutar un análisis de muestra con tus datos. Puedes ajustar el campo Porcentaje de objetos analizados dentro del depósito para ahorrar recursos si tienes una gran cantidad de datos. Para obtener más detalles, consulta Elige los datos de entrada.

    • (Opcional) En Configurar detección, puedes configurar qué tipos de datos buscar, llamados “infoTypes”. Puedes elegir de la lista de Infotipos predefinidos o seleccionar una plantilla si la hay. Para obtener más detalles, consulta Configura la detección.

    • En Agregar acciones, selecciona una o más acciones que Sensitive Data Protection realizará después de que se complete el trabajo. Para obtener más información, consulta Habilita las acciones de inspección o análisis de riesgo.

      Después de seleccionar las acciones, haz clic en Continuar.

    • (Opcional) En Programar, para ejecutar el análisis una sola vez, deja el menú configurado en Ninguno. A fin de programar análisis que se ejecuten de forma periódica, haz clic en Crear un activador para ejecutar el trabajo de forma periódica. Para obtener más detalles, consulta Programa.

  3. Haz clic en Crear.

  4. Una vez que se complete el trabajo de protección de datos sensibles, se te redireccionará a la página de detalles del trabajo y recibirás una notificación por correo electrónico. Puedes ver los resultados de la inspección en la página de detalles del trabajo.

  5. (Opcional) Si elegiste publicar los resultados de la protección de datos sensibles en BigQuery, en la página Detalles del trabajo, haz clic en Ver resultados en BigQuery para abrir la tabla en la IU web de BigQuery. Luego, puedes consultar la tabla y analizar los resultados. Para obtener más información sobre cómo consultar los resultados en BigQuery, consulta Consulta los resultados de la protección de datos sensibles en BigQuery.

Protocolo

A continuación, hay un JSON de muestra que se puede enviar en una solicitud POST al extremo de REST especificado de Sensitive Data Protection. En este JSON de ejemplo, se muestra cómo usar la API de DLP para inspeccionar buckets de Cloud Storage. Para obtener información sobre los parámetros incluidos en la solicitud, consulta “Configura la inspección de almacenamiento” más adelante en este tema.

Puedes probar esto de forma rápida en el Explorador de API en la página de referencia de content.inspect:

Ir al Explorador de API

Ten en cuenta que una solicitud con éxito, incluso en el Explorador de API, creará un trabajo de análisis nuevo. Para obtener información sobre cómo controlar los trabajos de análisis, consulta “Recupera los resultados de inspección” más adelante en este tema. Si quieres obtener información general sobre el uso de JSON para enviar solicitudes a la API de DLP, consulta la guía de inicio rápido de JSON.

Entrada de JSON:

POST https://dlp.googleapis.com/v2/projects/[PROJECT-ID]/dlpJobs?key={YOUR_API_KEY}

{
  "inspectJob":{
    "storageConfig":{
      "cloudStorageOptions":{
        "fileSet":{
          "url":"gs://[BUCKET-NAME]/*"
        },
        "bytesLimitPerFile":"1073741824"
      },
      "timespanConfig":{
        "startTime":"2017-11-13T12:34:29.965633345Z",
        "endTime":"2018-01-05T04:45:04.240912125Z"
      }
    },
    "inspectConfig":{
      "infoTypes":[
        {
          "name":"PHONE_NUMBER"
        }
      ],
      "excludeInfoTypes":false,
      "includeQuote":true,
      "minLikelihood":"LIKELY"
    },
    "actions":[
      {
        "saveFindings":{
          "outputConfig":{
            "table":{
              "projectId":"[PROJECT-ID]",
              "datasetId":"[DATASET-ID]"
            }
          }
        }
      }
    ]
  }
}

Resultado de JSON:

{
  "name":"projects/[PROJECT-ID]/dlpJobs/[JOB-ID]",
  "type":"INSPECT_JOB",
  "state":"PENDING",
  "inspectDetails":{
    "requestedOptions":{
      "snapshotInspectTemplate":{

      },
      "jobConfig":{
        "storageConfig":{
          "cloudStorageOptions":{
            "fileSet":{
              "url":"gs://[BUCKET-NAME]/*"
            },
            "bytesLimitPerFile":"1073741824"
          },
          "timespanConfig":{
            "startTime":"2017-11-13T12:34:29.965633345Z",
            "endTime":"2018-01-05T04:45:04.240912125Z"
          }
        },
        "inspectConfig":{
          "infoTypes":[
            {
              "name":"PHONE_NUMBER"
            }
          ],
          "minLikelihood":"LIKELY",
          "limits":{

          },
          "includeQuote":true
        },
        "actions":[
          {
            "saveFindings":{
              "outputConfig":{
                "table":{
                  "projectId":"[PROJECT-ID]",
                  "datasetId":"[DATASET-ID]",
                  "tableId":"[NEW-TABLE-ID]"
                }
              }
            }
          }
        ]
      }
    }
  },
  "createTime":"2018-11-07T18:01:14.225Z"
}

Java

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Sensitive Data Protection, consulta las bibliotecas cliente de Sensitive Data Protection.

Para autenticarte en Protección de datos sensibles, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.


import com.google.api.core.SettableApiFuture;
import com.google.cloud.dlp.v2.DlpServiceClient;
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.Action;
import com.google.privacy.dlp.v2.CloudStorageOptions;
import com.google.privacy.dlp.v2.CloudStorageOptions.FileSet;
import com.google.privacy.dlp.v2.CreateDlpJobRequest;
import com.google.privacy.dlp.v2.DlpJob;
import com.google.privacy.dlp.v2.GetDlpJobRequest;
import com.google.privacy.dlp.v2.InfoType;
import com.google.privacy.dlp.v2.InfoTypeStats;
import com.google.privacy.dlp.v2.InspectConfig;
import com.google.privacy.dlp.v2.InspectDataSourceDetails;
import com.google.privacy.dlp.v2.InspectJobConfig;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.StorageConfig;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class InspectGcsFile {

  public static void main(String[] args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String gcsUri = "gs://" + "your-bucket-name" + "/path/to/your/file.txt";
    String topicId = "your-pubsub-topic-id";
    String subscriptionId = "your-pubsub-subscription-id";
    inspectGcsFile(projectId, gcsUri, topicId, subscriptionId);
  }

  // Inspects a file in a Google Cloud Storage Bucket.
  public static void inspectGcsFile(
      String projectId, String gcsUri, String topicId, String subscriptionId)
      throws ExecutionException, InterruptedException, IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (DlpServiceClient dlp = DlpServiceClient.create()) {
      // Specify the GCS file to be inspected.
      CloudStorageOptions cloudStorageOptions =
          CloudStorageOptions.newBuilder().setFileSet(FileSet.newBuilder().setUrl(gcsUri)).build();

      StorageConfig storageConfig =
          StorageConfig.newBuilder().setCloudStorageOptions(cloudStorageOptions).build();

      // Specify the type of info the inspection will look for.
      // See https://cloud.google.com/dlp/docs/infotypes-reference for complete list of info types
      List<InfoType> infoTypes =
          Stream.of("PHONE_NUMBER", "EMAIL_ADDRESS", "CREDIT_CARD_NUMBER")
              .map(it -> InfoType.newBuilder().setName(it).build())
              .collect(Collectors.toList());

      // Specify how the content should be inspected.
      InspectConfig inspectConfig =
          InspectConfig.newBuilder().addAllInfoTypes(infoTypes).setIncludeQuote(true).build();

      // Specify the action that is triggered when the job completes.
      String pubSubTopic = String.format("projects/%s/topics/%s", projectId, topicId);
      Action.PublishToPubSub publishToPubSub =
          Action.PublishToPubSub.newBuilder().setTopic(pubSubTopic).build();
      Action action = Action.newBuilder().setPubSub(publishToPubSub).build();

      // Configure the long running job we want the service to perform.
      InspectJobConfig inspectJobConfig =
          InspectJobConfig.newBuilder()
              .setStorageConfig(storageConfig)
              .setInspectConfig(inspectConfig)
              .addActions(action)
              .build();

      // Create the request for the job configured above.
      CreateDlpJobRequest createDlpJobRequest =
          CreateDlpJobRequest.newBuilder()
              .setParent(LocationName.of(projectId, "global").toString())
              .setInspectJob(inspectJobConfig)
              .build();

      // Use the client to send the request.
      final DlpJob dlpJob = dlp.createDlpJob(createDlpJobRequest);
      System.out.println("Job created: " + dlpJob.getName());

      // Set up a Pub/Sub subscriber to listen on the job completion status
      final SettableApiFuture<Boolean> done = SettableApiFuture.create();

      ProjectSubscriptionName subscriptionName =
          ProjectSubscriptionName.of(projectId, subscriptionId);

      MessageReceiver messageHandler =
          (PubsubMessage pubsubMessage, AckReplyConsumer ackReplyConsumer) -> {
            handleMessage(dlpJob, done, pubsubMessage, ackReplyConsumer);
          };
      Subscriber subscriber = Subscriber.newBuilder(subscriptionName, messageHandler).build();
      subscriber.startAsync();

      // Wait for job completion semi-synchronously
      // For long jobs, consider using a truly asynchronous execution model such as Cloud Functions
      try {
        done.get(15, TimeUnit.MINUTES);
      } catch (TimeoutException e) {
        System.out.println("Job was not completed after 15 minutes.");
        return;
      } finally {
        subscriber.stopAsync();
        subscriber.awaitTerminated();
      }

      // Get the latest state of the job from the service
      GetDlpJobRequest request = GetDlpJobRequest.newBuilder().setName(dlpJob.getName()).build();
      DlpJob completedJob = dlp.getDlpJob(request);

      // Parse the response and process results.
      System.out.println("Job status: " + completedJob.getState());
      System.out.println("Job name: " + dlpJob.getName());
      InspectDataSourceDetails.Result result = completedJob.getInspectDetails().getResult();
      System.out.println("Findings: ");
      for (InfoTypeStats infoTypeStat : result.getInfoTypeStatsList()) {
        System.out.print("\tInfo type: " + infoTypeStat.getInfoType().getName());
        System.out.println("\tCount: " + infoTypeStat.getCount());
      }
    }
  }

  // handleMessage injects the job and settableFuture into the message reciever interface
  private static void handleMessage(
      DlpJob job,
      SettableApiFuture<Boolean> done,
      PubsubMessage pubsubMessage,
      AckReplyConsumer ackReplyConsumer) {
    String messageAttribute = pubsubMessage.getAttributesMap().get("DlpJobName");
    if (job.getName().equals(messageAttribute)) {
      done.set(true);
      ackReplyConsumer.ack();
    } else {
      ackReplyConsumer.nack();
    }
  }
}

Node.js

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Sensitive Data Protection, consulta las bibliotecas cliente de Sensitive Data Protection.

Para autenticarte en Protección de datos sensibles, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

// Import the Google Cloud client libraries
const DLP = require('@google-cloud/dlp');
const {PubSub} = require('@google-cloud/pubsub');

// Instantiates clients
const dlp = new DLP.DlpServiceClient();
const pubsub = new PubSub();

// The project ID to run the API call under
// const projectId = 'my-project';

// The name of the bucket where the file resides.
// const bucketName = 'YOUR-BUCKET';

// The path to the file within the bucket to inspect.
// Can contain wildcards, e.g. "my-image.*"
// const fileName = 'my-image.png';

// The minimum likelihood required before returning a match
// const minLikelihood = 'LIKELIHOOD_UNSPECIFIED';

// The maximum number of findings to report per request (0 = server maximum)
// const maxFindings = 0;

// The infoTypes of information to match
// const infoTypes = [{ name: 'PHONE_NUMBER' }, { name: 'EMAIL_ADDRESS' }, { name: 'CREDIT_CARD_NUMBER' }];

// The customInfoTypes of information to match
// const customInfoTypes = [{ infoType: { name: 'DICT_TYPE' }, dictionary: { wordList: { words: ['foo', 'bar', 'baz']}}},
//   { infoType: { name: 'REGEX_TYPE' }, regex: {pattern: '\\(\\d{3}\\) \\d{3}-\\d{4}'}}];

// The name of the Pub/Sub topic to notify once the job completes
// TODO(developer): create a Pub/Sub topic to use for this
// const topicId = 'MY-PUBSUB-TOPIC'

// The name of the Pub/Sub subscription to use when listening for job
// completion notifications
// TODO(developer): create a Pub/Sub subscription to use for this
// const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION'

async function inspectGCSFile() {
  // Get reference to the file to be inspected
  const storageItem = {
    cloudStorageOptions: {
      fileSet: {url: `gs://${bucketName}/${fileName}`},
    },
  };

  // Construct request for creating an inspect job
  const request = {
    parent: `projects/${projectId}/locations/global`,
    inspectJob: {
      inspectConfig: {
        infoTypes: infoTypes,
        customInfoTypes: customInfoTypes,
        minLikelihood: minLikelihood,
        limits: {
          maxFindingsPerRequest: maxFindings,
        },
      },
      storageConfig: storageItem,
      actions: [
        {
          pubSub: {
            topic: `projects/${projectId}/topics/${topicId}`,
          },
        },
      ],
    },
  };

  // Create a GCS File inspection job and wait for it to complete
  const [topicResponse] = await pubsub.topic(topicId).get();
  // Verify the Pub/Sub topic and listen for job notifications via an
  // existing subscription.
  const subscription = await topicResponse.subscription(subscriptionId);
  const [jobsResponse] = await dlp.createDlpJob(request);
  // Get the job's ID
  const jobName = jobsResponse.name;
  // Watch the Pub/Sub topic until the DLP job finishes
  await new Promise((resolve, reject) => {
    const messageHandler = message => {
      if (message.attributes && message.attributes.DlpJobName === jobName) {
        message.ack();
        subscription.removeListener('message', messageHandler);
        subscription.removeListener('error', errorHandler);
        resolve(jobName);
      } else {
        message.nack();
      }
    };

    const errorHandler = err => {
      subscription.removeListener('message', messageHandler);
      subscription.removeListener('error', errorHandler);
      reject(err);
    };

    subscription.on('message', messageHandler);
    subscription.on('error', errorHandler);
  });

  setTimeout(() => {
    console.log('Waiting for DLP job to fully complete');
  }, 500);
  const [job] = await dlp.getDlpJob({name: jobName});
  console.log(`Job ${job.name} status: ${job.state}`);

  const infoTypeStats = job.inspectDetails.result.infoTypeStats;
  if (infoTypeStats.length > 0) {
    infoTypeStats.forEach(infoTypeStat => {
      console.log(
        `  Found ${infoTypeStat.count} instance(s) of infoType ${infoTypeStat.infoType.name}.`
      );
    });
  } else {
    console.log('No findings.');
  }
}
await inspectGCSFile();

Python

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Sensitive Data Protection, consulta las bibliotecas cliente de Sensitive Data Protection.

Para autenticarte en Protección de datos sensibles, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import threading
from typing import List, Optional

import google.cloud.dlp
import google.cloud.pubsub


def inspect_gcs_file(
    project: str,
    bucket: str,
    filename: str,
    topic_id: str,
    subscription_id: str,
    info_types: List[str],
    custom_dictionaries: List[str] = None,
    custom_regexes: List[str] = None,
    min_likelihood: Optional[str] = None,
    max_findings: Optional[int] = None,
    timeout: int = 300,
) -> None:
    """Uses the Data Loss Prevention API to analyze a file on GCS.
    Args:
        project: The Google Cloud project id to use as a parent resource.
        bucket: The name of the GCS bucket containing the file, as a string.
        filename: The name of the file in the bucket, including the path, as a
            string; e.g. 'images/myfile.png'.
        topic_id: The id of the Cloud Pub/Sub topic to which the API will
            broadcast job completion. The topic must already exist.
        subscription_id: The id of the Cloud Pub/Sub subscription to listen on
            while waiting for job completion. The subscription must already
            exist and be subscribed to the topic.
        info_types: A list of strings representing info types to look for.
            A full list of info type categories can be fetched from the API.
        min_likelihood: A string representing the minimum likelihood threshold
            that constitutes a match. One of: 'LIKELIHOOD_UNSPECIFIED',
            'VERY_UNLIKELY', 'UNLIKELY', 'POSSIBLE', 'LIKELY', 'VERY_LIKELY'.
        max_findings: The maximum number of findings to report; 0 = no maximum.
        timeout: The number of seconds to wait for a response from the API.
    Returns:
        None; the response from the API is printed to the terminal.
    """

    # Instantiate a client.
    dlp = google.cloud.dlp_v2.DlpServiceClient()

    # Prepare info_types by converting the list of strings into a list of
    # dictionaries (protos are also accepted).
    if not info_types:
        info_types = ["FIRST_NAME", "LAST_NAME", "EMAIL_ADDRESS"]
    info_types = [{"name": info_type} for info_type in info_types]

    # Prepare custom_info_types by parsing the dictionary word lists and
    # regex patterns.
    if custom_dictionaries is None:
        custom_dictionaries = []
    dictionaries = [
        {
            "info_type": {"name": f"CUSTOM_DICTIONARY_{i}"},
            "dictionary": {"word_list": {"words": custom_dict.split(",")}},
        }
        for i, custom_dict in enumerate(custom_dictionaries)
    ]
    if custom_regexes is None:
        custom_regexes = []
    regexes = [
        {
            "info_type": {"name": f"CUSTOM_REGEX_{i}"},
            "regex": {"pattern": custom_regex},
        }
        for i, custom_regex in enumerate(custom_regexes)
    ]
    custom_info_types = dictionaries + regexes

    # Construct the configuration dictionary. Keys which are None may
    # optionally be omitted entirely.
    inspect_config = {
        "info_types": info_types,
        "custom_info_types": custom_info_types,
        "min_likelihood": min_likelihood,
        "limits": {"max_findings_per_request": max_findings},
    }

    # Construct a storage_config containing the file's URL.
    url = f"gs://{bucket}/{filename}"
    storage_config = {"cloud_storage_options": {"file_set": {"url": url}}}

    # Convert the project id into full resource ids.
    topic = google.cloud.pubsub.PublisherClient.topic_path(project, topic_id)
    parent = f"projects/{project}/locations/global"

    # Tell the API where to send a notification when the job is complete.
    actions = [{"pub_sub": {"topic": topic}}]

    # Construct the inspect_job, which defines the entire inspect content task.
    inspect_job = {
        "inspect_config": inspect_config,
        "storage_config": storage_config,
        "actions": actions,
    }

    operation = dlp.create_dlp_job(
        request={"parent": parent, "inspect_job": inspect_job}
    )
    print(f"Inspection operation started: {operation.name}")

    # Create a Pub/Sub client and find the subscription. The subscription is
    # expected to already be listening to the topic.
    subscriber = google.cloud.pubsub.SubscriberClient()
    subscription_path = subscriber.subscription_path(project, subscription_id)

    # Set up a callback to acknowledge a message. This closes around an event
    # so that it can signal that it is done and the main thread can continue.
    job_done = threading.Event()

    def callback(message: google.cloud.pubsub_v1.subscriber.message.Message) -> None:
        try:
            if message.attributes["DlpJobName"] == operation.name:
                # This is the message we're looking for, so acknowledge it.
                message.ack()

                # Now that the job is done, fetch the results and print them.
                job = dlp.get_dlp_job(request={"name": operation.name})
                print(f"Job name: {job.name}")
                if job.inspect_details.result.info_type_stats:
                    for finding in job.inspect_details.result.info_type_stats:
                        print(
                            f"Info type: {finding.info_type.name}; Count: {finding.count}"
                        )
                else:
                    print("No findings.")

                # Signal to the main thread that we can exit.
                job_done.set()
            else:
                # This is not the message we're looking for.
                message.drop()
        except Exception as e:
            # Because this is executing in a thread, an exception won't be
            # noted unless we print it manually.
            print(e)
            raise

    subscriber.subscribe(subscription_path, callback=callback)
    finished = job_done.wait(timeout=timeout)
    if not finished:
        print(
            "No event received before the timeout. Please verify that the "
            "subscription provided is subscribed to the topic provided."
        )

Go

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Sensitive Data Protection, consulta las bibliotecas cliente de Sensitive Data Protection.

Para autenticarte en Protección de datos sensibles, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta