Como criar modelos de transformação de desidentificação do Cloud DLP para conjuntos de dados de PII

Neste tutorial, mostramos como criar e gerenciar transformações de desidentificação para conjuntos de dados de informações de identificação pessoal (PII, na sigla em inglês) em grande escala usando os modelos de prevenção contra perda de dados do Cloud (Cloud DLP). Neste tutorial, também oferecemos orientações sobre como selecionar as transformações apropriadas para seu caso de uso.

Este documento faz parte de uma série:

Neste tutorial, presumimos que você tenha conhecimento básico de scripts de shell e que seja destinado a administradores de segurança empresarial.

Arquitetura de referência

Neste tutorial, demonstramos a seção de gerenciamento de configuração (modelo DLP e chave) ilustrada no diagrama a seguir.

Arquitetura de configuração de desidentificação.

Essa arquitetura consiste em uma configuração de desidentificação gerenciada que pode ser acessada apenas por um pequeno grupo de pessoas (por exemplo, administradores de segurança), para evitar a exposição de métodos de desidentificação e chaves de criptografia.

Objetivos

  • Projetar uma transformação do Cloud DLP para um conjunto de dados de amostra.
  • Criar modelos do Cloud DLP para armazenar a configuração de transformação.

Custos

Neste tutorial, usamos os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem ser qualificados para uma avaliação gratuita.

Ao concluir este tutorial, exclua os recursos criados para evitar o faturamento contínuo. Para mais informações, consulte Como fazer a limpeza.

Antes de começar

  1. Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. No Console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  3. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como confirmar se o faturamento está ativado para o projeto.

  4. No Console do Cloud, ative o Cloud Shell.

    Ativar o Cloud Shell

    Na parte inferior do Console do Cloud, uma sessão do Cloud Shell é iniciada e exibe um prompt de linha de comando. O Cloud Shell é um ambiente com o SDK do Cloud pré-instalado com a ferramenta de linha de comando gcloud e os valores já definidos para seu projeto atual. A inicialização da sessão pode levar alguns segundos.

  5. Execute todos os comandos deste tutorial no Cloud Shell.
  6. No Cloud Shell, ative as APIs Cloud DLP, Cloud Key Management Service, BigQuery, Cloud Storage, Dataflow e Cloud Build.
    gcloud services enable dlp.googleapis.com
    gcloud services enable cloudkms.googleapis.com
    gcloud services enable bigquery.googleapis.com
    gcloud services enable storage-component.googleapis.com
    gcloud services enable dataflow.googleapis.com
    gcloud services enable cloudbuild.googleapis.com
    

Como criar buckets do Cloud Storage

Nesta série, você precisa de dois buckets do Cloud Storage. O primeiro bucket armazena o conjunto de dados de amostra e o segundo armazena dados temporários para o pipeline automatizado usado na próxima parte desta série (Como executar um pipeline automatizado do Dataflow para desidentificar um conjunto de dados PII).

  1. No Cloud Shell, crie dois buckets do Cloud Storage (substitua REGION pela região do Dataflow) de sua escolha, por exemplo, us-central1:

    export REGION=REGION
    export PROJECT_ID=$(gcloud config get-value project)
    export DATA_STORAGE_BUCKET=${PROJECT_ID}-data-storage-bucket
    export DATAFLOW_TEMP_BUCKET=${PROJECT_ID}-dataflow-temp-bucket
    gsutil mb -c standard -l ${REGION} gs://${DATA_STORAGE_BUCKET}
    gsutil mb -c standard -l ${REGION} gs://${DATAFLOW_TEMP_BUCKET}
    

Como fazer o download dos arquivos de amostra

