Utiliser des clés de chiffrement gérées par le client (CMEK)

Cette page explique comment effectuer des tâches liées aux clés de chiffrement gérées par le client (CMEK) pour Firestore. Pour plus d'informations sur la CMEK en général, y compris quand et pourquoi l'activer, consultez la documentation Cloud KMS.

Préparer vos clés CMEK

Avant de pouvoir créer une base de données Firestore protégée par CMEK, vous devez procéder comme suit:

  1. Créez (ou récupérez) un agent de service Firestore.
  2. Créez une clé CMEK.
  3. Configurez les paramètres IAM pour cette clé.

Procédez comme suit pour chaque projet qui contiendra des bases de données Firestore protégées par des CMEK. Si vous créez ultérieurement une clé CMEK, vous devez configurer les paramètres IAM de cette clé.

Créer un agent de service Firestore

Avant de créer une clé CMEK, vous devez disposer d'un agent de service Firestore, qui est un type de compte de service géré par Google permettant à Firestore d'accéder à la clé.

Exécutez la commande services Identity create pour créer l'agent de service permettant à Firestore d'accéder à la clé CMEK en votre nom. Cette commande crée le compte de service s'il n'existe pas déjà, puis l'affiche.

gcloud beta services identity create \
    --service=firestore.googleapis.com \
    --project FIRESTORE_PROJECT

Remplacez FIRESTORE_PROJECT par le projet que vous prévoyez d'utiliser pour vos bases de données Firestore.

La commande affiche l'ID de l'agent de service, qui est formaté comme une adresse e-mail. Enregistrez la chaîne de l'e-mail de sortie, car vous en aurez besoin à une étape ultérieure.

Service identity created:
service-xxx@gcp-sa-firestore.iam.gserviceaccount.com

Créer une clé

Vous pouvez utiliser une clé créée directement dans Cloud KMS ou une clé gérée en externe que vous rendez disponible avec Cloud External Key Manager.

L'emplacement de la clé Cloud KMS doit être identique à celui de la base de données Firestore avec laquelle elle sera utilisée.

  • Pour les emplacements de base de données régionaux, utilisez le même nom d'emplacement pour le trousseau de clés, la clé et la base de données, car les noms d'emplacement sont mappés un à un.

    Par exemple, si vous souhaitez créer une base de données protégée par une clé CMEK dans us-west1, créez un trousseau de clés et une clé dans us-west1.

  • Pour les emplacements de bases de données multirégionales, utilisez le nom d'emplacement de l'emplacement multirégional KMS:

    • Utilisez l'emplacement multirégional Cloud KMS us pour l'emplacement multirégional nam5 de Firestore.
    • Utilisez l'emplacement multirégional Cloud KMS europe pour l'emplacement multirégional eur3 de Firestore.

Dans le projet Google Cloud dans lequel vous souhaitez gérer vos clés, procédez comme suit:

  1. Activez l'API Cloud KMS.

  2. Créez un trousseau de clés et une clé à l'aide de l'une des options suivantes :

Configurer les paramètres IAM de la clé

Console

Pour attribuer un rôle Cloud KMS à votre agent de service, procédez comme suit : Vous pouvez également accorder une autorisation au niveau de la clé ou du trousseau si vous souhaitez bénéficier d'un niveau de précision inférieur.

  1. Dans la console Google Cloud, accédez à la page IAM.

    Accédez à la page IAM.

  2. Cliquez sur Ajouter.

  3. Saisissez l'ID au format e-mail de votre agent de service Firestore.

  4. Sélectionnez le rôle Chiffreur/Déchiffreur de clés cryptographiques Cloud KMS.

  5. Cliquez sur Enregistrer.

