Cloud Functions-Funktionen mit vom Kunden verwalteten Verschlüsselungsschlüsseln (CMEK) verschlüsseln

1. Einführung

Übersicht

Cloud Functions ist eine ressourcensparende Computing-Lösung, mit der Entwickler zweckgebundene, eigenständige Funktionen erstellen können, die auf Cloud-Ereignisse reagieren, ohne einen Server oder eine Laufzeitumgebung verwalten zu müssen.

Sie können vom Kunden verwaltete Verschlüsselungsschlüssel (Customer-Managed Encryption Keys, CMEK) des Cloud Key Management Service verwenden, um Cloud Functions und zugehörige ruhende Daten zu schützen. Durch das Bereitstellen einer Funktion mit einem CMEK werden die damit verknüpften Daten mithilfe eines Verschlüsselungsschlüssels geschützt, der in Ihrer Kontrolle liegt. Mit dieser Art der Verschlüsselung können Sie Compliance-Anforderungen in bestimmten Branchen erfüllen, z. B. in der Finanzdienstleistungsbranche. Da Ihnen der Schlüssel gehört und nicht von Google gesteuert wird, kann niemand (einschließlich Sie) auf die Daten zugreifen, die durch diese Verschlüsselungsschlüssel geschützt sind, wenn die Schlüssel deaktiviert oder gelöscht werden.

Bei Cloud Functions werden mit CMEK Folgendes verschlüsselt:

  • Quellcode der Funktion, der für die Bereitstellung hochgeladen und von Google in Cloud Storage gespeichert wird, der beim Build-Prozess verwendet wird.
  • Die Ergebnisse des Funktions-Build-Prozesses, einschließlich des Container-Images, das aus Ihrem Funktionsquellcode erstellt wurde, und jeder Instanz der bereitgestellten Funktion.
  • Ruhende Daten für interne Ereignistransportkanäle (nur 1. Generation).

Weitere Informationen dazu, welche Daten verschlüsselt werden, finden Sie in der Dokumentation zum Cloud Functions-CMEK.

Aufgaben

In diesem Codelab wird gezeigt, wie Sie eine Cloud Functions-Funktion (entweder 1. Generation oder 2. Generation) bereitstellen, die mit CMEK verschlüsselt ist. In diesem Codelab wird zu Demonstrationszwecken eine öffentliche Cloud-Funktion verwendet, für die keine Authentifizierung erforderlich ist. Sie können eine authentifizierte CMEK-fähige Funktion wie jede andere Cloud Functions-Funktion aufrufen, die eine Authentifizierung erfordert.

Lerninhalte

  • CMEK-Schlüssel für einen vorhandenen symmetrischen Schlüsselbund erstellen
  • Artifact Registry-Repository erstellen
  • CMEK für eine Cloud Function der 1. und 2. Generation konfigurieren

2. Einrichtung und Anforderungen

Vorbereitung

  • Sie sind in der Cloud Console angemeldet.
  • Sie haben zuvor eine durch HTTP ausgelöste Cloud Functions-Funktion bereitgestellt, um zu prüfen, ob die entsprechenden Rollen und APIs aktiviert sind.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Wenn Sie Cloud Shell zum ersten Mal starten, wird ein Zwischenbildschirm mit einer Beschreibung angezeigt. Klicken Sie in diesem Fall auf Weiter.

9c92662c6a846a5c.png

Die Bereitstellung und Verbindung mit Cloud Shell sollte nur wenige Minuten dauern.

9f0e51b578fecce5.png

Auf dieser virtuellen Maschine sind alle erforderlichen Entwicklungstools installiert. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht alle Aufgaben in diesem Codelab können mit einem Browser erledigt werden.

Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie authentifiziert sind und das Projekt auf Ihre Projekt-ID festgelegt ist.

  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

3. Neuen Schlüsselbund und Schlüssel für Cloud Functions erstellen

Prüfen Sie mit dem folgenden Befehl, ob die Cloud KMS API aktiviert ist:

gcloud services enable cloudkms.googleapis.com

Erstellen Sie zuerst Umgebungsvariablen für den Namen des Schlüsselbunds, den Schlüsselnamen, die Region und andere Variablen, die in diesem Codelab verwendet werden.

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)")"

Erstellen Sie als Nächstes einen Schlüsselbund, der die Stammressource für Cloud KMS-Schlüssel und ‑Schlüsselversionen ist.

gcloud kms keyrings create $KEYRING_NAME --location $REGION

Außerdem können Sie jetzt in Ihrem neuen Schlüsselbund in Cloud KMS einen symmetrischen Schlüssel erstellen.

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

4. CMEK-fähiges Artifact Registry-Repository im Docker-Format erstellen

In diesem Abschnitt erstellen Sie in Artifact Registry mit aktiviertem CMEK ein Repository im Docker-Format. Dieser Schlüssel ist derselbe, der zum Bereitstellen der Cloud Functions-Funktion verwendet wird.

Zuerst benötigen Sie das Dienstkonto für Artifact Registry. Sie können sie mit dem folgenden Befehl erstellen:

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

Mit dem folgenden Befehl gewähren Sie dem Artifact Registry-Dienstkonto die IAM-Rolle „CryptoKey-Verschlüsseler/Entschlüsseler“ (roles/cloudkms.cryptoKeyEncrypterDecrypter), damit es Berechtigungen für den Schlüssel erhält:

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

Weisen Sie die Rolle dem Prinzip zu, das das Repository in der Artefaktregistrierung erstellt, z.B. Ihrem derzeit aktiven Konto. Sie können das derzeit aktive Konto mit dem Befehl „gcloud auth list“ prüfen.

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

Sie können jetzt ein CMEK-fähiges Repository im Docker-Format erstellen.

Hinweis:Die Region muss mit der Region des CMEK-Schlüssels übereinstimmen.

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

Sie können Ihr neues Artifact Registry-Repository mit dem folgenden Befehl aufrufen:

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

5. Dienstkonten Zugriff auf den Schlüssel gewähren (2. Generation)

In diesem Abschnitt erfahren Sie, wie Sie Dienstkonten für Funktionen der 2. Generation erstellen. Wenn Sie eine Funktion der 1. Generation erstellen, fahren Sie mit dem nächsten Abschnitt fort.

Sie müssen mehreren Dienst-Agenten Zugriff auf den Schlüssel gewähren, indem Sie ihnen die IAM-Rolle „CryptoKey Encrypter/Decrypter“ (roles/cloudkms.cryptoKeyEncrypterDecrypter) zuweisen. Diese Dienst-Agenten werden verwendet, um Zugriff auf den in Cloud Storage gespeicherten Quellcode zu erhalten, Funktions-Images in einem CMEK-geschützten Repository in Artifact Registry zu speichern und eine CMEK-verschlüsselte Cloud-Funktion bereitzustellen.

Schritte für Funktionen der 2. Generation

  1. Gewähren Sie dem Cloud Run-Dienst-Agent Zugriff auf den Schlüssel:
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. Gewähren Sie dem Eventarc-Dienst-Agent Zugriff auf den Schlüssel:
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. Gewähren Sie dem Artifact Registry-Dienst-Agent Zugriff auf den Schlüssel:
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. Gewähren Sie den Cloud Storage-Dienst-Agents Zugriff auf den Schlüssel:
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

Im nächsten Abschnitt erfahren Sie, wie Sie eine CMEK-verschlüsselte Funktion erstellen und bereitstellen.

6. Dienstkonten Zugriff auf den Schlüssel gewähren (1. Generation)

In diesem Abschnitt erfahren Sie, wie Sie Dienstkonten für Funktionen der 1. Generation erstellen. Wenn Sie bereits Dienstkonten für eine Funktion der 2. Generation erstellt haben, fahren Sie mit dem nächsten Abschnitt fort.

Sie müssen mehreren Dienst-Agents Zugriff auf den Schlüssel gewähren, indem Sie die IAM-Rolle CryptoKey Encrypter/Decrypter (roles/cloudkms.cryptoKeyEncrypterDecrypter) zuweisen. Diese Dienst-Agents werden verwendet, um Zugriff auf den in Cloud Storage gespeicherten Quellcode zu erhalten, Funktions-Images in einem CMEK-geschützten Repository in Artifact Registry zu speichern und eine CMEK-verschlüsselte Cloud Functions-Funktion bereitzustellen.

Schritte für Funktionen der 1. Generation

  1. Gewähren Sie dem Cloud Functions-Dienst-Agent Zugriff auf den Schlüssel:
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. Gewähren Sie dem Artifact Registry-Dienst-Agent Zugriff auf den Schlüssel:
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. Gewähren Sie den Cloud Storage-Dienst-Agents Zugriff auf den Schlüssel:
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

Im nächsten Abschnitt erfahren Sie, wie Sie eine CMEK-verschlüsselte Funktion erstellen und bereitstellen.

7. CMEK-verschlüsselte Funktion (2nd gen) erstellen

In diesem Abschnitt wird das Erstellen von Funktionen der 2. Generation behandelt. Eine Anleitung für die 1. Generation finden Sie im nächsten Abschnitt.

Sie haben ein Artifact Registry-Repository mit aktiviertem CMEK konfiguriert und Cloud Functions Zugriff auf Ihren Schlüssel gewährt. Jetzt können Sie eine Funktion bereitstellen, die mit Ihrem CMEK-Schlüssel verschlüsselt ist.

Schritte für Funktionen der 2. Generation:

Quellcode für die Funktion erstellen

In diesem Codelab wird Node.js verwendet, Sie können aber jede unterstützte Laufzeit verwenden.

Erstellen Sie zunächst ein Verzeichnis und speichern Sie das Verzeichnis mit cd.

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

Erstellen Sie dann die Datei „package.json“.

touch package.json

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

Erstellen Sie als Nächstes die Quelldatei "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

Cloud Functions-Funktion der 2. Generation mit CMEK-Verschlüsselung bereitstellen

Hinweis:Im folgenden Beispiel wird gezeigt, wie eine Funktion mithilfe von Quellen aus dem aktuellen Verzeichnis bereitgestellt wird. Sie müssen sich im selben Verzeichnis wie der Quellcode Ihrer Funktion befinden.

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

Sie können den CMEK-Schlüssel in der resultierenden Ausgabe sehen, indem Sie diesen Befehl ausführen:

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

Funktion der 2. Generation testen

Sie können die Funktion mit curl testen:

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

curl $FUNCTION_URL

Das führt zu folgendem Ergebnis:

Hello World!

Solange der Verschlüsselungsschlüssel aktiviert ist, gibt die Funktion dem Aufrufer den Wert „Erfolg“ zurück. Sobald der Verschlüsselungsschlüssel jedoch deaktiviert ist, erhält der Anrufer eine Fehlermeldung.

Im nächsten Abschnitt erfahren Sie, was passiert, wenn Sie die Funktion aufrufen, nachdem der Schlüssel deaktiviert wurde.

8. CMEK-verschlüsselte Funktion erstellen (1. Generation)

In diesem Abschnitt erfahren Sie, wie Sie Funktionen der 1. Generation erstellen. Wenn Sie bereits eine Funktion der 2. Generation erstellt haben, fahren Sie mit dem nächsten Abschnitt fort.

Sie haben ein Artifact Registry-Repository mit aktiviertem CMEK konfiguriert und Cloud Functions Zugriff auf Ihren Schlüssel gewährt. Jetzt können Sie eine Funktion bereitstellen, die mit Ihrem CMEK-Schlüssel verschlüsselt ist.

Schritte für Funktionen der 1. Generation:

Quellcode für die Funktion der 1. Generation erstellen

In diesem Codelab wird Node.js zwar verwendet, Sie können aber jede unterstützte Laufzeit verwenden.

Erstellen Sie zuerst ein Verzeichnis und wechseln Sie dann in dieses Verzeichnis.

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

Erstellen Sie als Nächstes die Datei „package.json“.

touch package.json

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

Erstellen Sie dann die Quelldatei „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

Cloud Functions-Funktion der 1. Generation mit CMEK-Verschlüsselung bereitstellen

Hinweis:Im folgenden Beispiel wird gezeigt, wie eine Funktion mithilfe von Quellen aus dem aktuellen Verzeichnis bereitgestellt wird. Sie müssen sich im selben Verzeichnis wie der Quellcode Ihrer Funktion befinden.

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

Sie können den CMEK-Schlüssel in der resultierenden Ausgabe sehen, indem Sie diesen Befehl ausführen:

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

Funktion der 1. Generation testen

Sie können die Funktion mit curl testen:

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

curl $FUNCTION_URL

Das führt zu folgendem Ergebnis:

Hello World!

Solange der Verschlüsselungsschlüssel aktiviert ist, gibt die Funktion dem Aufrufer den Wert „Erfolg“ zurück. Sobald der Verschlüsselungsschlüssel jedoch deaktiviert ist, erhält der Anrufer eine Fehlermeldung.

Im nächsten Abschnitt erfahren Sie, was passiert, wenn Sie die Funktion aufrufen, nachdem der Schlüssel deaktiviert wurde.

9. Eine CMEK-verschlüsselte Funktion aufrufen, bei der der Verschlüsselungsschlüssel deaktiviert wurde

In diesem letzten Abschnitt machen Sie den Schlüssel ungültig und rufen die Funktion noch einmal auf, um den resultierenden Fehler zu sehen.

Verschlüsselungsschlüssel deaktivieren

Sie können diesen Befehl ausführen, um den Schlüssel zu deaktivieren. Da in diesem Codelab nur eine Version des Schlüssels erstellt wird, deaktivieren Sie Version 1.

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

Sie sollten dann die folgenden Informationen sehen:

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

Funktion mit einem deaktivierten Schlüssel aufrufen

curl die Funktion noch einmal.

curl $FUNCTION_URL

und Sie erhalten diesmal keine „Hello World“-Antwort.

In den Logs für die Cloud-Funktion sehen Sie

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

Versuch, Ressourcen aufzurufen, wenn der CMEK-Schlüssel deaktiviert ist

In diesem Abschnitt erfahren Sie, welche Ressourcen nicht mehr verfügbar sind, wenn der CMEK-Schlüssel deaktiviert ist:

  • Quellcode der Funktion
  • Container-Image, das aus Ihrem Quellcode erstellt wurde

Wenn Sie beispielsweise den Tab „Quelle“ für die Cloud-Funktion aufrufen, wird beim Abrufen des Archivs ein Fehler angezeigt. Sie erhalten eine ähnliche Fehlermeldung, wenn Sie versuchen, die ZIP-Datei mit dem Quellcode direkt in Cloud Storage aufzurufen.

ac3307bb05d30e19.png

Außerdem haben Sie keinen Zugriff auf das Container-Image für die Funktion aus Artifact Registry. Wenn Sie beispielsweise versuchen, dieses Container-Image in Cloud Run bereitzustellen, erhalten Sie die Fehlermeldung, dass das Image nicht gefunden wurde.

Eine vollständige Liste der verschlüsselten Ressourcen finden Sie in der CMEK-Funktionsdokumentation.

10. Glückwunsch

Glückwunsch, du hast das Codelab abgeschlossen.

Behandelte Themen

  • CMEK-Schlüssel für einen vorhandenen symmetrischen Schlüsselbund erstellen
  • Artifact Registry-Repository erstellen
  • CMEK für eine Cloud-Funktion konfigurieren

Weitere Informationen

Weitere Informationen zu Cloud Functions und CMEK finden Sie unter den folgenden Links: