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 mostrarán las diversas formas en que se puede usar para proteger los datos.

Actividades

  • Usa DLP para inspeccionar strings y archivos en busca de tipos de información que coincidan
  • Aprender sobre las técnicas de desidentificación y usar DLP para desidentificar datos
  • Más información para reidentificar datos que se desidentificaron mediante la encriptación de preservación de formato (FPE)
  • Usa DLP para ocultar los tipos de información de imágenes y cadenas

Requisitos

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

2. Cómo prepararte

Este codelab puede ejecutarse completamente en Google Cloud Platform sin ninguna instalación o configuración local.

Cloud Shell

Durante este codelab, aprovisionaremos y administraremos diferentes servicios y recursos de la nube con la línea de comandos 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 ejemplos y, luego, instala los paquetes obligatorios de Node.js:

cd samples && npm install

Para asegurarte de usar el proyecto correcto, configúralo con el siguiente comando de gcloud:

gcloud config set project [PROJECT_ID]

Habilitar APIs

Estas son las APIs que debemos habilitar en nuestro proyecto:

  • API de Cloud Data Loss Prevention: Proporciona métodos para la detección, el análisis de riesgos y la desidentificación de fragmentos sensibles a la privacidad en texto, imágenes y repositorios de almacenamiento de Google Cloud Platform.
  • API de Cloud Key Management Service (KMS): Google Cloud KMS permite a los clientes administrar claves de encriptación y realizar operaciones criptográficas con esas claves.

Habilita las APIs necesarias con el siguiente comando de gcloud:

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

3. Cómo inspeccionar cadenas y archivos

El directorio de muestras del proyecto descargado en el paso anterior contiene varios archivos JavaScript que usan las diferentes funciones de Cloud DLP. inspect.js inspeccionará una cadena o un archivo proporcionado en busca de tipos de información sensible.

Para probar esto, puedes proporcionar la opción string y una cadena de muestra 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 decirnos los resultados de cada tipo de información coincidente, lo que incluye lo siguiente:

Cita: La plantilla especifica

InfoType: el tipo de información detectado para esa parte de la string. Encontrarás una lista completa de los posibles tipos de información aquí. De forma predeterminada, inspect.js solo inspeccionará los tipos de información CREDIT_CARD_NUMBER, PHONE_NUMBER y EMAIL_ADDRESS.

Probabilidad: Los resultados se clasifican según la probabilidad de que cada uno represente una coincidencia. La probabilidad puede variar de VERY_UNLIKELY a VERY_LIKELY.

Los resultados 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

Del mismo modo, podemos inspeccionar los archivos en busca de tipos de información. Consulta el archivo accounts.txt de muestra:

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 consulta, 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 limitaciones, 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

Del mismo modo, 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 muestra 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 envía a la función inspectContent para obtener una respuesta que dé como resultado 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 la definición de los tipos de información y, luego, usa una transformación de desidentificación para ocultar, enmascarar o borrar los datos.

deid.js demostrará la desidentificación de varias maneras. El método de desidentificación más simple 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 tipo de información coincidente con un carácter diferente, *, de forma predeterminada. Este será el resultado:

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

Ten en cuenta que la dirección de correo electrónico en la cadena está ofuscada, mientras que el número de orden arbitrario está intacto. Es posible usar tipos de información personalizados, pero están fuera del alcance 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);

Desidentificar con encriptación que preserva el formato

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

Comenzaremos usando 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 unirá. Lo necesitaremos más adelante para volver a identificarlo:

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 desidentificar el número de teléfono en la siguiente cadena de muestra mediante la 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 devolverá 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 desidentificar 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);

Reidentificar datos

Para volver a identificar los datos, la API de DLP utilizará 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 ocultaciones ni el tipo subrogado:

My client's cell is 9006492568

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

deid.js

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

Y, 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 algunos contextos, las fechas se pueden considerar datos sensibles que quizás queremos ofuscar. El cambio de fechas nos permite cambiar las fechas por un incremento aleatorio y, al mismo tiempo, preservar la secuencia y la duración de un período. Cada fecha en un conjunto se desplaza por una cantidad de tiempo única para esa entrada. Para demostrar la desidentificación mediante el cambio de fechas, primero consulta el archivo CSV de muestra que contiene los datos de fechas:

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 cambio 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 que permita seleccionar un número de días al azar para cambiar 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

Observa que también pudimos especificar qué columna de fecha en el archivo CSV queríamos cambiar. El campo birth_date El campo register_date no se modifica.

Veamos una función que controla la desidentificación con un cambio de fecha:

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, 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. Ocultar imágenes y cadenas

Otro método para ofuscar información sensible es la ocultación. La ocultación reemplazará una coincidencia por el tipo de información con el que se identificó. 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'

El resultado reemplaza el número de tarjeta de crédito de muestra con el tipo de información CREDIT_CARD_NUMBER:

Please refund the purchase on my credit card [CREDIT_CARD_NUMBER]

Esto es útil si quieres ocultar información sensible sin dejar de identificar el tipo de información que se quitará. La API de DLP puede ocultar de manera similar información de las imágenes que contienen texto. Para demostrarlo, veamos una imagen de muestra:

resources/test.png

bf3719cfeb5676ff.png

Sigue estos pasos para ocultar el número de teléfono y la dirección de correo electrónico de la imagen anterior:

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

Como se especifica, se generará una imagen nueva llamada redacted.png con la información solicitada oculta:

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 el momento de limpiar nuestro proyecto con cualquier recurso que hayamos creado.

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 que proporciona acceso a una sólida 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 tipos de información.
  • Aprendimos cómo la API de DLP puede desidentificar strings con una máscara para ocultar tipos de información de coincidencia de datos
  • Usamos la API de DLP a fin de usar una clave de encriptación para desidentificar y, luego, reidentificar los datos
  • Usamos la API de DLP para ocultar datos de una cadena y de una imagen