Descripción general de Cloud Data Loss Prevention

1. Descripción general

Cloud Data Loss Prevention (DLP) es un servicio completamente administrado diseñado para descubrir, clasificar y proteger información sensible. En este codelab, se presentarán algunas de las capacidades básicas de la API de Cloud DLP y se demostrarán las diversas formas en que se puede usar para proteger los datos.

Actividades

  • Usar DLP para inspeccionar cadenas y archivos en busca de infotipos coincidentes
  • Aprender sobre las técnicas de desidentificación y usar DLP para desidentificar datos
  • Obtén información para volver a identificar datos que se desidentificaron con la encriptación de preservación de formato (FPE)
  • Usa DLP para ocultar tipos de información de imágenes y cadenas

Requisitos

  • Un proyecto de Google Cloud con la facturación configurada. Si no tienes una, deberás crearla.

2. Cómo prepararte

Este codelab se puede ejecutar completamente en Google Cloud Platform sin necesidad de instalación ni configuración local.

Cloud Shell

A lo largo de este codelab, aprovisionaremos y administraremos diferentes recursos y servicios de la nube con la línea de comandos a través de Cloud Shell.

Descarga el repositorio del proyecto complementario:

git clone https://github.com/googleapis/nodejs-dlp

Una vez que se descargue el código del proyecto, cambia al directorio de muestras y, luego, instala los paquetes de Node.js requeridos:

cd samples && npm install

Asegúrate de usar el proyecto correcto configurándolo con el siguiente comando de gcloud:

gcloud config set project [PROJECT_ID]

Habilita las APIs

Estas son las APIs que deberemos habilitar en nuestro proyecto:

  • API de Cloud Data Loss Prevention: Proporciona métodos para detectar y desidentificar fragmentos sensibles en cuanto a la privacidad, así como analizar el riesgo que conllevan, en texto, imágenes y repositorios de almacenamiento de Google Cloud
  • API de Cloud Key Management Service (KMS): Google Cloud KMS permite que los clientes administren claves de encriptación y realicen operaciones criptográficas con ellas.

Habilita las APIs requeridas con el siguiente comando de gcloud:

gcloud services enable dlp.googleapis.com cloudkms.googleapis.com \
--project ${GOOGLE_CLOUD_PROJECT}

3. Inspecciona cadenas y archivos

El directorio samples del proyecto descargado en el paso anterior contiene varios archivos JavaScript que utilizan las diferentes funciones de Cloud DLP. inspect.js inspeccionará una cadena o un archivo proporcionados en busca de infotipos sensibles.

Para probar esto, puedes proporcionar la opción string y una cadena de ejemplo con información potencialmente sensible:

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'My email address is jenny@somedomain.com and you can call me at 555-867-5309'

El resultado debe indicarnos los hallazgos de cada infotipo coincidente, lo que incluye lo siguiente:

Cotización: La plantilla especifica lo siguiente:

InfoType: Es el infotipo detectado en esa parte de la cadena. Encontrarás una lista completa de los posibles tipos de información aquí. De forma predeterminada, inspect.js solo inspeccionará los infotipos CREDIT_CARD_NUMBER, PHONE_NUMBER Y EMAIL_ADDRESS.

Likelihood: Los resultados se clasifican según la probabilidad que tienen de representar una coincidencia. La probabilidad puede variar de VERY_UNLIKELY a VERY_LIKELY.

Los hallazgos de la solicitud de comando anterior son los siguientes:

Findings:
        Quote: jenny@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY
        Quote: 555-867-5309
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY

De manera similar, podemos inspeccionar archivos en busca de infotipos. Consulta el archivo de muestra accounts.txt:

resources/accounts.txt

My credit card number is 1234 5678 9012 3456, and my CVV is 789.

Vuelve a ejecutar inspect.js, esta vez con la opción de archivo:

node inspect.js -c $GOOGLE_CLOUD_PROJECT file resources/accounts.txt

Estos son los resultados:

Findings:
        Quote: 5678 9012 3456
        Info type: CREDIT_CARD_NUMBER
        Likelihood: VERY_LIKELY

Para cualquier tipo de búsqueda, podríamos limitar los resultados por probabilidad o tipo de información. Por ejemplo:

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'Call 900-649-2568 or email me at anthony@somedomain.com' \
-m VERY_LIKELY

Si especificas VERY_LIKELY como la probabilidad mínima, se excluyen todas las coincidencias inferiores a VERY_LIKELY:

Findings:
        Quote: 900-649-2568
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY

Los resultados completos sin la limitación serían los siguientes:

Findings:
        Quote: 900-649-2568
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY
        Quote: anthony@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY

De manera similar, podríamos especificar el tipo de información que estamos verificando:

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'Call 900-649-2568 or email me at anthony@somedomain.com' \
-t EMAIL_ADDRESS

Solo se devuelve el tipo de información especificado si se encuentra:

Findings:
        Quote: anthony@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY

A continuación, se muestra la función asíncrona que usa la API para inspeccionar la entrada:

inspect.js

async function inspectString(
  callingProjectId,
  string,
  minLikelihood,
  maxFindings,
  infoTypes,
  customInfoTypes,
  includeQuote
) {
...
}

Los argumentos proporcionados para los parámetros anteriores se usan para construir un objeto de solicitud. Luego, esa solicitud se proporciona a la función inspectContent para obtener una respuesta que genera nuestro resultado:

inspect.js

  // Construct item to inspect
  const item = {value: string};

  // Construct request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    inspectConfig: {
      infoTypes: infoTypes,
      customInfoTypes: customInfoTypes,
      minLikelihood: minLikelihood,
      includeQuote: includeQuote,
      limits: {
        maxFindingsPerRequest: maxFindings,
      },
    },
    item: item,
  };
...
...
 const [response] = await dlp.inspectContent(request);

4. Desidentificación

Además de inspeccionar y detectar datos sensibles, Cloud DLP puede realizar la desidentificación. La desidentificación es el proceso de quitar información de identificación de los datos. La API detecta datos sensibles según lo definido por los infotipos y, luego, usa una transformación de desidentificación para enmascarar, borrar o, de otro modo, ocultar los datos.

deid.js demostrará la seudoanonimización de varias maneras. El método más simple de seudoanonimización es con una máscara:

node deid.js deidMask -c $GOOGLE_CLOUD_PROJECT \
"My order number is F12312399. Email me at anthony@somedomain.com"

Con una máscara, la API reemplazará los caracteres del infotipo coincidente por otro carácter (de forma predeterminada, *). El resultado será el siguiente:

My order number is F12312399. Email me at *****************************

Observa que la dirección de correo electrónico de la cadena está ofuscada, mientras que el número de pedido arbitrario permanece intacto. (Es posible establecer infotipos personalizados, pero no forma parte de los temas de este codelab).

Veamos la función que usa la API de DLP para desidentificar con una máscara:

deid.js

async function deidentifyWithMask(
  callingProjectId,
  string,
  maskingCharacter,
  numberToMask
) {
...
}

Una vez más, estos argumentos se usan para construir un objeto de solicitud. Esta vez, se proporciona a la función deidentifyContent:

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              characterMaskConfig: {
                maskingCharacter: maskingCharacter,
                numberToMask: numberToMask,
              },
            },
          },
        ],
      },
    },
    item: item,
  };
... 
... 
const [response] = await dlp.deidentifyContent(request);

Desidentifica datos con encriptación de preservación de formato

La API de DLP también ofrece la capacidad de encriptar valores de datos sensibles con una clave criptográfica.

Comenzaremos por usar Cloud KMS para crear un llavero de claves:

gcloud kms keyrings create dlp-keyring --location global

Ahora podemos crear una clave que usaremos para encriptar los datos:

gcloud kms keys create dlp-key \
--purpose='encryption' \
--location=global \
--keyring=dlp-keyring

La API de DLP aceptará una clave unida encriptada con la clave de KMS que creamos. Podemos generar una cadena aleatoria que se ajustará. Necesitaremos esta información más adelante para volver a identificar:

export AES_KEY=`head -c16 < /dev/random | base64 -w 0`

Ahora podemos encriptar la cadena con nuestra clave de KMS. Esto generará un archivo binario que contiene la cadena encriptada como texto cifrado:

echo -n $AES_KEY | gcloud kms encrypt \
--location global \
--keyring dlp-keyring  \
--key dlp-key \
--plaintext-file - \
--ciphertext-file ./ciphertext.bin 

Con deid.js, ahora podemos anonimizar el número de teléfono en la siguiente cadena de ejemplo con encriptación:

node deid.js deidFpe -c $GOOGLE_CLOUD_PROJECT \
"My client's cell is 9006492568" `base64 -w 0 ciphertext.bin` \
projects/${GOOGLE_CLOUD_PROJECT}/locations/global/keyRings/dlp-keyring/cryptoKeys/dlp-key \
-s PHONE_NUMBER

El resultado mostrará la cadena con los tipos de información coincidentes reemplazados por una cadena encriptada y precedida por el tipo de información indicado por la marca -s:

My client's cell is PHONE_NUMBER(10):vSt55z79nR

Veamos la función que usamos para seudoanonimizar la cadena:

deid.js

async function deidentifyWithFpe(
  callingProjectId,
  string,
  alphabet,
  surrogateType,
  keyName,
  wrappedKey
) {
...
}

Los argumentos se usan para construir un objeto cryptoReplaceFfxFpeConfig:

