Créer des modèles de transformation Cloud DLP pour anonymiser les ensembles de données contenant des informations personnelles

Ce tutoriel explique comment créer et gérer des transformations d'anonymisation pour des ensembles de données à grande échelle contenant des informations personnelles à l'aide de modèles Cloud DLP (Cloud Data Loss Prevention). Ce tutoriel donne également des indications pour choisir les transformations qui conviennent à votre cas d'utilisation.

Ce document fait partie d'une série :

Ce tutoriel est destiné aux administrateurs de sécurité informatique et suppose que le lecteur maîtrise les notions élémentaires du langage de script shell.

Architecture de référence

Ce tutoriel explique comment gérer la configuration (modèle et clé DLP) représentée graphiquement dans la zone inférieure gauche du diagramme ci-dessous.

Architecture d'une configuration d'anonymisation.

Cette architecture consiste en une configuration d'anonymisation gérée, qui n'est accessible que par un petit groupe d'utilisateurs (des administrateurs de sécurité informatique, par exemple) afin d'éviter de divulguer les méthodes d'anonymisation et les clés de chiffrement.

Objectifs

  • Créer une transformation Cloud DLP pour un ensemble de données d'exemple
  • Créer des modèles Cloud DLP pour stocker la configuration de la transformation

Coûts

Ce tutoriel utilise les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Une fois que vous avez terminé ce tutoriel, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Consultez la page Effectuer un nettoyage pour en savoir plus.

Avant de commencer

  1. Connectez-vous à votre compte Google.

    Si vous n'en possédez pas déjà un, vous devez en créer un.

  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder à la page de sélection du projet

  3. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  4. Dans Cloud Console, activez Cloud Shell.

    Activer Cloud Shell

    En bas de la fenêtre de Cloud Console, une session Cloud Shell démarre et affiche une invite de ligne de commande. Cloud Shell est un environnement shell dans lequel le SDK Cloud est déjà installé (y compris l'outil de ligne de commande gcloud), et dans lequel des valeurs sont déjà définies pour votre projet actuel. L'initialisation de la session peut prendre quelques secondes.

  5. Vous exécuterez toutes les commandes de ce tutoriel depuis Cloud Shell.
  6. Dans Cloud Shell, activez les API Cloud DLP, Cloud Key Management Service, BigQuery, Cloud Storage, Dataflow et 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
    

Créer des buckets Cloud Storage

Pour cette série de tutoriels, vous avez besoin de deux buckets Cloud Storage. Le premier bucket stocke l'ensemble de données d'exemple tandis que le second stocke les données temporaires du pipeline automatisé décrit dans la prochaine partie de cette série : Exécuter un pipeline Dataflow automatisé pour anonymiser un ensemble de données contenant des informations personnelles.

  1. Dans Cloud Shell, créez deux buckets Cloud Storage (remplacez REGION par la région Dataflow de votre choix, par exemple 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}
    

Télécharger les fichiers d'exemple

Le but de cette opération est d'identifier les colonnes sur lesquelles les transformations d'anonymisation seront appliquées.

  1. Dans Cloud Shell, téléchargez sur votre ordinateur local l'ensemble de données d'exemple et les scripts utilisés dans ce tutoriel :

    curl -X GET \
        -o "sample_data_scripts.tar.gz" \
        "http://storage.googleapis.com/dataflow-dlp-solution-sample-data/sample_data_scripts.tar.gz"
    
  2. Décompressez le fichier et extrayez le contenu de l'archive :

    tar -zxvf sample_data_scripts.tar.gz
    
  3. Pour vérifier que le transfert s'est bien passé, tapez la commande suivante et comparez son résultat :

    wc -l solution-test/CCRecords_1564602825.csv
    

    Le résultat est le suivant :

    100001 solution-test/CCRecords_1564602825.csv
    
  4. Pour identifier quelles sont les colonnes devant faire l'objet d'une anonymisation DLP, examinez l'enregistrement d'en-tête du fichier CSV à l'aide de la commande suivante :

    head -1 solution-test/CCRecords_1564602825.csv
    

    Le résultat est :

    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
    

    La première ligne de chaque fichier CSV définit le schéma de données et les noms des colonnes. L'ensemble de données extrait contient des identifiants directs (SSN et Card Holder's Name) et des quasi-identifiants (Age et JobTitle).

Le processus permettant de déterminer les transformations requises dépend de votre cas d'utilisation. Pour l'ensemble de données d'exemple utilisé dans ce tutoriel, la liste des transformations est résumée par le tableau suivant :

Nom de la colonne InfoType (intégré ou personnalisé) Type de transformation Cloud DLP Description de la transformation
Card PIN ND Hachage de chiffrement La transformation par hachage de chiffrement remplace les données d'origine par une valeur codée en base64. Elle est irréversible.
Card Number ND Chiffrement déterministe La transformation par chiffrement déterministe remplace les données d'origine par une valeur chiffrée codée en base64. Le jeu de caractères et la taille des données d'origine ne sont pas conservés.
Card Holder's Name ND Chiffrement déterministe La transformation par chiffrement déterministe remplace les données d'origine par une valeur chiffrée codée en base64. Le jeu de caractères et la taille des données d'origine ne sont pas conservés.
SSN (Social Security Number) ND Caractère de masquage Le masquage est une technique non cryptographique utilisée pour masquer partiellement ou totalement les données d'origine à l'aide d'un caractère donné.
Age ND Généralisation par binning La transformation de binning remplace une valeur distinctive par une valeur plus générale.
Job Title ND Généralisation par binning La transformation de binning remplace une valeur distinctive par une valeur plus générale.
Additional Details Intégré : IBAN_CODE, EMAIL_ADDRESS, PHONE_NUMBER
Personnalisé : ONLINE_USER_ID
Remplacement par un jeton La transformation de remplacement remplace les données d'origine par une valeur arbitraire.

Créer un ensemble de données BigQuery

  1. Créez dans BigQuery l'ensemble de données où le pipeline Cloud DLP stockera les données anonymisées (remplacez LOCATION par l'emplacement BigQuery de votre choix, par exemple US) :

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

Dans ce tutoriel, nous partons du principe que les données sensibles sont stockées dans Cloud Storage sous forme tabulaire, généralement au format CSV. Le pipeline crée automatiquement une table BigQuery en fonction du contenu de l'enregistrement d'en-tête des fichiers CSV. Si jamais cet enregistrement d'en-tête est supprimé des fichiers CSV, vous risquez d'exposer par erreur des informations personnelles dans BigQuery.

Créer une clé de chiffrement de clé (KEK)

La clé de chiffrement de jeton (TEK) créée est protégée (encapsulée) à l'aide d'une autre clé (appelée clé de chiffrement de clé) provenant de Cloud Key Management Service (Cloud KMS) :

  1. Créez la clé TEK en local dans Cloud Shell. Dans le cadre de ce tutoriel, il s'agit d'une clé base64 de 32 caractères, que vous générez à l'aide de la commande suivante :

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

    Le résultat est une clé aléatoire ayant la forme suivante :

    MpyFxEQKYKscEJVOiKMuEPdwqdffk4vTF+qwGwrp7Ps=
    

    La taille effective de la clé en base 2 est de (64)^32 = (2^6)^32 = 2^192, soit un vecteur d'initialisation (IV) AES de 192 bits. Cette clé est utilisée ultérieurement dans le script.

  2. Exportez la clé, le trousseau de clés et le fichier KEK en tant que variables à l'aide des commandes suivantes :

    export KEY_RING_NAME=my-kms-key-ring
    export KEY_NAME=my-kms-key
    export KEK_FILE_NAME=kek.json
    
  3. Attribuez les rôles d'administrateur et de chiffreur de clé Cloud KMS au compte de service Cloud Build à l'aide des commandes suivantes :

    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. Clonez le dépôt GitHub suivant et accédez au dossier racine du projet :

    git clone https://github.com/GoogleCloudPlatform/dlp-dataflow-deidentification.git
    cd dlp-dataflow-deidentification
    
  5. Créez la clé KEK à l'aide de la commande suivante :

    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. À l'aide de la commande suivante, vérifiez que la clé KEK a bien été créée :

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

    La sortie ressemble à ceci :

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

    Remarques concernant la sortie :

    • kms-key-resource-path : chemin d'accès à la ressource KEK au format projects/${PROJECT_ID}/locations/global/keyRings/${KEY_RING_NAME}/cryptoKeys/${KEY_NAME}/cryptoKeyVersions/1

    • kms-wrapped-key : valeur de la clé TEK encapsulée par Cloud KMS encodée en base64

    • checksum : somme de contrôle CRC32C du texte chiffré

Créer les modèles Cloud DLP

À ce stade, vous avez étudié l'ensemble de données d'exemple et déterminé quelles sont les transformations Cloud DLP requises. Vous avez également créé une clé de chiffrement de clé (KEK) permettant d'effectuer les transformations cryptographiques sur les colonnes qui le nécessitent. L'étape suivante consiste à exécuter un script Cloud Build pour créer des modèles Cloud DLP basés sur la transformation requise et sur la clé KEK.

Créer un compte de service pour Cloud DLP

  1. Dans Cloud Shell, créez un compte de service à l'aide des commandes suivantes :

    export SERVICE_ACCOUNT_NAME=my-service-account
    gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \
        --display-name "DLP Demo Service Account"
    
  2. Créez la clé de compte de service et stockez-la dans un fichier JSON appelé service-account-key.json :

    gcloud iam service-accounts keys create \
        --iam-account ${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \
        service-account-key.json
    
  3. Attribuez les rôles project editor et storage admin au compte de service à l'aide des commandes suivantes :

    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. Enfin, activez le compte de service :

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

Créer les modèles

  1. Dans Cloud Shell, exécutez le script Cloud Build suivant afin de créer les modèles :

    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. Vérifiez à l'aide des commandes suivantes que le modèle d'anonymisation a bien été créé :

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

    La sortie ressemble à ceci :

    {
      "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. Vérifiez à l'aide des commandes suivantes que le modèle d'inspection a bien été créé :

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

    La sortie ressemble à ceci :

    {
      "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. Vérifiez que le modèle de restauration de l'identification a bien été créé :

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

    La sortie ressemble à ceci :

    {
      "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>"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }

    Le modèle de restauration de l'identification est semblable au modèle d'anonymisation, mais il ne contient que des transformations réversibles, dans le cas présent, celles des champs Card Holder's Name et Card Number.

  5. Exportez les noms des modèles Cloud DLP à l'aide des commandes suivantes :

    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. Enfin, vérifiez que les variables suivantes existent :

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

Vous avez terminé ce tutoriel. Dans le tutoriel suivant, vous allez déclencher un pipeline Dataflow automatisé pour inspecter l'ensemble de données d'exemple et l'anonymiser. Les données anonymisées seront stockées dans BigQuery.

Effectuer un nettoyage

Si vous n'avez pas l'intention de continuer à suivre les tutoriels de cette série, le moyen le plus simple d'éviter la facturation consiste à supprimer le projet Cloud que vous avez créé pour ce tutoriel. Vous pouvez également supprimer les différentes ressources.

Supprimer le projet

  1. Dans Cloud Console, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Étape suivante