gcloud

  1. Attribuez le rôle cloudkms.cryptoKeyEncrypterDecrypter à votre agent de service :

    gcloud kms keys add-iam-policy-binding KMS_KEY \
        --keyring KMS_KEYRING\
        --location KMS_LOCATION \
        --member serviceAccount:SERVICE_AGENT_EMAIL \
        --role roles/cloudkms.cryptoKeyEncrypterDecrypter \
        --project KMS_PROJECT
    

    Indiquez les éléments suivants :

    • KMS_KEY : nom attribué à la clé.
    • KMS_KEYRING : trousseau de clés KMS contenant la clé.
    • KMS_LOCATION : région contenant le trousseau de clés.
    • SERVICE_AGENT_EMAIL : identifiant au format adresse e-mail de l'agent de service auquel vous accordez l'accès.
    • KMS_PROJECT : projet contenant la clé.

    Le terminal doit afficher une réponse semblable à celle-ci:

    Updated IAM policy for key KMS_KEY.
    bindings:
    - members:
      - serviceAccount:
        service-{project-number}@gcp-sa-firestore.iam.gserviceaccount.com
    role: roles/cloudkms.cryptoKeyEncrypterDecrypter
    

Créer une base de données compatible avec les CMEK

Une fois vos clés CMEK créées et configurées, vous pouvez créer une base de données protégée par des CMEK. Les bases de données Firestore existantes protégées par le chiffrement par défaut de Google ne peuvent pas être converties pour utiliser des clés CMEK. Vous ne pouvez choisir qu'un type de chiffrement et une clé au moment de la création.

gcloud

gcloud alpha firestore databases create --location=FIRESTORE_DATABASE_LOCATION \
      --database=DATABASE_ID \
      --kms-key-name=KMS_KEY_NAME \
      --project=FIRESTORE_PROJECT

Indiquez les éléments suivants :

  • FIRESTORE_DATABASE_LOCATION: emplacement Firestore de la base de données
  • DATABASE_ID: ID de la base de données
  • KMS_KEY_NAME: nom que vous avez attribué à la clé. Utilisez le nom complet de la ressource pour la clé au format suivant:

    projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID

  • FIRESTORE_PROJECT: projet à utiliser pour votre base de données Firestore

API REST

Requête HTTP :

POST https://firestore.googleapis.com/v1/projects/{FIRESOTRE_PROJECT}/databases

Dans le corps de la requête, configurez la clé CMEK dans le champ cmek_config.kms_key_name.

Définissez-le sur l'ID de ressource complet d'une clé Cloud KMS. Seule une clé située au même emplacement que cette base de données est autorisée.

Cette valeur doit correspondre à l'ID de ressource de la clé Cloud KMS au format projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}.

Pour en savoir plus sur les autres champs, consultez la page database create.

Exemple de requête :

curl -X POST 'https://firestore.googleapis.com/v1/projects/FIRESTORE_PROJECT/databases?databaseId={DATABASE_ID}' \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-type: application/json" \
-d '{
  "type":"FIRESTORE_NATIVE",
  "locationId":"{FIRESTORE_DATABASE_LOCATION}",
  "cmekConfig": {
    "kmsKeyName":"projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID"
  }
}'

Terraform

Pour créer une base de données compatible avec les CMEK, utilisez la ressource google_firestore_database. Pour en savoir plus et obtenir des exemples, consultez google_firestore_database.

resource "google_firestore_database" "database" {
  project     = "FIRESTORE_PROJECT"
  name        = "DATABASE_ID"
  location_id = "FIRESTORE_DATABASE_LOCATION"
  type        = "DATABASE_TYPE"

  cmek_config {
    kms_key_name = "KMS_KEY_NAME"
  }

}

Indiquez les éléments suivants :

  • FIRESTORE_PROJECT: projet à utiliser pour votre base de données Firestore
  • DATABASE_ID: ID de la base de données
  • FIRESTORE_DATABASE_LOCATION: emplacement Firestore de la base de données
  • DATABASE_TYPE: FIRESTORE_NATIVE pour le mode natif ou DATASTORE_MODE pour le mode Datastore.
  • KMS_KEY_NAME: nom que vous avez attribué à la clé. Utilisez le nom complet de la ressource pour la clé au format suivant:

    projects/KMS_PROJECT/locations/KMS_LOCATION/keyRings/KMS_KEYRING_ID/cryptoKeys/KMS_KEY_ID

Accéder à une base de données protégée par une clé CMEK

Toutes les opérations de lecture, d'écriture et de requête envoyées à une base de données protégée par une clé CMEK doivent fonctionner de la même manière qu'avec une base de données chiffrée par défaut de Google. Par exemple, vous n'avez pas besoin de fournir une clé pour chaque requête.

Afficher la clé utilisée

gcloud

Vous pouvez utiliser la commande gcloud CLI databases describe pour confirmer la configuration CMEK de la base de données:

gcloud firestore databases describe --database=DATABASE_ID --project=FIRESTORE_PROJECT

Des informations CMEK doivent s'afficher dans le champ cmekConfig de la réponse, comme suit:

cmekConfig:
    activeKeyVersion:
    - projects/PROJECT_ID/locations/us/keyRings/KEYRING_NAME/cryptoKeys/KEY_NAME/cryptoKeyVersions/1
    kmsKeyName: projects/PROJECT_ID/locations/us/keyRings/KEYRING_NAME/cryptoKeys/KEY_NAME
  locationId: nam5
  name: projects/PROJECT_ID/databases/DATABASE_ID

La réponse inclut les informations suivantes :

  • kmsKeyName: nom de ressource complet de la clé utilisée pour chiffrer votre base de données protégée par une clé CMEK.
  • activeKeyVersion: liste de toutes les versions de clé actuellement utilisées par la base de données protégée par des clés CMEK. Lors de la rotation des clés, il peut y avoir plusieurs versions de clé actives.

API REST

Requête HTTP :

GET https://firestore.googleapis.com/v1/{name=projects/FIRESTORE_PROJECT/databases/DATABASE_ID}

Dans le corps de la requête, configurez la clé CMEK dans le champ cmek_config.kms_key_name. Définissez-le sur l'ID de ressource complet d'une clé Cloud KMS. Seule une clé située au même emplacement que cette base de données est autorisée.

Cette valeur doit correspondre à l'ID de ressource de la clé Cloud KMS au format projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}.

Pour en savoir plus sur les autres champs, consultez la page database create.

Exemple de requête et de réponse:

curl 'https://firestore.googleapis.com/v1/projects/FIRESTORE_PROJECT/databases/{DATABASE_ID}' \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-type: application/json"

—----------------------------------------- Response —--------------------------------------------
{
  "name": "projects/FIRESTORE_PROJECT/databases/{DATABASE_ID}",
  "locationId": "{FIRESTORE_DATABASE_LOCATION}",
  "type": "FIRESTORE_NATIVE",
  "cmekConfig": {
    "kmsKeyName": "projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}",
    "activeKeyVersion": [
      "projects/{KMS_PROJECT}/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}/cryptoKeyVersions/1"
    ]
  },
  ……
}

Désactiver une clé

Pour désactiver une clé associée à une base de données, procédez comme suit:

  1. Afficher les versions de clé utilisées pour une base de données
  2. Désactiver ces versions de clé
  3. Attendez que la modification soit prise en compte et vérifiez si les données ne sont plus accessibles. En principe, les modifications prennent effet en quelques minutes, mais un délai de trois heures est parfois nécessaire.

Lorsqu'une clé utilisée par une base de données est désactivée, attendez-vous à recevoir une exception FAILED_PRECONDITION avec des détails supplémentaires dans le message d'erreur, par exemple:

{
  "error": {
    "code": 400,
    "message": "The customer-managed encryption key required by the requested resource is not accessible. Error reason:  generic::permission_denied: Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied on resource 'projects/FIRESTORE_PROJECT/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}' (or it may not exist).",
    "status": "FAILED_PRECONDITION",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.DebugInfo",
        "detail": "The customer-managed encryption key required by the requested resource is not accessible. Error reason:  generic::permission_denied: Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied on resource 'projects/FIRESTORE_PROJECT/locations/{KMS_LOCATION}/keyRings/{KMS_KEYRING_ID}/cryptoKeys/{KMS_KEY_ID}' (or it may not exist)"
      }
    ]
  }
}

Activer une clé

Pour réactiver une clé associée à une base de données, procédez comme suit:

  1. Afficher les versions de clé utilisées pour une base de données
  2. Activez ces versions de clé.
  3. Attendez que la modification soit prise en compte et vérifiez si les données ne sont plus accessibles. En principe, les modifications prennent effet en quelques minutes, mais un délai de trois heures est parfois nécessaire.

Afficher les journaux d'audit d'une clé Cloud KMS

Avant d'activer les journaux d'audit d'accès aux données Cloud KMS, vous devez vous familiariser avec les journaux d'audit Cloud.

Les journaux d'audit des accès aux données Cloud KMS vous indiquent lorsque Firestore ou tout autre produit configuré pour utiliser votre clé CMEK effectue des appels de chiffrement/déchiffrement à Cloud KMS. Firestore n'émet pas d'appel de chiffrement/déchiffrement à chaque requête de données, mais gère un service d'interrogation qui vérifie régulièrement la clé. Les résultats s'affichent dans les journaux d'audit.

Vous pouvez configurer les journaux d'audit dans la console Google Cloud et interagir avec ces éléments :

  1. Assurez-vous de l'activation de la journalisation pour l'API Cloud KMS dans votre projet.

  2. Accédez à Cloud Logging dans la console Google Cloud.

    Accéder à Cloud Logging

  3. Limitez les entrées de journal à votre clé Cloud KMS en ajoutant les lignes suivantes au générateur de requêtes :

    resource.type="cloudkms_cryptokey"
    resource.labels.key_ring_id = KMS_KEYRING
    resource.labels.crypto_key_id = KMS_KEY
    resource.labels.location=KMS_LOCATION
    

    Indiquez les éléments suivants :

    • KMS_KEY : nom de la clé CMEK.
    • KMS_KEYRING : trousseau de clés KMS contenant la clé.
    • KMS_LOCATION: emplacement de la clé et du trousseau de clés

    Le journal affiche quelques entrées de journal toutes les cinq minutes par base de données environ. Les entrées du journal se présentent comme suit :

    Info 2021-03-20 08:02:24.869 EDT Cloudkms.googleapis.com Decrypt projects/cloud-kms-project/locations/us-central1/keyRings/firestore-keys/cryptoKeys/my-cmek-key service-123456789123@gcp-sa-firestore.iam.gserviceaccount.com
    audit_log, method: "Decrypt", principal_email: "service-1234567891011@gcp-sa-firestore.iam.gserviceaccount.com"
    
    Info 2021-03-20 08:02:24.913 EDT Cloudkms.googleapis.com Encrypt projects/cloud-kms-project/locations/us-central1/keyRings/firestore-keys/cryptoKeys/my-cmek-key service-123456789123@gcp-sa-firestore.iam.gserviceaccount.com
    audit_log, method: "Encrypt", principal_email: "service-123456789123@gcp-sa-firestore.iam.gserviceaccount.com"
    

Pour en savoir plus sur l'interprétation des journaux d'audit, consultez la section Comprendre les journaux d'audit.

Configurer une règle d'administration CMEK

Pour spécifier des exigences de conformité en termes de chiffrement pour les bases de données Firestore de votre organisation, utilisez une contrainte de règle d'administration CMEK.

Exiger une protection CMEK

Configurez constraints/gcp.restrictNonCmekServices afin d'exiger l'utilisation du chiffrement CMEK pour la création de la base de données Firestore. Définissez la contrainte sur deny et ajoutez firestore.googleapis.com à la liste de refus, par exemple:

 gcloud resource-manager org-policies deny gcp.restrictNonCmekServices  is:firestore.googleapis.com --project=FIRESTORE_PROJECT

Remplacez FIRESTORE_PROJECT par le projet à restreindre.

Pour en savoir plus sur la configuration des règles d'administration, consultez Créer et modifier des règles.

Une fois la stratégie appliquée, vous recevez une exception FAILED_PRECONDITION et un message d'erreur si vous essayez de créer une base de données non CMEK dans le projet concerné. Par exemple, une exception se présente comme suit:

{
  "error": {
    "code": 400,
    "message": "Constraint 'constraints/gcp.restrictNonCmekServices' violated for 'projects/FIRESTORE_PROJECT' attempting to perform the operation 'google.firestore.admin.v1.FirestoreAdmin.CreateDatabase' with violated value 'firestore.googleapis.com'. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information.",
    "status": "FAILED_PRECONDITION",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
        "violations": [
          {
            "type": "constraints/gcp.restrictNonCmekServices",
            "subject": "orgpolicy:projects/FIRESTORE_PROJECT",
            "description": "Constraint 'constraints/gcp.restrictNonCmekServices' violated for 'projects/FIRESTORE_PROJECT' attempting to perform the operation 'google.firestore.admin.v1.FirestoreAdmin.CreateDatabase' with violated value 'firestore.googleapis.com'. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information."
          }
        ]

Limiter l'utilisation des clés pour les CMEK

Pour limiter les clés Cloud KMS utilisées pour la protection CMEK, configurez la contrainte constraints/gcp.restrictCmekCryptoKeyProjects.

En tant que contrainte de liste, les valeurs acceptées sont des indicateurs de hiérarchie des ressources (par exemple, projects/PROJECT_ID, under:folders/FOLDER_ID et under:organizations/ORGANIZATION_ID). Utilisez cette contrainte en configurant une liste d'indicateurs de hiérarchie des ressources et en définissant la contrainte sur Allow (Autoriser). Cette configuration limite les services compatibles de sorte que les clés CMEK ne puissent être choisies qu'à partir des projets, dossiers et organisations répertoriés. Les requêtes de création de ressources protégées par des clés CMEK dans les services configurés n'aboutissent pas sans une clé Firestore provenant de l'une des ressources autorisées.

L'exemple suivant n'autorise que les clés du ALLOWED_KEY_PROJECT_ID pour les bases de données protégées par des clés CMEK dans le projet spécifié:

gcloud resource-manager org-policies allow gcp.restrictCmekCryptoKeyProjects \
under:projects/ALLOWED_KEY_PROJECT_ID \
--project=FIRESTORE_PROJECT

Une fois la règle appliquée, vous recevez une exception FAILED_PRECONDITION et un message d'erreur si vous ne respectez pas la contrainte. Une exception se présente comme suit:

{
  "error": {
    "code": 400,
    "message": "Constraint 'constraints/gcp.restrictCmekCryptoKeyProjects' violated for 'projects/FIRESTORE_PROJECT' attempting to perform the operation 'google.firestore.admin.v1.FirestoreAdmin.CreateDatabase' with violated value 'projects/{NOT_ALLOWED_KEY_PROJECT}'. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information.",
    "status": "FAILED_PRECONDITION",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
        "violations": [
          {
            "type": "constraints/gcp.restrictCmekCryptoKeyProjects",
            "subject": "orgpolicy:projects/FIRESTORE_PROJECT",
            "description": "Constraint 'constraints/gcp.restrictCmekCryptoKeyProjects' violated for 'projects/FIRESTORE_PROJECT' attempting to perform the operation 'google.firestore.admin.v1.FirestoreAdmin.CreateDatabase' with violated value 'projects/{NOT_ALLOWED_KEY_PROJECT}'. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information."
          }
        ]
      }
    ]
  }
}

Étapes suivantes