Chiffrer des fonctions Cloud Functions à l'aide de clés de chiffrement gérées par le client (CMEK)

1. Introduction

Présentation

Cloud Functions est une solution de calcul légère permettant aux développeurs de créer des fonctions autonomes à usage spécifique qui répondent aux événements Cloud sans avoir à gérer de serveur ni d'environnement d'exécution.

Vous pouvez utiliser les clés de chiffrement gérées par le client (CMEK, customer-managed encryption keys) Cloud Key Management Service pour protéger Cloud Functions et les données au repos associées. Le déploiement d'une fonction avec une CMEK protège les données qui lui sont associées en utilisant une clé de chiffrement que vous contrôlez entièrement. Ce type de chiffrement vous permet de répondre aux exigences de conformité dans certains secteurs, tels que les services financiers. Étant donné que la clé vous appartient et n'est pas contrôlée par Google, personne (même pas vous) ne peut accéder aux données protégées par ces clés de chiffrement lorsque ces dernières sont désactivées ou détruites.

Pour Cloud Functions, CMEK chiffre les éléments suivants:

  • Code source de la fonction importé pour le déploiement et stocké par Google dans Cloud Storage, utilisé dans le processus de compilation.
  • Les résultats du processus de compilation de la fonction, y compris l'image de conteneur créée à partir du code source de votre fonction, chaque instance de la fonction qui est déployée.
  • Données au repos pour les canaux internes de transport d'événements (1re génération uniquement).

Pour en savoir plus sur les données chiffrées, consultez la documentation sur le chiffrement CMEK dans Cloud Functions.

Ce que vous allez faire

Cet atelier de programmation explique comment déployer une fonction Cloud (1re génération ou 2e génération) chiffrée à l'aide de CMEK. Cet atelier de programmation utilise une fonction Cloud publique, c'est-à-dire une fonction qui ne nécessite pas d'authentification, à des fins de démonstration. Vous pouvez appeler une fonction authentifiée compatible avec CMEK comme n'importe quelle autre fonction Cloud nécessitant une authentification.

Points abordés

  • Créer une clé CMEK sur un trousseau de clés symétriques existant
  • Créer un dépôt Artifact Registry
  • Configurer CMEK sur une fonction Cloud pour les versions 1re et 2e génération

2. Préparation

Prérequis

  • Vous êtes connecté à la console Cloud.
  • Vous avez déjà déployé une fonction Cloud déclenchée par HTTP (pour vérifier que vous avez activé les rôles et les API appropriés)

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Si vous démarrez Cloud Shell pour la première fois, un écran intermédiaire s'affiche pour décrire de quoi il s'agit. Si tel est le cas, cliquez sur Continuer.

9c92662c6a846a5c.png

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

9f0e51b578fecce5.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez réaliser une grande partie, voire la totalité, des activités de cet atelier de programmation dans un navigateur.

Une fois connecté à Cloud Shell, vous êtes en principe authentifié, et le projet est défini avec votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet:
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

3. Créer un trousseau de clés et une clé pour Cloud Functions

Assurez-vous que l'API Cloud KMS est activée en exécutant la commande suivante:

gcloud services enable cloudkms.googleapis.com

Commencez par créer des variables d'environnement contenant le nom du trousseau de clés, le nom de la clé, la région et les autres variables utilisées dans cet atelier de programmation.

KEYRING_NAME="keyring-functions"
REGION="us-central1"
KEY_NAME="key-encrypted-function"
PROJECT_ID=$(gcloud config get-value project)
PROJECT_NUMBER="$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')"
USER_EMAIL="$(gcloud config list account --format "value(core.account)")"

Créez ensuite un trousseau de clés, qui est la ressource racine des clés et des versions de clé Cloud KMS.

gcloud kms keyrings create $KEYRING_NAME --location $REGION

Enfin, vous pouvez désormais créer une clé symétrique dans votre nouveau trousseau dans Cloud KMS.

gcloud kms keys create $KEY_NAME --keyring $KEYRING_NAME --location $REGION --purpose "encryption"

4. Créer un dépôt Artifact Registry au format Docker avec CMEK activé

Dans cette section, vous allez créer un dépôt au format Docker dans Artifact Registry avec CMEK activé. Il s'agit de la même clé que celle utilisée pour déployer votre fonction Cloud.

Vous devez d'abord disposer d'un compte de service pour Artifact Registry. Pour ce faire, exécutez la commande suivante:

gcloud beta services identity create --service=artifactregistry.googleapis.com --project=$PROJECT_ID

Utilisez la commande suivante pour accorder le rôle IAM de chiffreur/déchiffreur de clés cryptographiques (roles/cloudkms.cryptoKeyEncrypterDecrypter) au compte de service Artifact Registry afin d'obtenir des autorisations sur la clé:

gcloud kms keys add-iam-policy-binding \
  $KEY_NAME --location $REGION --keyring=$KEYRING_NAME \
  --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com \
  --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Attribuez le rôle au principe qui créera le dépôt dans le registre d'artefacts, par exemple votre compte actif actuel. Vous pouvez vérifier votre compte actif actuel en exécutant gcloud auth list.

gcloud kms keys add-iam-policy-binding \
       $KEY_NAME --location $REGION --keyring=$KEYRING_NAME \
       --member user:$USER_EMAIL \
       --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Vous pouvez maintenant créer un dépôt au format Docker compatible avec CMEK.

Remarque:La région doit être la même que celle de la clé CMEK.

REPO_NAME=my-cmek-encrypted-repo 

KEY_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/keyRings/"$KEYRING_NAME"/cryptoKeys/"$KEY_NAME" 

gcloud artifacts repositories create $REPO_NAME \
    --repository-format=docker \
    --location=$REGION \
    --kms-key=$KEY_FULLPATH \
    --async

Vous pouvez afficher votre nouveau dépôt Artifact Registry en exécutant la commande suivante:

gcloud artifacts repositories describe $REPO_NAME --location=$REGION

5. Accorder aux comptes de service l'accès à la clé (2e génération)

Cette section explique comment créer des comptes de service pour des fonctions de 2e génération. Si vous créez une fonction de 1re génération, passez à la section suivante.

Vous devez accorder l'accès à la clé à plusieurs agents de service en leur attribuant le rôle IAM de chiffreur/déchiffreur de clés cryptographiques (roles/cloudkms.cryptoKeyEncrypterDecrypter). Ces agents de service permettent d'accéder au code source stocké dans Cloud Storage, de stocker des images de fonction dans un dépôt protégé par CMEK dans Artifact Registry et de déployer une fonction Cloud chiffrée par CMEK.

Étapes pour les fonctions de 2e génération

  1. Autorisez l'agent de service Cloud Run à accéder à la clé:
CLOUDRUN_SA=service-$PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com

gcloud kms keys add-iam-policy-binding $KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION \
--member=serviceAccount:$CLOUDRUN_SA \
--role=roles/cloudkms.cryptoKeyEncrypterDecrypter
  1. Accordez à l'agent de service Eventarc l'accès à la clé:
EVENTARC_SA=service-$PROJECT_NUMBER@gcp-sa-eventarc.iam.gserviceaccount.com

gcloud kms keys add-iam-policy-binding $KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION \
--member=serviceAccount:$EVENTARC_SA \
--role=roles/cloudkms.cryptoKeyEncrypterDecrypter
  1. Accordez à l'agent de service Artifact Registry l'accès à la clé:
AR_SA=service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com

gcloud kms keys add-iam-policy-binding $KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION \
--member=serviceAccount:$AR_SA \
--role=roles/cloudkms.cryptoKeyEncrypterDecrypter
  1. Accordez aux agents de service Cloud Storage l'accès à la clé:
STORAGE_SA=service-$PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com

gcloud kms keys add-iam-policy-binding $KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION \
--member=serviceAccount:$STORAGE_SA \
--role=roles/cloudkms.cryptoKeyEncrypterDecrypter

Dans la section suivante, vous allez découvrir comment créer et déployer une fonction chiffrée CMEK.

6. Accorder aux comptes de service l'accès à la clé (1re génération)

Cette section explique comment créer des comptes de service pour les fonctions de 1re génération. Si vous avez déjà créé des comptes de service pour une fonction de 2e génération, passez à la section suivante.

Vous devez accorder l'accès à la clé à plusieurs agents de service en leur attribuant le rôle IAM de chiffreur/déchiffreur de clés cryptographiques (roles/cloudkms.cryptoKeyEncrypterDecrypter). Ces agents de service permettent d'accéder au code source stocké dans Cloud Storage, de stocker des images de fonction dans un dépôt protégé par CMEK dans Artifact Registry et de déployer une fonction Cloud chiffrée par CMEK.

Étapes pour les fonctions de 1re génération

  1. Autorisez l'agent de service Cloud Functions à accéder à la clé:
FUNCTION_SA=service-$PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com

gcloud kms keys add-iam-policy-binding $KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION \
--member=serviceAccount:$FUNCTION_SA \
--role=roles/cloudkms.cryptoKeyEncrypterDecrypter
  1. Accordez à l'agent de service Artifact Registry l'accès à la clé:
AR_SA=service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com

gcloud kms keys add-iam-policy-binding $KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION \
--member=serviceAccount:$AR_SA \
--role=roles/cloudkms.cryptoKeyEncrypterDecrypter
  1. Accordez aux agents de service Cloud Storage l'accès à la clé:
STORAGE_SA=service-$PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com

gcloud kms keys add-iam-policy-binding $KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION \
--member=serviceAccount:$STORAGE_SA \
--role=roles/cloudkms.cryptoKeyEncrypterDecrypter

Dans la section suivante, vous découvrirez comment créer et déployer une fonction chiffrée par CMEK.

7. Créer une fonction chiffrée CMEK (2nd gen)

Cette section explique comment créer des fonctions de 2e génération. Vous pouvez passer à la section suivante pour obtenir des instructions concernant la première génération.

Maintenant que vous avez configuré un dépôt Artifact Registry avec CMEK activé et accordé à Cloud Functions l'accès à votre clé, vous pouvez déployer une fonction chiffrée à l'aide de votre clé CMEK.

Procédure à suivre pour les fonctions de 2e génération:

Créer le code source de la fonction

Bien que cet atelier de programmation utilise Node.js, vous pouvez utiliser n'importe quel environnement d'exécution compatible.

Commencez par créer un répertoire et utilisez la commande cd pour y accéder.

mkdir ~/cmek-function-2ndgen && cd $_

Créez ensuite le fichier package.json.

touch package.json

echo '{
  "dependencies": {
    "@google-cloud/functions-framework": "^2.1.0"
  }
}
' > package.json

Créez ensuite le fichier source index.js.

touch index.js

echo 'const functions = require("@google-cloud/functions-framework");

functions.http("helloWorld", (req, res) => {
 res.send(`Hello ${req.query.name || req.body.name || "World"}!`);
});' > index.js

Déployer la fonction Cloud de 2e génération à l'aide du chiffrement CMEK

Remarque:L'exemple ci-dessous montre comment déployer une fonction à l'aide de sources de votre répertoire actuel. Assurez-vous de vous trouver dans le même répertoire que le code source de votre fonction.

FUNCTION_NAME=protect-me-cmek-2ndgen
ENTRY_POINT=helloWorld

REPO_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/repositories/$REPO_NAME

gcloud beta functions deploy $FUNCTION_NAME  \
--gen2 \
--region $REGION \
--kms-key $KEY_FULLPATH \
--docker-repository $REPO_FULLPATH \
--source . \
--trigger-http \
--allow-unauthenticated \
--runtime nodejs16 \
--entry-point $ENTRY_POINT

Vous pouvez voir la clé CMEK dans la sortie générée en exécutant cette commande :

gcloud functions describe $FUNCTION_NAME –region $REGION | grep kmsKeyName

Tester la fonction 2e génération

Vous pouvez tester votre fonction en exécutant une commande curl:

FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(serviceConfig.uri)')"

curl $FUNCTION_URL

ce qui donne le résultat suivant:

Hello World!

Tant que la clé de chiffrement est activée, la fonction renvoie un code de succès à l'appelant. Toutefois, une fois la clé de chiffrement désactivée, l'appelant reçoit une erreur.

Dans la section suivante, vous verrez ce qui se passe lorsque vous appelez la fonction après la désactivation de la clé.

8. Créer une fonction chiffrée CMEK (1re génération)

Cette section explique comment créer des fonctions de 1re génération. Si vous avez déjà créé une fonction de 2e génération, passez à la section suivante.

Maintenant que vous disposez d'un dépôt Artifact Registry avec CMEK activé et que vous avez autorisé Cloud Functions à accéder à votre clé, vous pouvez déployer une fonction chiffrée à l'aide de votre clé CMEK.

Procédure à suivre pour les fonctions de 1re génération:

Créer le code source de la fonction de 1re génération

Bien que cet atelier de programmation utilise Node.js, vous pouvez utiliser n'importe quel environnement d'exécution compatible.

Commencez par créer un répertoire et utilisez la commande cd pour y accéder.

mkdir ~/cmek-function-1stgen && cd $_

Créez ensuite le fichier package.json.

touch package.json

echo '{
    "name": "function-cmek-codelab",
    "version": "0.0.1"
}' > package.json

Ensuite, créez le fichier source index.js.

touch index.js

echo "exports.helloWorld = (req, res) => {
    let message = req.query.message || req.body.message || 'Hello World!';
    res.status(200).send(message);
};" > index.js

Déployer la fonction Cloud 1re génération à l'aide du chiffrement CMEK

Remarque:L'exemple ci-dessous montre comment déployer une fonction à l'aide de sources de votre répertoire actuel. Assurez-vous de vous trouver dans le même répertoire que le code source de votre fonction.

FUNCTION_NAME=protect-me-cmek-1stgen
ENTRY_POINT=helloWorld

REPO_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/repositories/$REPO_NAME

gcloud functions deploy $FUNCTION_NAME  \
--region $REGION \
--kms-key $KEY_FULLPATH \
--docker-repository $REPO_FULLPATH \
--source . \
--trigger-http \
--allow-unauthenticated \
--runtime nodejs16 \
--entry-point $ENTRY_POINT

Vous pouvez voir la clé CMEK dans la sortie générée en exécutant cette commande :

gcloud functions describe $FUNCTION_NAME –region $REGION | grep kmsKeyName

Tester la fonction de 1re génération

Vous pouvez tester votre fonction en l'exécutant avec curl:

FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(httpsTrigger.url)')"

curl $FUNCTION_URL

ce qui donne le résultat suivant:

Hello World!

Tant que la clé de chiffrement est activée, la fonction renvoie un code de succès à l'appelant. Toutefois, une fois la clé de chiffrement désactivée, l'appelant reçoit une erreur.

Dans la section suivante, vous verrez ce qui se passe lorsque vous appelez la fonction après que la touche a été désactivée.

9. Appeler une fonction chiffrée CMEK dont la clé de chiffrement a été désactivée

Dans cette dernière section, vous allez invalider la clé et appeler à nouveau la fonction pour voir l'erreur qui en résulte.

Désactiver la clé de chiffrement

Vous pouvez exécuter cette commande pour désactiver la clé. Comme cet atelier de programmation ne crée qu'une seule version de la clé, vous allez désactiver la version 1.

gcloud kms keys versions disable 1 \
    --key=$KEY_NAME \
    --keyring=$KEYRING_NAME \
    --location=$REGION

Vous devriez obtenir les informations suivantes:

algorithm: GOOGLE_SYMMETRIC_ENCRYPTION
createTime: '2023-04-11T03:30:49.111832653Z'
generateTime: '2023-04-11T03:30:49.111832653Z'
name: projects/dogfood-gcf-saraford/locations/us-central1/keyRings/myKeyRing/cryptoKeys/encrypted-function/cryptoKeyVersions/1
protectionLevel: SOFTWARE
state: DISABLED

Appeler la fonction avec une clé désactivée

curl à nouveau la fonction.

curl $FUNCTION_URL

et vous ne recevrez pas de réponse "Hello World" cette fois-ci.

Dans les journaux de la fonction Cloud, vous verrez

User's CMEK key has been disabled. CMEK key: projects/<PROJECT-NAME>/locations/us-central1/keyRings/myKeyRing/cryptoKeys/encrypted-function

Tentative d'affichage des ressources lorsque la clé CMEK est désactivée

Dans cette section, vous verrez que les ressources suivantes ne sont plus disponibles lorsque la clé CMEK est désactivée:

  • Code source de la fonction
  • Créer une image de conteneur à partir de votre code source

Par exemple, l'onglet "Source" de la fonction Cloud affiche une erreur lors de la récupération de l'archive. Une erreur similaire s'affiche si vous tentez d'afficher le fichier ZIP contenant le code source directement dans Cloud Storage.

ac3307bb05d30e19.png

De plus, vous n'aurez pas accès à l'image de conteneur de la fonction à partir d'Artifact Registry. Par exemple, si vous essayez de déployer cette image de conteneur sur Cloud Run, vous recevrez un message d'erreur indiquant que l'image n'a pas été trouvée.

Pour obtenir la liste complète des ressources chiffrées, consultez la documentation sur les fonctions CMEK.

10. Félicitations

Félicitations, vous avez terminé cet atelier de programmation.

Points abordés

  • Créer une clé CMEK sur un trousseau de clés symétriques existant
  • Créer un dépôt Artifact Registry
  • Configurer CMEK sur une fonction Cloud

Pour en savoir plus

Pour en savoir plus sur Cloud Functions et CMEK, consultez les liens suivants: