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 in grado di rispondere agli eventi Cloud senza dover 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 in tuo pieno controllo. Questo tipo di crittografia consente di soddisfare i requisiti di conformità in determinati settori, ad esempio i servizi finanziari. Poiché la chiave è di tua proprietà e non è controllata da Google, nessuno (incluso te) può accedere ai dati protetti da queste chiavi di crittografia quando le chiavi vengono disabilitate 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 interni di trasporto degli eventi (solo 1a generazione).

Per saperne di più su quali dati vengono criptati, consulta la documentazione CMEK della funzione Cloud Functions.

Cosa creerai

Questo codelab mostra come eseguire il deployment di una funzione Cloud Functions (1a o 2a generazione) criptata tramite CMEK. A scopo dimostrativo, questo codelab utilizza una funzione Cloud Functions pubblica, ovvero che non richiede l'autenticazione. Puoi richiamare una funzione autenticata con CMEK come qualsiasi altra funzione Cloud Functions che richiede l'autenticazione.

Obiettivi didattici

  • Come creare una chiave CMEK su un keyring simmetrico esistente
  • Creare un repository Artifact Registry
  • Come configurare CMEK su una funzione Cloud Functions per la 1a e 2a generazione

2. Configurazione e requisiti

Prerequisiti

  • Hai eseguito l'accesso alla console Cloud
  • In precedenza hai eseguito il deployment di una funzione Cloud Functions attivata da HTTP (per verificare se hai abilitato i ruoli e le API appropriati).

Attiva Cloud Shell

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

55efc1aaa7a4d3ad.png

Se è la prima volta che avvii Cloud Shell, ti verrà mostrata una schermata intermedia che descrive di cosa si tratta. Se ti è stata presentata una schermata intermedia, fai clic su Continua.

9c92662c6a846a5c.png

Il provisioning e la connessione a Cloud Shell dovrebbero richiedere solo qualche istante.

9f0e51b578fecce5.png

Questa macchina virtuale viene 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 di rete e l'autenticazione. Gran parte, se non tutto, del lavoro in questo codelab può essere svolto con un browser.

Una volta stabilita la connessione a Cloud Shell, dovresti vedere che hai eseguito l'autenticazione e che 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 confermare che il comando gcloud è a conoscenza del 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 keyring e una nuova chiave per Cloud Functions

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

gcloud services enable cloudkms.googleapis.com

Per prima cosa, crea variabili di ambiente che contengano 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)")"

Successivamente, crea un keyring che funge da risorsa principale per le chiavi e le versioni delle chiavi di Cloud KMS.

gcloud kms keyrings create $KEYRING_NAME --location $REGION

Infine, ora puoi creare una chiave simmetrica nel nuovo keyring all'interno di 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 per CMEK

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

Innanzitutto, avrai bisogno dell'account di servizio per Artifact Registry. Per crearlo, esegui 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) all'account di servizio Artifact Registry per avere le 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

Concedi il ruolo al principio che creerà il repository in Artifact Registry, ad esempio il tuo account attuale. Puoi verificare il tuo 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 tuo nuovo repository Artifact Registry che esegue questo comando:

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

5. Concedi agli account di servizio l'accesso alla chiave (2a generazione)

Questa sezione illustra la creazione di account di servizio per le funzioni di 2a generazione. Se stai creando una funzione di 1a generazione, vai alla sezione successiva.

Per concedere l'accesso alla chiave a diversi agenti di servizio, devi concedere il ruolo IAM Autore crittografia/decrittografia CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter). Questi agenti di servizio 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 funzione Cloud Functions criptata con CMEK.

Passaggi per le funzioni di 2a generazione

  1. Concedi all'agente di servizio 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 scoprirai come creare una funzione criptata con CMEK ed eseguirne il deployment.

6. Concedi agli account di servizio l'accesso alla chiave (1a gen.)

Questa sezione illustra la creazione di account di servizio per le funzioni di 1a generazione. Se hai già creato degli account di servizio per una funzione di 2a generazione, vai alla sezione successiva.

