1. Introducción
Descripción general
Cloud Functions es una solución de procesamiento ligera para que los desarrolladores creen funciones individuales y de un solo propósito que respondan a eventos de Cloud sin necesidad de administrar un servidor o un entorno de ejecución.
Puedes usar claves de encriptación administradas por el cliente (CMEK) de Cloud Key Management Service para proteger Cloud Functions y los datos en reposo relacionados. La implementación de una función con una CMEK protege los datos asociados con ella usando una clave de encriptación que está bajo tu control total. Este tipo de encriptación te permite cumplir con los requisitos de cumplimiento en ciertos sectores, como los servicios financieros. Debido a que la clave es de tu propiedad y Google no la controla, nadie, ni siquiera tú, puede acceder a los datos protegidos por estas claves de encriptación cuando se inhabilitan o destruyen.
En el caso de Cloud Functions, la CMEK encripta lo siguiente:
- Código fuente de la función subido para la implementación y almacenado por Google en Cloud Storage, que se usa en el proceso de compilación
- Los resultados del proceso de compilación de la función, incluida la imagen del contenedor compilada a partir del código fuente de la función y cada instancia de la función que se implementa
- Datos en reposo para canales de transporte de eventos internos (solo 1ª gen.).
Puedes encontrar más información sobre qué datos se encriptan en la documentación de CMEK de Cloud Functions.
Qué compilarás
En este codelab, se muestra cómo implementar una Cloud Function (de 1ª o 2ª gen.) encriptada con CMEK. En este codelab, se usa una Cloud Function pública, es decir, una que no requiere autenticación, para fines de demostración. Puedes invocar una función autenticada habilitada para CMEK como cualquier otra Cloud Function que requiera autenticación.
Qué aprenderás
- Cómo crear una clave de CMEK en un llavero de claves simétricas existente
- Cómo crear un repositorio de Artifact Registry
- Cómo configurar CMEK en una Cloud Function para la 1ª y la 2ª gen.
2. Configuración y requisitos
Requisitos previos
- Accediste a la consola de Cloud.
- Ya implementaste una función de Cloud Functions activada por HTTP (para verificar que tienes los roles y las APIs habilitados correspondientes).
Activar Cloud Shell
- En la consola de Cloud, haz clic en Activar Cloud Shell
.

Si es la primera vez que inicias Cloud Shell, aparecerá una pantalla intermedia en la que se describirá qué es. Si apareció una pantalla intermedia, haz clic en Continuar.

El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.

Esta máquina virtual está cargada con todas las herramientas de desarrollo necesarias. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer con un navegador.
Una vez que te conectes a Cloud Shell, deberías ver que te autenticaste y que el proyecto se configuró con tu ID del proyecto.
- En Cloud Shell, ejecuta el siguiente comando para confirmar que tienes la autenticación:
gcloud auth list
Resultado del comando
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- En Cloud Shell, ejecuta el siguiente comando para confirmar que el comando gcloud conoce tu proyecto:
gcloud config list project
Resultado del comando
[core] project = <PROJECT_ID>
De lo contrario, puedes configurarlo con el siguiente comando:
gcloud config set project <PROJECT_ID>
Resultado del comando
Updated property [core/project].
3. Crea un llavero de claves y una clave nuevos para Cloud Functions
Ejecuta el siguiente comando para asegurarte de que la API de Cloud KMS esté habilitada:
gcloud services enable cloudkms.googleapis.com
Primero, crea variables de entorno para que contengan el nombre del llavero de claves, el nombre de la clave, la región y otras variables que se usan en este 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)")"
A continuación, crea un llavero de claves, que es el recurso raíz para las claves y las versiones de claves de Cloud KMS.
gcloud kms keyrings create $KEYRING_NAME --location $REGION
Por último, ahora puedes crear una clave simétrica en tu nuevo llavero de claves dentro de Cloud KMS.
gcloud kms keys create $KEY_NAME --keyring $KEYRING_NAME --location $REGION --purpose "encryption"
4. Crea un repositorio de Artifact Registry con formato de Docker y habilitado para CMEK
En esta sección, crearás un repositorio con formato de Docker en Artifact Registry que tenga habilitada la CMEK. Esta será la misma clave que se usará para implementar tu Cloud Function.
Primero, necesitarás la cuenta de servicio de Artifact Registry. Para crearla, ejecuta este comando:
gcloud beta services identity create --service=artifactregistry.googleapis.com --project=$PROJECT_ID
Usa el siguiente comando para otorgar el rol de IAM de encriptador/desencriptador de CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter) a la cuenta de servicio de Artifact Registry para que tenga permisos para la clave:
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
Otorga el rol al principal que creará el repo en Artifact Registry, p.ej., tu cuenta activa actual. Para verificar tu cuenta activa actual, ejecuta 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
Ahora puedes crear un repo con formato de Docker que esté habilitado para CMEK.
Nota: La región debe ser la misma que la de la clave de 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
Para ver tu nuevo repositorio de Artifact Registry, ejecuta este comando:
gcloud artifacts repositories describe $REPO_NAME --location=$REGION
5. Otorga a las cuentas de servicio acceso a la clave (2ª gen.)
En esta sección, se explica cómo crear cuentas de servicio para funciones de 2ª gen. Si vas a crear una función de 1ª gen., continúa con la siguiente sección.
Debes otorgar a varios agentes de servicio acceso a la clave otorgando el rol de IAM de encriptador/desencriptador de CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter). Estos agentes de servicio se usan para obtener acceso al código fuente almacenado en Cloud Storage, almacenar imágenes de funciones en un repositorio protegido por CMEK en Artifact Registry y, también, para implementar una Cloud Function encriptada con CMEK.
Pasos para las funciones de 2ª gen.
- Otorga al agente de servicio de Cloud Run acceso a la clave:
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
- Otorga al agente de servicio de Eventarc acceso a la clave:
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
- Otorga al agente de servicio de Artifact Registry acceso a la clave:
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
- Otorga a los agentes de servicio de Cloud Storage acceso a la clave:
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
En la siguiente sección, verás cómo crear e implementar una función encriptada con CMEK.
6. Otorga a las cuentas de servicio acceso a la clave (1ª gen.)
En esta sección, se explica cómo crear cuentas de servicio para las funciones de 1ª gen. Si ya creaste cuentas de servicio para una función de 2ª gen., continúa con la siguiente sección.
Debes otorgar a varios agentes de servicio acceso a la clave otorgando el rol de IAM de encriptador/desencriptador de CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter). Estos agentes de servicio se usan para obtener acceso al código fuente almacenado en Cloud Storage, almacenar imágenes de funciones en un repositorio protegido por CMEK en Artifact Registry y, también, para implementar una Cloud Function encriptada con CMEK.
Pasos para las funciones de 1ª gen.
- Otorga al agente de servicio de Cloud Functions acceso a la clave:
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
- Otorga al agente de servicio de Artifact Registry acceso a la clave:
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
- Otorga a los agentes de servicio de Cloud Storage acceso a la clave:
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
En la siguiente sección, verás cómo crear e implementar una función encriptada con CMEK.
7. Crea una función (2ª gen.) encriptada con CMEK
En esta sección, se explica cómo crear funciones de 2ª gen. Puedes continuar con la siguiente sección para obtener instrucciones sobre la 1ª gen.
Ahora que tienes un repositorio de Artifact Registry configurado con CMEK habilitadas y otorgaste a Cloud Functions acceso a tu clave, puedes implementar una función encriptada con tu clave de CMEK.
Pasos para las funciones de 2ª gen.:
Crea el código fuente de la función
Aunque este codelab usa Node.js, puedes usar cualquier entorno de ejecución compatible.
Primero, crea un directorio y ábrelo con el comando cd.
mkdir ~/cmek-function-2ndgen && cd $_
Luego, crea el archivo package.json.
touch package.json
echo '{
"dependencies": {
"@google-cloud/functions-framework": "^2.1.0"
}
}
' > package.json
A continuación, crea el archivo fuente 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
Implementa la Cloud Function de 2ª gen. con encriptación CMEK
Nota: En el siguiente ejemplo, se muestra cómo implementar una función con fuentes de tu directorio actual. Asegúrate de estar en el mismo directorio que el código fuente de tu función.
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
Para ver la clave CMEK en el resultado, ejecuta este comando:
gcloud functions describe $FUNCTION_NAME –region $REGION | grep kmsKeyName
Prueba la función de 2ª gen.
Puedes probar tu función con curl:
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(serviceConfig.uri)')" curl $FUNCTION_URL
que genera el siguiente resultado:
Hello World!
Mientras la clave de encriptación esté habilitada, la función devolverá un mensaje de éxito al llamador. Sin embargo, una vez que se inhabilite la clave de encriptación, la persona que llama recibirá un error.
En la siguiente sección, verás qué sucede cuando invocas la función después de que se inhabilitó la clave.
8. Crea una función encriptada con CMEK (1ª gen.)
En esta sección, se explica cómo crear funciones de 1ª gen. Si ya creaste una función de 2ª gen., continúa con la siguiente sección.
Ahora que tienes un repositorio de Artifact Registry configurado con CMEK habilitadas y otorgaste a Cloud Functions acceso a tu clave, puedes implementar una función encriptada con tu clave de CMEK.
Pasos para las funciones de 1ª gen.:
Crea el código fuente para la función de 1ª gen.
Aunque este codelab usa Node.js, puedes usar cualquier entorno de ejecución compatible.
Primero, crea un directorio y ábrelo con el comando cd.
mkdir ~/cmek-function-1stgen && cd $_
A continuación, crea el archivo package.json.
touch package.json
echo '{
"name": "function-cmek-codelab",
"version": "0.0.1"
}' > package.json
Luego, crea el archivo fuente 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
Implementa la Cloud Function de 1ª gen. con encriptación CMEK
Nota: En el siguiente ejemplo, se muestra cómo implementar una función con fuentes de tu directorio actual. Asegúrate de estar en el mismo directorio que el código fuente de tu función.
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
Para ver la clave CMEK en el resultado, ejecuta este comando:
gcloud functions describe $FUNCTION_NAME –region $REGION | grep kmsKeyName
Prueba la función de 1ª gen.
Puedes probar tu función con curl:
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(httpsTrigger.url)')" curl $FUNCTION_URL
que genera el siguiente resultado:
Hello World!
Mientras la clave de encriptación esté habilitada, la función devolverá un mensaje de éxito al llamador. Sin embargo, una vez que se inhabilite la clave de encriptación, la persona que llama recibirá un error.
En la siguiente sección, verás qué sucede cuando invocas la función después de que se inhabilitó la clave.
9. Invoca una función encriptada con CMEK en la que se inhabilitó la clave de encriptación
En esta sección final, invalidarás la clave y volverás a invocar la función para ver el error resultante.
Inhabilita la clave de encriptación
Puedes ejecutar este comando para inhabilitar la clave. Como este codelab solo crea una versión de la clave, inhabilitarás la versión 1.
gcloud kms keys versions disable 1 \
--key=$KEY_NAME \
--keyring=$KEYRING_NAME \
--location=$REGION
y deberías ver la información resultante:
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
Invoca la función con una clave inhabilitada
Ahora, vuelve a curl la función.
curl $FUNCTION_URL
y no recibirás una respuesta de Hello World esta vez.
En los registros de Cloud Function, verás lo siguiente:
User's CMEK key has been disabled. CMEK key: projects/<PROJECT-NAME>/locations/us-central1/keyRings/myKeyRing/cryptoKeys/encrypted-function
Intenta ver recursos cuando la clave de CMEK está inhabilitada
En esta sección, verás que los siguientes recursos dejan de estar disponibles cuando se inhabilita la clave de CMEK:
- Código fuente de la función
- Imagen de contenedor compilada a partir de tu código fuente
Por ejemplo, si visitas la pestaña Fuente de la Cloud Function, se muestra un error al recuperar el archivo. Recibirás un error similar si intentas ver el archivo .zip que contiene el código fuente directamente en Cloud Storage.

Además, no tendrás acceso para usar la imagen de contenedor de la función desde Artifact Registry. Por ejemplo, si intentas implementar esa imagen de contenedor en Cloud Run, recibirás un error que indica que no se encontró la imagen.
Consulta la documentación de las funciones de CMEK para obtener una lista completa de los recursos encriptados.
10. Felicitaciones
¡Felicitaciones! Completaste el codelab.
Temas abordados
- Cómo crear una clave de CMEK en un llavero de claves simétricas existente
- Cómo crear un repositorio de Artifact Registry
- Cómo configurar CMEK en una Cloud Function
Más información
Puedes encontrar más información sobre Cloud Functions y la CMEK en los siguientes vínculos:
- Artículo Protección de Cloud Functions con CMEK
- Documentación sobre las claves de encriptación administradas por el cliente