Faça o download dos arquivos de amostra para identificar as colunas necessárias para transformações de desidentificação.

  1. No Cloud Shell, faça o download do conjunto de dados e dos scripts de amostra usados neste tutorial para a máquina local:

    curl -X GET \
        -o "sample_data_scripts.tar.gz" \
        "http://storage.googleapis.com/dataflow-dlp-solution-sample-data/sample_data_scripts.tar.gz"
    
  2. Descompacte o conteúdo do arquivo:

    tar -zxvf sample_data_scripts.tar.gz
    
  3. Para validar a transferência, confirme se a saída corresponde à lista dos seguintes arquivos baixados:

    wc -l solution-test/CCRecords_1564602825.csv
    

    A saída é esta:

    100001 solution-test/CCRecords_1564602825.csv
    
  4. Para identificar quais colunas podem exigir a desidentificação do DLP, examine o registro do cabeçalho no arquivo CSV:

    head -1 solution-test/CCRecords_1564602825.csv
    

    A resposta é:

    ID,Card Type Code,Card Type Full Name,Issuing Bank,Card Number,Card Holder's Name,Issue Date,Expiry Date,Billing Date,Card PIN,Credit Limit,Age,SSN,JobTitle,Additional Details
    

    A primeira linha de cada arquivo CSV define o esquema dos dados e os nomes das colunas. O conjunto de dados extraído contém identificadores diretos (SSN e Card Holder's Name) e quase identificadores (Age e JobTitle).

O processo para determinar as transformações necessárias varia de acordo com seu caso de uso. Para o conjunto de dados de amostra usado neste tutorial, uma lista de transformações está resumida na tabela a seguir.

Nome da coluna InfoType (personalizado ou integrado) Tipo de transformação do Cloud DLP Descrição da transformação
Card PIN N/A Criptografia usando hash criptográfico A criptografia de hash criptográfico substitui os dados originais por um valor codificado em base64 que não pode ser revertido.
Card Number N/A Como criptografar usando criptografia determinística (DE, na sigla em inglês) A DE substitui os dados originais por um valor criptografado codificado em base64 e não preserva o conjunto de caracteres ou o comprimento original.
Card Holder's Name N/A Como criptografar usando criptografia determinística (DE, na sigla em inglês) A DE substitui os dados originais por um valor criptografado codificado em base64 e não preserva o conjunto de caracteres ou o comprimento original.
SSN (Social Security Number) N/A Caractere de mascaramento O mascaramento é uma técnica não criptográfica que pode ser usada para mascarar dados originais parciais ou completos com um caractere especificado.
Age N/A Agrupamento por classes com um valor geral A transformação de agrupamento por classes ajuda a substituir um valor identificável por um valor geral.
Job Title N/A Agrupamento por classes com um valor geral A transformação de agrupamento por classes ajuda a substituir um valor identificável por um valor geral.
Additional Details Integrado: IBAN_CODE, EMAIL_ADDRESS, PHONE_NUMBER
Personalizado: ONLINE_USER_ID
Substituição por um token A transformação de substituição substitui os dados originais por um valor arbitrário.

Como criar um conjunto de dados do BigQuery

  1. Crie um conjunto de dados no BigQuery onde o pipeline do Cloud DLP possa armazenar os dados desidentificados (substitua LOCATION pelo local do BigQuery de sua preferência, por exemplo, US):

    bq mk --location=LOCATION \
        --description="De-Identified PII Dataset" \
        deid_dataset
    

Nestas etapas, presumimos que os dados confidenciais são armazenados no Cloud Storage em formato delimitado por colunas, normalmente CSV. O pipeline usado neste tutorial cria automaticamente uma tabela do BigQuery com base no conteúdo do registro de cabeçalho CSV encontrado nos arquivos de dados. Se esse registro de cabeçalho for removido dos arquivos CSV, você corre o risco de expor dados de PII no BigQuery.

Como criar uma chave de criptografia de chaves (KEK, na sigla em inglês)

Uma chave de criptografia de token (TEK, na sigla em inglês) é protegida (encapsulada) por outra chave (chave de criptografia de chaves) do Cloud Key Management Service (Cloud KMS):

  1. No Cloud Shell, crie uma TEK localmente. Para este tutorial, você gera uma chave de criptografia base-64 aleatória de 32 caracteres:

    export TEK=$(openssl rand -base64 32); echo ${TEK}
    

    A saída é uma chave aleatória gerada no seguinte formato:

    MpyFxEQKYKscEJVOiKMuEPdwqdffk4vTF+qwGwrp7Ps=
    

    O tamanho efetivo da chave em base-2 é (64)^32 =(2^6)^32=2^192 ou um vetor de inicialização (IV, na sigla em inglês) AES de tamanho de 192 bits. Ela será usada posteriormente em um script.

  2. Exporte a chave, o keyring e o arquivo KEK como variáveis:

    export KEY_RING_NAME=my-kms-key-ring
    export KEY_NAME=my-kms-key
    export KEK_FILE_NAME=kek.json
    
  3. Ative os papéis de administrador e criptografador de chaves do Cloud KMS para a conta de serviço do Cloud Build:

    export PROJECT_NUMBER=$(gcloud projects list \
        --filter=${PROJECT_ID} --format="value(PROJECT_NUMBER)")
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
        --role roles/cloudkms.cryptoKeyEncrypter
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
        --role roles/cloudkms.admin
    
  4. Clone o seguinte repositório do GitHub e acesse a pasta raiz do projeto:

    git clone https://github.com/GoogleCloudPlatform/dlp-dataflow-deidentification.git
    cd dlp-dataflow-deidentification
    
  5. Crie uma KEK:

    gcloud builds submit . \
        --config dlp-demo-part-1-crypto-key.yaml \
        --substitutions \
        _GCS_BUCKET_NAME=gs://${DATA_STORAGE_BUCKET},_KEY_RING_NAME=${KEY_RING_NAME},_KEY_NAME=${KEY_NAME},_TEK=${TEK},_KEK=${KEK_FILE_NAME},_API_KEY=$(gcloud auth print-access-token)
    
  6. Valide a criação da KEK:

    gsutil cat gs://${DATA_STORAGE_BUCKET}/${KEK_FILE_NAME}
    

    A saída será assim:

    {
      "name": "kms-key-resource-path",
      "ciphertext": "kms-wrapped-key",
      "ciphertextCrc32c": "checksum"
    }
    

    Observações sobre a saída:

    • kms-key-resource-path: o caminho do recurso da KEK no formato: projects/${PROJECT_ID}/locations/global/keyRings/${KEY_RING_NAME}/cryptoKeys/${KEY_NAME}/cryptoKeyVersions/1.

    • kms-wrapped-key: valor codificado em Base64 do TEK encapsulado por Cloud KMS.

    • checksum: uma soma de verificação CRC32C do texto criptografado.

Como criar os modelos do Cloud DLP

Até aqui, você investigou o conjunto de dados de amostra e determinou quais transformações do Cloud DLP são necessárias. Para as colunas que exigem transformações criptográficas, você também criou uma chave de criptografia de chaves (KEK). A próxima etapa é executar um script do Cloud Build para criar modelos do Cloud DLP com base na transformação necessária e na KEK.

Como criar uma conta de serviço para o Cloud DLP

  1. No Cloud Shell, crie uma conta de serviço:

    export SERVICE_ACCOUNT_NAME=my-service-account
    gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \
        --display-name "DLP Demo Service Account"
    
  2. Crie um arquivo de chave de API JSON chamado service-account-key.json para a conta de serviço:

    gcloud iam service-accounts keys create \
        --iam-account ${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \
        service-account-key.json
    
  3. Atribua os papéis project editor e storage admin à conta de serviço:

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \
        --role roles/editor
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \
        --role roles/storage.admin
    
  4. Ative a conta de serviço:

    gcloud auth activate-service-account --key-file service-account-key.json
    

Como criar os modelos

  1. No Cloud Shell, execute o script do Cloud Build para criar os modelos:

    gcloud builds submit . \
        --config dlp-demo-part-2-dlp-template.yaml \
        --substitutions \
        _KEK_CONFIG_FILE=gs://${DATA_STORAGE_BUCKET}/${KEK_FILE_NAME},_GCS_BUCKET_NAME=gs://${DATA_STORAGE_BUCKET},_API_KEY=$(gcloud auth print-access-token)
    
  2. Valide a criação do modelo de desidentificação:

    gsutil cp gs://${DATA_STORAGE_BUCKET}/deid-template.json .
    cat deid-template.json
    

    A saída será assim:

    {
      "name": "projects/<project_id>/deidentifyTemplates/<template_id>",
      "displayName": "Config to DeIdentify Sample Dataset",
      "description": "De-identifies Card Number, Card PIN, Card Holder's Name, SSN, Age, Job Title, Additional Details and Online UserId Fields",
      "createTime": "2019-12-01T19:21:07.306279Z",
      "updateTime": "2019-12-01T19:21:07.306279Z",
      "deidentifyConfig": {
        "recordTransformations": {
          "fieldTransformations": [
            {
              "fields": [
                {
                  "name": "Card PIN"
                }
              ],
              "primitiveTransformation": {
                "cryptoHashConfig": {
                  "cryptoKey": {
                    "kmsWrapped": {
                      "wrappedKey": "<var>kms-wrapped-key</var>",
                      "cryptoKeyName": "<var>kms-key-resource-name</var>"
                    }
                  }
                }
              }
            },
            {
              "fields": [
                {
                  "name": "SSN"
                }
              ],
              "primitiveTransformation": {
                "characterMaskConfig": {
                  "maskingCharacter": "*",
                  "numberToMask": 5,
                  "charactersToIgnore": [
                    {
                      "charactersToSkip": "-"
                    }
                  ]
                }
              }
            },
            {
              "fields": [
                {
                  "name": "Age"
                }
              ],
              "primitiveTransformation": {
                "bucketingConfig": {
                  "buckets": [
                    {
                      "min": {
                        "integerValue": "18"
                      },
                      "max": {
                        "integerValue": "30"
                      },
                      "replacementValue": {
                        "stringValue": "20"
                      }
                    },
                    {
                      "min": {
                        "integerValue": "30"
                      },
                      "max": {
                        "integerValue": "40"
                      },
                      "replacementValue": {
                        "stringValue": "30"
                      }
                    },
                    {
                      "min": {
                        "integerValue": "40"
                      },
                      "max": {
                        "integerValue": "50"
                      },
                      "replacementValue": {
                        "stringValue": "40"
                      }
                    },
                    {
                      "min": {
                        "integerValue": "50"
                      },
                      "max": {
                        "integerValue": "60"
                      },
                      "replacementValue": {
                        "stringValue": "50"
                      }
                    },
                    {
                      "min": {
                        "integerValue": "60"
                      },
                      "max": {
                        "integerValue": "99"
                      },
                      "replacementValue": {
                        "stringValue": "60"
                      }
                    }
                  ]
                }
              }
            },
            {
              "fields": [
                {
                  "name": "JobTitle"
                }
              ],
              "primitiveTransformation": {
                "bucketingConfig": {
                  "buckets": [
                    {
                      "min": {
                        "stringValue": "CIO"
                      },
                      "max": {
                        "stringValue": "CIOz"
                      },
                      "replacementValue": {
                        "stringValue": "Executive"
                      }
                    },
                    {
                      "min": {
                        "stringValue": "CEO"
                      },
                      "max": {
                        "stringValue": "CEOz"
                      },
                      "replacementValue": {
                        "stringValue": "Executive"
                      }
                    },
                    {
                      "min": {
                        "stringValue": "Vice President"
                      },
                      "max": {
                        "stringValue": "Vice Presidentz"
                      },
                      "replacementValue": {
                        "stringValue": "Executive"
                      }
                    },
                    {
                      "min": {
                        "stringValue": "Software Engineer"
                      },
                      "max": {
                        "stringValue": "Software Engineerz"
                      },
                      "replacementValue": {
                        "stringValue": "Engineer"
                      }
                    },
                    {
                      "min": {
                        "stringValue": "Product Manager"
                      },
                      "max": {
                        "stringValue": "Product Managerz"
                      },
                      "replacementValue": {
                        "stringValue": "Manager"
                      }
                    }
                  ]
                }
              }
            },
            {
              "fields": [
                {
                  "name": "Additional Details"
                }
              ],
              "infoTypeTransformations": {
                "transformations": [
                  {
                    "infoTypes": [
                      {
                        "name": "EMAIL_ADDRESS"
                      },
                      {
                        "name": "PHONE_NUMBER"
                      },
                      {
                        "name": "IBAN_CODE"
                      },
                      {
                        "name": "ONLINE_USER_ID"
                      }
                    ],
                    "primitiveTransformation": {
                      "replaceWithInfoTypeConfig": {}
                    }
                  }
                ]
              }
            },
            {
              "fields": [
                {
                  "name": "Card Holder's Name"
                },
                {
                  "name": "Card Number"
                }
              ],
              "primitiveTransformation": {
                "cryptoDeterministicConfig": {
                  "cryptoKey": {
                    "kmsWrapped": {
                      "wrappedKey": "<var>kms-wrapped-key</var>",
                      "cryptoKeyName": "<var>kms-key-resource-name</var>"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  3. Valide a criação do modelo de inspeção:

    gsutil cp gs://${DATA_STORAGE_BUCKET}/inspect-template.json .
    cat inspect-template.json
    

    A saída será assim:

    {
      "name": "projects/<project_id>/inspectTemplates/<template_id>",
      "displayName": "Config to Inspect Additional Details Column",
      "description": "Inspect template for built in info types EMAIL_ADDRESS, PHONE_NUMBER, IBAN_CODE and custom Info type ONLINE_USER_ID",
      "createTime": "2019-12-01T19:21:08.063415Z",
      "updateTime": "2019-12-01T19:21:08.063415Z",
      "inspectConfig": {
        "infoTypes": [
          {
            "name": "IBAN_CODE"
          },
          {
            "name": "EMAIL_ADDRESS"
          },
          {
            "name": "PHONE_NUMBER"
          }
        ],
        "minLikelihood": "LIKELY",
        "limits": {},
        "customInfoTypes": [
          {
            "infoType": {
              "name": "ONLINE_USER_ID"
            },
            "regex": {
              "pattern": "\\b:\\d{16}"
            }
          }
        ]
      }
    }
  4. Verifique se o modelo de reidentificação foi criado com sucesso:

    gsutil cp gs://${DATA_STORAGE_BUCKET}/reid-template.json .
    cat reid-template.json
    

    A saída será assim:

    {
      "name": "projects/<project_id>/deidentifyTemplates/<template_id>",
      "displayName": "Config to ReIdentify Sample Dataset",
      "description": "Used to re-identify Card Number and Card Holder's Name",
      "createTime": "2019-12-01T19:21:07.306279Z",
      "updateTime": "2019-12-01T19:21:07.306279Z",
      "deidentifyConfig": {
        "recordTransformations": {
          "fieldTransformations": [
            {
              "fields": [
                {
                  "name": "Card_Holders_Name"
                },
                {
                  "name": "Card_Number"
                }
              ],
              "primitiveTransformation": {
                "cryptoDeterministicConfig": {
                  "cryptoKey": {
                    "kmsWrapped": {
                      "wrappedKey": "<var>kms-wrapped-key</var>",
                      "cryptoKeyName": "<var>kms-key-resource-name</var>"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }

    O modelo de reidentificação é semelhante ao modelo de desidentificação, exceto pelo fato de que ele contém apenas transformações reversíveis, neste caso, aquelas para os campos Card Holder's Name e Card Number.

  5. Exporte os nomes dos modelos do Cloud DLP:

    export DEID_TEMPLATE_NAME=$(jq -r '.name' deid-template.json)
    export INSPECT_TEMPLATE_NAME=$(jq -r '.name' inspect-template.json)
    export REID_TEMPLATE_NAME=$(jq -r '.name' reid-template.json)
    
  6. Valide a existência das seguintes variáveis:

    echo ${DATA_STORAGE_BUCKET}
    echo ${DATAFLOW_TEMP_BUCKET}
    echo ${DEID_TEMPLATE_NAME}
    echo ${INSPECT_TEMPLATE_NAME}
    echo ${REID_TEMPLATE_NAME}
    

Você concluiu este tutorial. No próximo tutorial, você acionará um pipeline automatizado do Dataflow para inspecionar e desidentificar o conjunto de dados de amostra e armazená-lo no BigQuery.

Como fazer a limpeza

Se você não pretende continuar com os tutoriais da série, a maneira mais fácil de evitar cobranças é excluindo o projeto do Cloud criado para o tutorial. A outra opção é excluir os recursos individuais.

Exclua o projeto

  1. No Console do Cloud, acesse a página Gerenciar recursos:

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

A seguir