Per concedere l'accesso alla chiave a diversi agenti di servizio, devi concedere il ruolo IAM Autore crittografia/decrittografia CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter). Questi agenti di servizio 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 funzione Cloud Functions criptata con CMEK.

Passaggi per funzioni di 1a generazione

  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 scoprirai come creare una funzione criptata con CMEK ed eseguirne il deployment.

7. Crea una funzione criptata con CMEK (2a generazione)

Questa sezione illustra la creazione di funzioni di 2a generazione. Puoi passare alla sezione successiva per istruzioni relative alla 1a generazione.

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

Passaggi per le funzioni di 2a generazione:

Crea il codice sorgente per la funzione

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

Per prima cosa, crea una directory e accedi a quella directory.

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

Quindi, crea il file package.json.

touch package.json

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

Quindi, 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 (2a gen.) utilizzando la crittografia CMEK

Nota: l'esempio seguente mostra come eseguire il deployment di una funzione utilizzando le origini della directory attuale. 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 vedere la chiave CMEK nell'output risultante eseguendo questo comando

le funzioni gcloud descrivono $FUNCTION_NAME –region $REGION | grep kmsKeyName

Testa la funzione di 2a generazione

Puoi testare la tua funzione tramite curl:

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

curl $FUNCTION_URL

con il risultato che:

Hello World!

Se la chiave di crittografia è abilitata, la funzione restituirà l'esito positivo al chiamante. Tuttavia, una volta disabilitata la chiave di crittografia, il chiamante riceverà un errore.

Nella sezione successiva scoprirai cosa succede quando richiami la funzione dopo che il tasto è stato disabilitato.

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

Questa sezione illustra la creazione di funzioni di 1a generazione. Se hai già creato una funzione di 2a generazione, vai alla sezione successiva.

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

Passaggi per le funzioni di 1a generazione:

Crea il codice sorgente per la funzione di 1a generazione

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

Per prima cosa, crea una directory e accedi a quella directory.

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

Quindi, crea il file package.json.

touch package.json

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

Quindi, crea il file di origine 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 (1a gen.) utilizzando la crittografia CMEK

Nota: l'esempio seguente mostra come eseguire il deployment di una funzione utilizzando le origini della directory attuale. 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 vedere la chiave CMEK nell'output risultante eseguendo questo comando

le funzioni gcloud descrivono $FUNCTION_NAME –region $REGION | grep kmsKeyName

Testa la funzione di 1a generazione

Puoi testare la tua funzione tramite curl:

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

curl $FUNCTION_URL

con il risultato che:

Hello World!

Se la chiave di crittografia è abilitata, la funzione restituirà l'esito positivo al chiamante. Tuttavia, una volta disabilitata la chiave di crittografia, il chiamante riceverà un errore.

Nella sezione successiva scoprirai cosa succede quando richiami la funzione dopo che il tasto è stato disabilitato.

9. Richiama una funzione criptata con CMEK in cui la chiave di crittografia è stata disabilitata

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

Disattiva la chiave di crittografia

Puoi eseguire questo comando per disabilitare la chiave. Poiché questo codelab crea solo una 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 seguenti informazioni:

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 Functions, 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 è disabilitata

In questa sezione vedrai le risorse seguenti che non sono più disponibili quando la chiave CMEK viene disabilitata:

  • Codice sorgente della funzione
  • Build dell'immagine container dal codice sorgente

Ad esempio, visitando la scheda Origine per la funzione Cloud Functions 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 dell'immagine container in Cloud Run, riceverai un errore che indica che l'immagine non è stata trovata.

Consulta la documentazione sulle funzioni CMEK per un elenco completo delle risorse criptate.

10. Complimenti

Complimenti, hai completato il codelab.

Argomenti trattati

  • Come creare una chiave CMEK su un keyring simmetrico esistente
  • Creare un repository Artifact Registry
  • Come configurare CMEK su una funzione Cloud Functions

Per ulteriori informazioni

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