deid.js

  const cryptoReplaceFfxFpeConfig = {
    cryptoKey: {
      kmsWrapped: {
        wrappedKey: wrappedKey,
        cryptoKeyName: keyName,
      },
    },
    commonAlphabet: alphabet,
  };
  if (surrogateType) {
    cryptoReplaceFfxFpeConfig.surrogateInfoType = {
      name: surrogateType,
    };
  }

A su vez, el objeto cryptoReplaceFfxFpeConfig se usa en la solicitud a la API a través de la función deidentifyContent:

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              cryptoReplaceFfxFpeConfig: cryptoReplaceFfxFpeConfig,
            },
          },
        ],
      },
    },
    item: item,
  };

  try {
    // Run deidentification request
    const [response] = await dlp.deidentifyContent(request);

Reidentificación de datos

Para reidentificar los datos, la API de DLP usará el texto cifrado que creamos en el paso anterior:

node deid.js reidFpe -c $GOOGLE_CLOUD_PROJECT \
"<YOUR_DEID_OUTPUT>" \
PHONE_NUMBER `base64 -w 0 ciphertext.bin`  \
projects/${GOOGLE_CLOUD_PROJECT}/locations/global/keyRings/dlp-keyring/cryptoKeys/dlp-key

El resultado será la cadena original sin tachaduras ni indicación de tipo de sustituto:

My client's cell is 9006492568

La función que se usa para reidentificar los datos es similar a la que se usa para desidentificarlos:

deid.js

async function reidentifyWithFpe(
  callingProjectId,
  string,
  alphabet,
  surrogateType,
  keyName,
  wrappedKey
) {
...
}

Una vez más, los argumentos se usan en una solicitud a la API, esta vez a la función reidentifyContent:

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    reidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              cryptoReplaceFfxFpeConfig: {
                cryptoKey: {
                  kmsWrapped: {
                    wrappedKey: wrappedKey,
                    cryptoKeyName: keyName,
                  },
                },
                commonAlphabet: alphabet,
                surrogateInfoType: {
                  name: surrogateType,
                },
              },
            },
          },
        ],
      },
    },
    inspectConfig: {
      customInfoTypes: [
        {
          infoType: {
            name: surrogateType,
          },
          surrogateType: {},
        },
      ],
    },
    item: item,
  };

  try {
    // Run reidentification request
    const [response] = await dlp.reidentifyContent(request);

Desidentifica fechas con el cambio de fechas

En ciertos contextos, las fechas se pueden considerar datos sensibles que tal vez queramos ofuscar. El cambio de fechas nos permite cambiar las fechas en un incremento aleatorio y, al mismo tiempo, conservar la secuencia y la duración de un período. Cada fecha de un conjunto se desplaza por una cantidad de tiempo única para esa entrada. Para demostrar la seudoanonimización a través del cambio de fecha, primero consulta el archivo CSV de muestra que contiene datos de fecha:

resources/dates.csv

name,birth_date,register_date,credit_card
Ann,01/01/1980,07/21/1996,4532908762519852
James,03/06/1988,04/09/2001,4301261899725540
Dan,08/14/1945,11/15/2011,4620761856015295
Laura,11/03/1992,01/04/2017,4564981067258901

Los datos contienen dos campos a los que podríamos aplicar un desplazamiento de fecha: birth_date y register_date. deid.js aceptará un valor de límite inferior y un valor de límite superior para definir un rango para seleccionar una cantidad aleatoria de días por la que se cambiarán las fechas:

node deid.js deidDateShift -c $GOOGLE_CLOUD_PROJECT resources/dates.csv datesShifted.csv 30 90 birth_date

Se generará un archivo llamado datesShifted.csv con las fechas cambiadas de forma aleatoria por una cantidad de días entre 30 y 90. Este es un ejemplo del resultado generado:

name,birth_date,register_date,credit_card
Ann,2/6/1980,7/21/1996,4532908762519852
James,5/18/1988,4/9/2001,4301261899725540
Dan,9/16/1945,11/15/2011,4620761856015295
Laura,12/16/1992,1/4/2017,4564981067258901

Ten en cuenta que también pudimos especificar qué columna de fecha del archivo CSV queríamos cambiar. El campo birth_date El campo register_date no se modificó.

Veamos la función que controla la seudonimización con un desplazamiento de fechas:

deid.js

async function deidentifyWithDateShift(
  callingProjectId,
  inputCsvFile,
  outputCsvFile,
  dateFields,
  lowerBoundDays,
  upperBoundDays,
  contextFieldId,
  wrappedKey,
  keyName
) {
...
}

Ten en cuenta que esta función podría aceptar una clave unida y un nombre de clave, de manera similar a la desidentificación con FPE, para que tengamos la opción de proporcionar una clave de encriptación para reidentificar un cambio de fecha. Los argumentos que proporcionamos compilan un objeto dateShiftConfig:

deid.js

  // Construct DateShiftConfig
  const dateShiftConfig = {
    lowerBoundDays: lowerBoundDays,
    upperBoundDays: upperBoundDays,
  };

  if (contextFieldId && keyName && wrappedKey) {
    dateShiftConfig.context = {name: contextFieldId};
    dateShiftConfig.cryptoKey = {
      kmsWrapped: {
        wrappedKey: wrappedKey,
        cryptoKeyName: keyName,
      },
    };
  } else if (contextFieldId || keyName || wrappedKey) {
    throw new Error(
      'You must set either ALL or NONE of {contextFieldId, keyName, wrappedKey}!'
    );
  }

  // Construct deidentification request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      recordTransformations: {
        fieldTransformations: [
          {
            fields: dateFields,
            primitiveTransformation: {
              dateShiftConfig: dateShiftConfig,
            },
          },
        ],
      },
    },
    item: tableItem,
  };

5. Oculta imágenes y cadenas

Otro método para ofuscar información sensible es la ocultación. La ocultación reemplazará una coincidencia por el infotipo con el que se identificó que coincide. redact.js muestra el ocultamiento:

node redact.js -c $GOOGLE_CLOUD_PROJECT \
string "Please refund the purchase to my credit card 4012888888881881" \
-t 'CREDIT_CARD_NUMBER'

En el resultado, el número de tarjeta de crédito de ejemplo se reemplaza por el infotipo CREDIT_CARD_NUMBER:

Please refund the purchase on my credit card [CREDIT_CARD_NUMBER]

La ocultación es útil para esconder información sensible de un modo que permite identificar el infotipo quitado. De manera similar, la API de DLP puede ocultar información de imágenes que contienen texto. Para demostrarlo, veamos una imagen de muestra:

resources/test.png

bf3719cfeb5676ff.png

Para ocultar el número de teléfono y la dirección de correo electrónico de la imagen anterior, haz lo siguiente:

node redact.js -c $GOOGLE_CLOUD_PROJECT \
image resources/test.png ./redacted.png \
-t PHONE_NUMBER -t EMAIL_ADDRESS

Como lo especificaste, se generará una nueva imagen llamada redacted.png con la información solicitada cubierta con un rectángulo negro:

ce023dd95cccc40f.png

Esta es la función que se usa para ocultar información de una cadena:

redact.js

async function redactText(
  callingProjectId, 
  string,
  minLikelihood,
  infoTypes
) {
...}

Esta es la solicitud que se proporcionará a la función deidentifyContent:

redact.js

const request = {
    parent: dlp.projectPath(callingProjectId),
    item: {
      value: string,
    },
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [replaceWithInfoTypeTransformation],
      },
    },
    inspectConfig: {
      minLikelihood: minLikelihood,
      infoTypes: infoTypes,
    },
  };

De manera similar, esta es la función para ocultar una imagen:

redact.js

async function redactImage(
  callingProjectId,
  filepath,
  minLikelihood,
  infoTypes,
  outputPath
) {
...}

Esta es la solicitud que se proporcionará a la función redactImage:

redact.js

// Construct image redaction request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    byteItem: {
      type: fileTypeConstant,
      data: fileBytes,
    },
    inspectConfig: {
      minLikelihood: minLikelihood,
      infoTypes: infoTypes,
    },
    imageRedactionConfigs: imageRedactionConfigs,
  };

6. Limpia

Exploramos cómo podemos usar la API de DLP para enmascarar, desidentificar y ocultar información sensible de nuestros datos. Ahora es momento de limpiar nuestro proyecto de todos los recursos que creamos.

Borra el proyecto

En GCP Console, ve a la página Cloud Resource Manager.

En la lista de proyectos, selecciona el proyecto en el que hemos estado trabajando y haz clic en Borrar. Se te pedirá que ingreses el ID del proyecto. Ingrésalo y haz clic en Cerrar.

Como alternativa, puedes borrar todo el proyecto directamente desde Cloud Shell con gcloud:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

7. ¡Felicitaciones!

¡Hurra! ¡Lo lograste! Cloud DLP es una herramienta potente que proporciona acceso a una plataforma de inspección, clasificación y desidentificación de datos sensibles.

Temas abordados

  • Vimos cómo se puede usar la API de Cloud DLP para inspeccionar cadenas y archivos en busca de varios infotipos.
  • Aprendimos cómo la API de DLP puede desidentificar cadenas con una máscara para ocultar datos que coinciden con los infotipos.
  • Usamos la API de DLP para desidentificar y, luego, reidentificar datos con una clave de encriptación.
  • Usamos la API de DLP para ocultar datos de una cadena y una imagen.