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 des clés de chiffrement gérées par le client (CMEK) Cloud Key Management Service pour protéger Cloud Functions et les données associées au repos. Le déploiement d'une fonction avec une CMEK protège les données qui lui sont associées à l'aide d'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 qu'elle n'est pas contrôlée par Google, personne (pas même vous) ne peut accéder aux données protégées par ces clés de chiffrement lorsque celles-ci sont désactivées ou détruites.

Pour Cloud Functions, la clé 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.
  • Résultats du processus de compilation de la fonction, y compris l'image de conteneur créée à partir du code source de votre fonction, ainsi que chaque instance de la fonction 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 CMEK de la fonction Cloud.

Ce que vous allez faire

Cet atelier de programmation explique comment déployer une fonction Cloud (1re 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 activée par 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étrique existant
  • Créer un dépôt Artifact Registry
  • Configurer une clé CMEK sur une fonction Cloud pour les 1re et 2e générations

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 les rôles et les API appropriés sont activé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 vous explique de quoi il s'agit. Si un écran intermédiaire s'est affiché, 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 dans Google Cloud, ce qui améliore considérablement les performances du réseau et l'authentification. Une grande partie, voire la totalité, de votre travail dans cet atelier de programmation peut être effectué dans un navigateur.

Une fois connecté à Cloud Shell, vous êtes authentifié et le projet est défini sur 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

Tout d'abord, créez des variables d'environnement contenant le nom du trousseau de clés, le nom de la clé, la région et d'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 maintenant créer une clé symétrique dans votre nouveau trousseau de clés au sein de 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 compatible avec CMEK

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

Tout d'abord, vous aurez besoin du compte de service pour Artifact Registry. Vous pouvez le créer en exécutant la commande suivante:

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

Utilisez la commande suivante pour accorder au compte de service Artifact Registry le rôle IAM Chiffreur/Déchiffreur de CryptoKeys (roles/cloudkms.cryptoKeyEncrypterDecrypter) afin qu'il dispose d'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

Accordez le rôle au principe qui créera le dépôt dans Artifact Registry, 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 CMEK.

Remarque:La région doit être identique à 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 cette commande:

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, veuillez passer à la section suivante.

Vous devez accorder à plusieurs agents de service l'accès à la clé en attribuant le rôle IAM Chiffreur/Déchiffreur de CryptoKeys (roles/cloudkms.cryptoKeyEncrypterDecrypter). Ces agents de service permettent d'obtenir l'accès au code source stocké dans Cloud Storage, de stocker des images de fonctions 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 2e génération

  1. Accordez à l'agent de service Cloud Run l'accès à 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 découvrirez comment créer et déployer une fonction chiffrée par 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 2nd gen, passez à la section suivante.

Vous devez accorder à plusieurs agents de service l'accès à la clé en attribuant le rôle IAM Chiffreur/Déchiffreur de CryptoKeys (roles/cloudkms.cryptoKeyEncrypterDecrypter). Ces agents de service permettent d'obtenir l'accès au code source stocké dans Cloud Storage, de stocker des images de fonctions 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 1re génération

  1. Accordez à l'agent de service Cloud Functions l'accès à 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 par CMEK (2e génération)

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 1re génération.

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.

Étapes pour les fonctions 2nd gen:

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.

Tout d'abord, créez un répertoire et utilisez la commande cd pour y accéder.

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

Ensuite, créez le fichier package.json.

touch package.json

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

Ensuite, créez 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. Vérifiez que vous vous trouvez 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 à partir du résultat en exécutant cette commande

Les fonctions gcloud décrivent $FUNCTION_NAME –region $REGION | grep kmsKeyName

Tester la fonction 2nd gen

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

Résultat:

Hello World!

Tant que la clé de chiffrement est activée, la fonction renvoie un message de réussite à l'appelant. Cependant, une fois la clé de chiffrement désactivée, l'appelant reçoit un message d'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.

8. Créer une fonction chiffrée par 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 2nd gen, 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.

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

Créer le code source pour 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 $_

Ensuite, créez 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 de 1re génération avec le chiffrement CMEK

Remarque:L'exemple ci-dessous montre comment déployer une fonction à l'aide de sources de votre répertoire actuel. Vérifiez que vous vous trouvez 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 à partir du résultat en exécutant cette commande

Les fonctions gcloud décrivent $FUNCTION_NAME –region $REGION | grep kmsKeyName

Tester la fonction de 1re 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(httpsTrigger.url)')"

curl $FUNCTION_URL

Résultat:

Hello World!

Tant que la clé de chiffrement est activée, la fonction renvoie un message de réussite à l'appelant. Cependant, une fois la clé de chiffrement désactivée, l'appelant reçoit un message d'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 par CMEK pour laquelle 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 afficher 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 désactiverez 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 touche désactivée

Maintenant, utilisez à nouveau curl pour 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

Tenter d'afficher les ressources lorsque la clé CMEK est désactivée

Dans cette section, vous verrez que les ressources suivantes deviennent indisponibles lorsque la clé CMEK est désactivée:

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

Par exemple, l'accès à l'onglet "Source" de la fonction Cloud indique 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 d'Artifact Registry pour la fonction. Par exemple, si vous tentez de déployer cette image de conteneur dans Cloud Run, vous recevrez un message d'erreur indiquant que l'image est introuvable.

Veuillez consulter la documentation sur les fonctions CMEK pour obtenir la liste complète des ressources chiffrées.

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étrique existant
  • Créer un dépôt Artifact Registry
  • Configurer une clé CMEK sur une fonction Cloud

Pour en savoir plus

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