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

Cette rubrique traite de la prise en charge des clés de chiffrement gérées par le client (CMEK) dans Secret Manager.

Présentation

Secret Manager fournit des outils de stockage, de gestion et d'accès aux données sensibles de vos applications.

Par défaut, les secrets stockés dans Secret Manager sont chiffrés au moyen du chiffrement par défaut de Google. Avec le chiffrement par défaut, les charges utiles des secrets sont chiffrées par des clés gérées par Google avant d'être écrites sur un espace de stockage persistant ; aucune configuration n'est nécessaire. Le chiffrement par défaut de Google constitue le meilleur choix pour de nombreuses organisations.

Pour les organisations qui souhaitent exercer un meilleur contrôle, la prise en charge de CMEK par Secret Manager permet de configurer la clé Cloud KMS qui protège les données au repos dans Secret Manager. Si vous désactivez ou détruisez temporairement la clé CMEK, les données chiffrées avec cette clé ne peuvent être déchiffrées et ne sont donc plus accessibles.

Fonctionnement de CMEK dans Secret Manager

Avant d'écrire la version d'un secret à un emplacement spécifique, Secret Manager chiffre les données à l'aide d'une clé de chiffrement de données unique (DEK, Data Encryption Key). Cette DEK est ensuite chiffrée par une clé spécifique à l'instance dupliquée, appelée clé de chiffrement de clé (KEK, Key Encryption Key) appartenant au service Secret Manager.

Lors de l'utilisation de CMEK par Secret Manager, la KEK est appelée clé CMEK ; il s'agit d'une clé symétrique que vous gérez dans Cloud KMS. La clé CMEK doit se trouver au même emplacement GCP que l'instance dupliquée de la version de secret chiffrée.

Ce guide explique comment configurer Secret Manager pour qu'il utilise CMEK. Pour en savoir plus sur CMEK en général, y compris quand et pourquoi l'activer, consultez la documentation de Cloud Key Management Service.

Limites

CMEK n'est disponible qu'avec l'API v1 de Secret Manager et gCloud.

Avant de commencer

Vous pouvez stocker toutes les ressources dans le même projet ou stocker les secrets et les clés dans des projets distincts. Consultez l'article Séparation des tâches Cloud KMS pour mieux comprendre cette décision.

Remplissez les conditions préalables suivantes pour configurer Secret Manager et Cloud KMS :

  • Secret Manager :

    • Créez ou utilisez un projet existant pour stocker vos ressources Secret Manager.
    • Si nécessaire, suivez les étapes décrites dans la section Configurer Secret Manager du guide de démarrage rapide de Secret Manager.
  • Cloud KMS :

    • Créez ou utilisez un projet existant pour stocker vos ressources Cloud KMS.
    • Si nécessaire, activez l'API Cloud KMS.

Attribuez les variables suivantes aux ID de vos projets Secret Manager et Cloud KMS.

Ligne de commande

$ export SM_PROJECT_ID="..."
$ export KMS_PROJECT_ID="..."

Authentifiez-vous sur Google Cloud :

gcloud

$ gcloud auth login

Créer un compte de service

Vous devez créer un compte de service pour chaque projet nécessitant des clés de chiffrement gérées par le client. Actuellement, vous ne pouvez utiliser que les commandes de l'outil de ligne de commande gcloud pour créer le type de compte de service dont vous avez besoin pour les clés de chiffrement gérées par le client.

Pour créer un compte de service avec l'outil de ligne de commande gcloud, exécutez la commande suivante :

gcloud

$ gcloud beta services identity create \
    --service "secretmanager.googleapis.com" \
    --project "${SM_PROJECT_ID}"

La commande précédente affiche un nom de compte de service au format suivant :

service-[PROJECT_NUMBER]@gcp-sa-secretmanager.iam.gserviceaccount.com

Accordez à ce compte de service l'accès aux clés CMEK de Cloud KMS pour chiffrer et déchiffrer vos secrets.

Enregistrez le nom du compte de service sous forme de variable d'environnement :

Ligne de commande

# This is from the output of the command above
$ export SM_SERVICE_ACCOUNT="service-...."

Les variables d'environnement du projet Secret Manager, du projet Cloud KMS et du compte de service de Secret Manager doivent être définies pendant toute la durée de cette procédure.

CMEK avec réplication automatique

Cette section traite des secrets configurés via une règle de réplication automatique.

Pour les secrets utilisant la règle de réplication automatique, votre clé CMEK doit se trouver dans l'emplacement multirégional global de Cloud KMS.

Créez une clé Cloud KMS symétrique dans la région Cloud KMS globale ou utilisez une clé existante. Cet exemple crée un trousseau de clés nommé secret-manager-cmek, puis crée dessus une clé appelée my-cmek-key.

gcloud

$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "global"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

Obtenez le nom de ressource de la clé et définissez-la comme variable d'environnement.

Ligne de commande

$ export KMS_KEY_NAME="projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"

Accordez au compte de service de Secret Manager l'accès au chiffrement et au déchiffrement à l'aide de la clé CMEK. Cette commande accorde au compte de service le rôle de chiffreur/déchiffreur Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) de la clé Cloud KMS my-cmek-key.

gcloud

$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Créer un secret avec réplication automatique. Le nom de ressource de la clé CMEK est stocké sous forme de métadonnées sur le secret.

gcloud

$ gcloud beta secrets create my-secret \
    --replication-policy "automatic" \
    --kms-key-name "${KMS_KEY_NAME}" \
    --project "${SM_PROJECT_ID}"

API

Attribuez comme valeur à replication.automatic.customerManagedEncryption.kmsKeyName le nom de ressource de la clé CMEK.

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets?secretId=my-secret" \
    --request "POST" \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --data-binary @- <<EOF
{
  "replication":{
    "automatic":{
      "customerManagedEncryption":{
        "kmsKeyName": "${KMS_KEY_NAME}"
      }
    }
  }
}
EOF

Désormais, chaque fois que la version d'un secret est créée dans ce secret, la charge utile de cette version est automatiquement chiffrée à l'aide de la clé avant d'être écrite sur le stockage persistant, tant que le compte de service a accès à la clé CMEK. Si le compte de service perd cet accès ou si la clé est indisponible, une tentative de création de version du secret ou d'accès à une version existante renvoie une erreur.

Ajouter une nouvelle version de secret. Notez que vous n'indiquez pas le nom de ressource de la clé Cloud KMS ; celui-ci est lu à partir des métadonnées du secret.

gcloud

$ echo -n "abcd1234" | gcloud beta secrets versions add "my-secret" \
    --project "${SM_PROJECT_ID}" \
    --data-file -

La version de secret est créée, même si l'appelant ne dispose pas d'un accès direct à l'utilisation de la clé CMEK. Le compte de service de Secret Manager, et non l'appelant, est responsable du chiffrement et du déchiffrement des secrets lors de leur lecture ou de leur écriture.

De même, vous n'avez pas besoin d'un accès direct à la clé CMEK pour accéder au secret. Le compte de service accède à la clé et chiffre ou déchiffre le code secret pour vous.

Accédez à la version du secret que vous venez de créer :

gcloud

$ gcloud beta secrets versions access latest \
    --project "${SM_PROJECT_ID}" \
    --secret "my-secret"

Mettre à jour la configuration CMEK

Créez de nouvelles clés KMS symétriques dans l'emplacement multirégional global de Cloud KMS.

gcloud

$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

Accordez à ce compte de service Secret Manager l'accès au chiffrement et au déchiffrement à l'aide de la nouvelle clé CMEK. Cette commande accorde au compte de service le rôle de chiffreur/déchiffreur Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) de la clé Cloud KMS my-other-key.

gcloud

$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Modifiez la configuration CMEK d'un un secret en mettant à jour la réplication du secret au moyen des nouveaux noms de ressources de la clé Cloud KMS.

gcloud

$ gcloud beta secrets replication update my-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication": {
    "automatic":{
      "customerManagedEncryption":{
        "kmsKeyName": "projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
      }
    }
  }
}
EOF

CMEK et réplication gérée par l'utilisateur

Cette section traite des secrets configurés avec une règle de réplication gérée par l'utilisateur. Avec une règle de réplication gérée par l'utilisateur, vous contrôlez l'emplacement GCP où le secret est stocké. Les secrets demeurent accessibles à partir de tous les emplacements GCP.

Les secrets suivant une règle de réplication gérée par l'utilisateur doivent recourir à des clés Cloud KMS qui correspondent exactement aux emplacements dans lesquels les versions des secrets sont stockées. Ce guide stocke un secret dans deux emplacements distincts : us-east1 et us-central1. Les requêtes d'accès à ce secret sont acheminées vers l'un de ces emplacements.

Dans chacune des deux régions, créez un trousseau de clés et une clé Cloud KMS destinée au chiffrement, ou utilisez une clé existante. Cet exemple crée un trousseau de clés nommé secret-manager-cmek, puis une clé appelée my-cmek-key dans chaque région.

gcloud

# us-east1
$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

# us-central1
$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

Accordez au compte de service l'autorisation de chiffrer et de déchiffrer à l'aide de la clé CMEK en attribuant le rôle de chiffreur/déchiffreur Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) à chaque clé CMEK ou à toutes les clés du projet.

gcloud

# us-east1
$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

# us-central1
$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Créer un secret CMEK activé dont la réplication est gérée par l'utilisateur Le nom de ressource de la clé CMEK est stocké sous forme de métadonnées sur le secret.

gcloud

$ cat <<EOF > replication-policy.json
{
  "userManaged":{
    "replicas":[
      {
        "location":"us-east1",
        "customerManagedEncryption":{
          "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
        }
      },
      {
        "location":"us-central1",
        "customerManagedEncryption":{
          "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
        }
      }
    ]
  }
}
EOF

$ gcloud beta secrets create my-ummr-secret \
    --replication-policy-file replication-policy.json \
    --project "${SM_PROJECT_ID}"

API

Attribuez comme valeur à replication.userManaged.replicas.customerManagedEncryption.kmsKeyName les noms des ressources destinées aux clés CMEK.

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets?secretId=my-ummr-secret" \
--request "POST" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @- <<EOF
{
  "replication":{
    "userManaged":{
      "replicas":[
        {
          "location":"us-east1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
          }
        },
        {
          "location":"us-central1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
          }
        }
      ]
    }
  }
}
EOF

Désormais, chaque fois que la version d'un secret est créée dans ce secret, la charge utile de cette version est automatiquement chiffrée à l'aide de la clé avant d'être écrite sur le stockage persistant, tant que le compte de service a accès à la clé CMEK. Si le compte de service perd cet accès ou si la clé est indisponible, une tentative de création de version du secret ou d'accès à une version existante renvoie une erreur.

Ajouter une nouvelle version de secret. Notez que vous n'indiquez pas le nom de ressource de la clé Cloud KMS ; celui-ci est lu à partir des métadonnées du secret.

gcloud

$ echo -n "abcd1234" | gcloud beta secrets versions add "my-ummr-secret" \
    --project "${SM_PROJECT_ID}" \
    --data-file -

La version de secret est créée, même si l'appelant ne dispose pas d'un accès direct à l'utilisation de la clé CMEK. Le compte de service de Secret Manager, et non l'appelant, est responsable du chiffrement et du déchiffrement des secrets lors de leur lecture ou de leur écriture.

De même, vous n'avez pas besoin d'un accès direct à la clé CMEK pour accéder au secret. Le compte de service accède à la clé et chiffre ou déchiffre le code secret pour vous.

Accédez à la version du secret que vous venez de créer.

gcloud

$ gcloud beta secrets versions access latest \
    --project "${SM_PROJECT_ID}" \
    --secret "my-ummr-secret"

Mettre à jour la configuration CMEK

Créez deux clés KMS symétriques dans les mêmes régions que le secret.

gcloud

# us-east1
$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

# us-central1
$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

Accordez à ce compte de service Secret Manager l'accès au chiffrement et au déchiffrement à l'aide des nouvelles clés CMEK. Cette commande accorde au compte de service le rôle de chiffreur/déchiffreur Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) des clés Cloud KMS my-other-key.

gcloud

# us-east1
$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

# us-central1
$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Modifiez la configuration CMEK d'un un secret en mettant à jour la réplication du secret au moyen des nouveaux noms de ressources de la clé Cloud KMS.

gcloud

$ gcloud beta secrets replication update my-ummr-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --location=us-east1 \
    --project "${SM_PROJECT_ID}"

$ gcloud beta secrets replication update my-ummr-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --location=us-central1 \
    --project "${SM_PROJECT_ID}"

Pour mettre à jour plusieurs clés simultanément dans un secret, vous pouvez obtenir et définir la stratégie de réplication via un fichier.

gcloud

$ gcloud beta secrets replication get my-ummr-secret --project "${SM_PROJECT_ID}" --format=json > replication-policy.json

# update the file to reflect desired CMEK configuration
$ edit replication-policy json

$ gcloud beta secrets replication set my-ummr-secret \
    --replication-policy-file=replication-policy.json \
    --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-ummr-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication":{
    "userManaged":{
      "replicas":[
        {
          "location":"us-east1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
          }
        },
        {
          "location":"us-central1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
          }
        }]
      }
    }
  }
EOF

Afficher la configuration CMEK de la version du secret

Consultez les métadonnées de la version d'un secret pour savoir si celle-ci est compatible avec CMEK et pour connaître le nom de ressource de la version de clé CMEK.

gcloud

$ gcloud beta secrets versions describe latest --secret my-secret --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret/versions/latest" \
    --request "GET" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json"

Cette commande renvoie le nom complet de la ressource Cloud KMS de la version de clé utilisée pour chiffrer la version du secret.

{
  "name": "projects/[PROJECT_NUMBER]/secrets/my-secret/versions/1",
  "createTime": "2020-07-...",
  "state": "ENABLED",
  "replicationStatus": {
    "automatic": {
      "customerManagedEncryption": {
        "kmsKeyVersionName": "projects/[KMS_PROJECT]/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key/cryptoKeyVersions/1"
      }
    }
  }
}

Désactiver CMEK

Supprimer la configuration CMEK d'un secret en mettant à jour la règle de réplication

gcloud

$ gcloud beta secrets replication update my-secret --remove-cmek --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication":{
    "automatic":{}
  }
}
EOF

Et ensuite ?

  • Apprenez-en davantage sur CMEK