Crittografia di Cloud Functions utilizzando chiavi di crittografia gestite dal cliente (CMEK)

1. Introduzione

Panoramica

Cloud Functions è una soluzione di calcolo leggera che consente agli sviluppatori di creare funzioni autonome a uso specifico, che rispondano a eventi Cloud senza la necessità di gestire un ambiente server o di runtime.

Puoi utilizzare le chiavi di crittografia gestite dal cliente (CMEK) di Cloud Key Management Service per proteggere Cloud Functions e i relativi dati at-rest. Il deployment di una funzione con una CMEK protegge i dati associati utilizzando una chiave di crittografia che è sotto il tuo pieno controllo. Questo tipo di crittografia ti consente di soddisfare i requisiti di conformità in determinati settori, come i servizi finanziari. Poiché la chiave è di tua proprietà e non è controllata da Google, nessuno (neanche tu) può accedere ai dati protetti da queste chiavi di crittografia quando le chiavi vengono disattivate o eliminate.

Per Cloud Functions, CMEK cripta quanto segue:

  • Codice sorgente della funzione caricato per il deployment e archiviato da Google in Cloud Storage, utilizzato nel processo di compilazione.
  • I risultati del processo di compilazione della funzione, inclusa l'immagine container creata dal codice sorgente della funzione, ogni istanza della funzione di cui è stato eseguito il deployment.
  • Dati at-rest per i canali di trasporto degli eventi interni (solo 1ª gen.).

Per ulteriori informazioni sui dati criptati, consulta la documentazione di CMEK di Cloud Functions.

Cosa creerai

Questo codelab mostra come eseguire il deployment di una Cloud Function (di 1ª o 2ª gen.) criptata utilizzando CMEK. Questo codelab utilizza una Cloud Function pubblica, ovvero una che non richiede l'autenticazione, a scopo dimostrativo. Puoi richiamare una funzione autenticata abilitata a CMEK proprio come qualsiasi altra Funzione Cloud che richiede l'autenticazione.

Obiettivi didattici

  • Come creare una chiave CMEK su un portachiavi simmetrico esistente
  • Come creare un repository Artifact Registry
  • Come configurare CMEK su una funzione Cloud Functions per la 1ª e la 2ª gen.

2. Configurazione e requisiti

Prerequisiti

  • Hai eseguito l'accesso a Cloud Console
  • Hai eseguito il deployment di una Cloud Function attivata da HTTP (per verificare di disporre dei ruoli e delle API appropriati abilitati)

Attiva Cloud Shell

  1. Nella console Cloud, fai clic su Attiva Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Se è la prima volta che avvii Cloud Shell, viene visualizzata una schermata intermedia che ne descrive le funzionalità. Se è stata visualizzata una schermata intermedia, fai clic su Continua.

9c92662c6a846a5c.png

Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.

9f0e51b578fecce5.png

Questa macchina virtuale è caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Gran parte del lavoro per questo codelab, se non tutto, può essere svolto con un browser.

Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è autenticato e il progetto è impostato sul tuo ID progetto.

  1. Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list

Output comando

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Esegui questo comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto:
gcloud config list project

Output comando

[core]
project = <PROJECT_ID>

In caso contrario, puoi impostarlo con questo comando:

gcloud config set project <PROJECT_ID>

Output comando

Updated property [core/project].

3. Crea un nuovo portachiavi e una nuova chiave per Cloud Functions

Assicurati che l'API Cloud KMS sia abilitata eseguendo il seguente comando:

gcloud services enable cloudkms.googleapis.com

Innanzitutto, crea variabili di ambiente per contenere il nome del keyring, il nome della chiave, la regione e altre variabili utilizzate in questo codelab.

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

Poi crea un keyring, che è la risorsa radice per le chiavi e le versioni delle chiavi Cloud KMS.

gcloud kms keyrings create $KEYRING_NAME --location $REGION

Infine, ora puoi creare una chiave simmetrica nel nuovo keyring in Cloud KMS.

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

4. Crea un repository Artifact Registry in formato Docker abilitato a CMEK

In questa sezione creerai un repository in formato Docker in Artifact Registry con CMEK abilitata. Questa chiave sarà la stessa utilizzata per il deployment della funzione Cloud Functions.

Per prima cosa, devi avere l'account di servizio per Artifact Registry. Puoi crearlo eseguendo questo comando:

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

Utilizza il seguente comando per concedere il ruolo IAM Autore crittografia/decrittografia CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter) al service account Artifact Registry per disporre delle autorizzazioni per la chiave:

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

e concedi il ruolo all'entità che creerà il repository in Artifact Registry, ad esempio il tuo account attivo attuale. Puoi verificare l'account attivo corrente eseguendo 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

Ora puoi creare un repository in formato Docker abilitato per CMEK.

Nota:la regione deve essere la stessa della chiave 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

Puoi visualizzare il nuovo repository Artifact Registry eseguendo questo comando:

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

5. Concedi l'accesso alla chiave ai service account (2ª gen.)

Questa sezione descrive la creazione di service account per le funzioni di 2ª gen. Se stai creando una funzione di 1ª gen., vai alla sezione successiva.

Devi concedere a diversi service agent l'accesso alla chiave assegnando il ruolo IAM Autore crittografia/decriptazione CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter). Questi service agent vengono utilizzati per ottenere l'accesso al codice sorgente archiviato in Cloud Storage, archiviare le immagini delle funzioni in un repository protetto da CMEK in Artifact Registry e per eseguire il deployment di una Cloud Function criptata con CMEK.

Passaggi per le funzioni di 2ª gen.

  1. Concedi al service agent Cloud Run l'accesso alla chiave:
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. Concedi all'agente di servizio Eventarc l'accesso alla chiave:
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. Concedi all'agente di servizio Artifact Registry l'accesso alla chiave:
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. Concedi agli agenti di servizio Cloud Storage l'accesso alla chiave:
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

Nella sezione successiva, vedrai come creare e implementare una funzione criptata con CMEK.

6. Concedi l'accesso alla chiave ai service account (1ª gen.)

Questa sezione descrive la creazione di service account per le funzioni di 1ª gen. Se hai già creato service account per una funzione di 2ª gen., vai alla sezione successiva.

Devi concedere a diversi service agent l'accesso alla chiave assegnando il ruolo IAM Autore crittografia/decriptazione CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter). Questi service agent vengono utilizzati per ottenere l'accesso al codice sorgente archiviato in Cloud Storage, archiviare le immagini delle funzioni in un repository protetto da CMEK in Artifact Registry e per eseguire il deployment di una Cloud Function criptata con CMEK.

Passaggi per le funzioni di 1ª gen.

  1. Concedi all'agente di servizio Cloud Functions l'accesso alla chiave:
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. Concedi all'agente di servizio Artifact Registry l'accesso alla chiave:
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. Concedi agli agenti di servizio Cloud Storage l'accesso alla chiave:
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

Nella sezione successiva, vedrai come creare e implementare una funzione criptata con CMEK.

7. Crea una funzione (2ª gen.) criptata con CMEK

Questa sezione descrive la creazione di funzioni di 2ª gen. Puoi procedere alla sezione successiva per le istruzioni relative alla 1ª gen.

Ora che hai configurato un repository Artifact Registry con CMEK abilitata e hai concesso l'accesso alla chiave a Cloud Functions, puoi eseguire il deployment di una funzione criptata utilizzando la chiave CMEK.

Passaggi per le funzioni di 2ª gen.:

Crea il codice sorgente per la funzione

Anche se questo codelab utilizza Node.js, puoi utilizzare qualsiasi runtime supportato.

Innanzitutto, crea una directory e accedi tramite cd.

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

Poi, crea il file package.json.

touch package.json

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

Poi, crea il file di origine 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

Esegui il deployment della funzione Cloud Functions (2ª gen.) utilizzando la crittografia CMEK

Nota:l'esempio seguente mostra come eseguire il deployment di una funzione utilizzando le origini della directory corrente. Assicurati di trovarti nella stessa directory del codice sorgente della funzione.

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

Puoi visualizzare la chiave CMEK dall'output risultante eseguendo questo comando

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

Testare la funzione di 2ª gen.

Puoi testare la funzione eseguendo il comando curl:

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

curl $FUNCTION_URL

che comporta quanto segue:

Hello World!

Finché la chiave di crittografia è abilitata, la funzione restituirà esito positivo al chiamante. Tuttavia, una volta disattivata la chiave di crittografia, il chiamante riceverà un errore.

Nella sezione successiva vedrai cosa succede quando richiami la funzione dopo che la chiave è stata disattivata.

8. Crea una funzione criptata con CMEK (1ª gen.)

Questa sezione descrive la creazione di funzioni di 1ª gen. Se hai già creato una funzione di 2ª gen., vai alla sezione successiva.

Ora che hai configurato un repository Artifact Registry con CMEK abilitata e hai concesso l'accesso alla chiave a Cloud Functions, puoi eseguire il deployment di una funzione criptata utilizzando la chiave CMEK.

Passaggi per Functions (1ª gen.):

Crea il codice sorgente per la funzione di 1ª gen.

Anche se questo codelab utilizza Node.js, puoi utilizzare qualsiasi runtime supportato.

Innanzitutto, crea una directory e accedi tramite cd.

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

Poi, crea il file package.json.

touch package.json

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

Poi, crea il file sorgente 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

Esegui il deployment della funzione Cloud Functions (1ª gen.) utilizzando la crittografia CMEK

Nota:l'esempio seguente mostra come eseguire il deployment di una funzione utilizzando le origini della directory corrente. Assicurati di trovarti nella stessa directory del codice sorgente della funzione.

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

Puoi visualizzare la chiave CMEK dall'output risultante eseguendo questo comando

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

Testa la funzione di 1ª gen.

Puoi testare la funzione eseguendo il comando curl:

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

curl $FUNCTION_URL

che comporta quanto segue:

Hello World!

Finché la chiave di crittografia è abilitata, la funzione restituirà esito positivo al chiamante. Tuttavia, una volta disattivata la chiave di crittografia, il chiamante riceverà un errore.

Nella sezione successiva vedrai cosa succede quando richiami la funzione dopo che la chiave è stata disattivata.

9. Richiamare una funzione criptata con CMEK in cui la chiave di crittografia è stata disattivata

In questa sezione finale, invaliderai la chiave e richiamerai di nuovo la funzione per visualizzare l'errore risultante.

Disattivare la chiave di crittografia

Puoi eseguire questo comando per disattivare la chiave. Poiché questo codelab crea una sola versione della chiave, disabiliterai la versione 1.

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

e dovresti vedere le informazioni risultanti:

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

Richiamare la funzione con un tasto disattivato

Ora curl di nuovo la funzione.

curl $FUNCTION_URL

e questa volta non riceverai una risposta Hello World.

Nei log della funzione Cloud, vedrai

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

Tentativo di visualizzare le risorse quando la chiave CMEK è disattivata

In questa sezione, vedrai le seguenti risorse diventare non disponibili quando la chiave CMEK viene disattivata:

  • Codice sorgente della funzione
  • Immagine container creata dal codice sorgente

Ad esempio, se visiti la scheda Origine per la funzione Cloud, viene visualizzato un errore durante il recupero dell'archivio. Riceverai un errore simile se tenti di visualizzare il file .zip contenente il codice sorgente direttamente in Cloud Storage.

ac3307bb05d30e19.png

Inoltre, non avrai accesso all'utilizzo dell'immagine container per la funzione da Artifact Registry. Ad esempio, se tenti di eseguire il deployment di questa immagine container su Cloud Run, riceverai un errore che indica che l'immagine non è stata trovata.

Per un elenco completo delle risorse criptate, consulta la documentazione sulle funzioni CMEK .

10. Complimenti

Congratulazioni, hai completato il codelab.

Argomenti trattati

  • Come creare una chiave CMEK su un portachiavi simmetrico esistente
  • Come creare un repository Artifact Registry
  • Come configurare CMEK in una funzione Cloud

Per ulteriori informazioni

Per saperne di più su Cloud Functions e CMEK, consulta i seguenti link: