Criptografar Cloud Functions usando chaves de criptografia gerenciadas pelo cliente (CMEK)

1. Introdução

Visão geral

O Cloud Functions é uma solução de computação leve para desenvolvedores. Ele cria funções autônomas e de finalidade única que respondem a eventos do Cloud sem a necessidade de gerenciar um servidor ou um ambiente de execução.

É possível usar chaves de criptografia gerenciadas pelo cliente (CMEK, na sigla em inglês) do Cloud Key Management Service para proteger o Cloud Functions e os dados relacionados em repouso. A implantação de uma função com uma CMEK protege os dados associados a ela usando uma chave de criptografia que está sob seu controle total. Esse tipo de criptografia permite atender a requisitos de conformidade em determinados setores, como serviços financeiros. Como a chave é de sua propriedade e não é controlada pelo Google, ninguém (incluindo você) pode acessar os dados protegidos por essas chaves de criptografia quando as chaves forem desativadas ou destruídas.

Para o Cloud Functions, a CMEK criptografa o seguinte:

  • Código-fonte da função enviado para implantação e armazenado pelo Google no Cloud Storage, usado no processo de build.
  • Os resultados do processo de compilação da função, incluindo a imagem do contêiner criada a partir do código-fonte da função, cada instância da função implantada.
  • Dados em repouso para canais internos de transporte de eventos (somente na 1ª geração).

Saiba mais sobre quais dados são criptografados na documentação da CMEK da função do Cloud.

O que você vai criar

Este codelab mostra como implantar uma função do Cloud (1a ou 2a geração) criptografada usando CMEK. Este codelab usa uma função pública do Cloud (que não requer autenticação) para fins de demonstração. Invoque uma função autenticada habilitada para CMEK, assim como qualquer outra função do Cloud que exija autenticação.

O que você vai aprender

  • Como criar uma chave CMEK em um keyring existente
  • Como criar um repositório do Artifact Registry
  • Como configurar CMEK em uma função do Cloud para 1a e 2a geração

2. Configuração e requisitos

Pré-requisitos

  • Você fez login no console do Cloud.
  • Você já implantou uma função do Cloud acionada por HTTP (para verificar se os papéis e as APIs apropriados estão ativados)

Ativar o Cloud Shell

  1. No Console do Cloud, clique em Ativar o Cloud Shell853e55310c205094.png.

55efc1aaa7a4d3ad.png

Se você estiver iniciando o Cloud Shell pela primeira vez, verá uma tela intermediária com a descrição dele. Se aparecer uma tela intermediária, clique em Continuar.

9c92662c6a846a5c.png

Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.

9f0e51b578fecce5.png

Essa máquina virtual tem todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Grande parte do trabalho neste codelab, se não todo, pode ser feito em um navegador.

Depois de se conectar ao Cloud Shell, você verá sua autenticação e o projeto estará configurado com o ID do seu projeto.

  1. Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:
gcloud auth list

Resposta ao comando

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Execute o seguinte comando no Cloud Shell para confirmar que o comando gcloud sabe sobre seu projeto:
gcloud config list project

Resposta ao comando

[core]
project = <PROJECT_ID>

Se o projeto não estiver configurado, configure-o usando este comando:

gcloud config set project <PROJECT_ID>

Resposta ao comando

Updated property [core/project].

3. Criar um keyring e uma chave para o Cloud Functions

Verifique se a API Cloud KMS está ativada executando o seguinte comando:

gcloud services enable cloudkms.googleapis.com

Primeiro, crie variáveis de ambiente para conter o nome do keyring, o nome da chave, a região e outras variáveis usadas neste 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)")"

Em seguida, crie um keyring, que é o recurso raiz das chaves e versões de chave do Cloud KMS.

gcloud kms keyrings create $KEYRING_NAME --location $REGION

Por fim, agora é possível criar uma chave simétrica no novo keyring no Cloud KMS.

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

4. Crie um repositório do Artifact Registry, formatado para CMEK, no Docker

Nesta seção, você vai criar um repositório formatado do Docker no Artifact Registry com a CMEK ativada. Essa chave será a mesma usada para implantar a função do Cloud.

Primeiro você precisa da conta de serviço do Artifact Registry. Para criá-la, execute este comando:

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

Use o comando a seguir para conceder o papel do IAM de criptografia/descriptografia do CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter) à conta de serviço do Artifact Registry para ter permissões na chave:

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 conceder o papel ao princípio que vai criar o repositório no Artifact Registry, por exemplo, sua conta ativa atual. Para verificar a conta ativa atual, execute o comando 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

Agora é possível criar um repositório formatado do Docker que seja ativado para CMEK.

Observação:a região precisa ser a mesma da chave 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 conferir seu novo repositório do Artifact Registry, execute este comando:

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

5. Conceder às contas de serviço acesso à chave (2a geração)

Nesta seção, abordamos a criação de contas de serviço para funções de 2a geração. Se você estiver criando uma função de 1a geração, prossiga para a próxima seção.

É preciso conceder a vários agentes de serviço acesso à chave concedendo o papel do IAM de criptografador/descriptografador de CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter). Esses agentes são usados para ter acesso ao código-fonte armazenado no Cloud Storage, armazenar imagens de funções em um repositório protegido por CMEK no Artifact Registry e implantar uma função do Cloud criptografada por CMEK.

Etapas para funções de 2a geração

  1. Conceda ao agente de serviço do Cloud Run acesso à chave:
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. Conceda ao agente de serviço do Eventarc acesso à chave:
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. Conceda ao agente de serviço do Artifact Registry acesso à chave:
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. Conceda aos agentes de serviço do Cloud Storage acesso à chave:
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

Na próxima seção, você vai aprender a criar e implantar uma função criptografada por CMEK.

6. Conceder às contas de serviço acesso à chave (1a geração)

Nesta seção, abordamos a criação de contas de serviço para funções de 1a geração. Se você já tiver criado contas de serviço para uma função de 2a geração, prossiga para a próxima seção.

É preciso conceder a vários agentes de serviço acesso à chave concedendo o papel do IAM de criptografador/descriptografador de CryptoKey (roles/cloudkms.cryptoKeyEncrypterDecrypter). Esses agentes são usados para ter acesso ao código-fonte armazenado no Cloud Storage, armazenar imagens de funções em um repositório protegido por CMEK no Artifact Registry e implantar uma função do Cloud criptografada por CMEK.

Etapas para funções de 1a geração

  1. Conceda ao agente de serviço do Cloud Functions acesso à chave:
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. Conceda ao agente de serviço do Artifact Registry acesso à chave:
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. Conceda aos agentes de serviço do Cloud Storage acesso à chave:
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

Na próxima seção, você vai aprender a criar e implantar uma função criptografada por CMEK.

7. Criar uma função criptografada por CMEK (2a geração)

Esta seção aborda a criação de funções de 2a geração. Siga para a próxima seção para conferir instruções de 1a geração.

Agora que você tem um repositório do Artifact Registry configurado com a CMEK ativada e concedeu ao Cloud Functions acesso à sua chave, é possível implantar uma função criptografada usando essa chave.

Etapas para funções de 2a geração:

Criar o código-fonte para a função

Embora este codelab use Node.js, você pode usar qualquer ambiente de execução com suporte.

Primeiro, crie um diretório e use cd nele.

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

Em seguida, crie o arquivo package.json.

touch package.json

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

Em seguida, crie o arquivo de origem 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

Implante a Função do Cloud de 2a geração usando a criptografia CMEK

Observação:o exemplo abaixo mostra como implantar uma função usando origens do diretório atual. Verifique se você está no mesmo diretório que o código-fonte da função.

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 conferir a chave CMEK na saída resultante, execute este comando:

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

Testar a função de 2a geração

Para testar a função, use o comando curl:

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

curl $FUNCTION_URL

o que resulta no seguinte:

Hello World!

Enquanto a chave de criptografia estiver ativada, a função retornará o sucesso para o autor da chamada. No entanto, quando a chave de criptografia é desativada, o autor da chamada recebe um erro.

Na próxima seção, você vai ver o que acontece quando a função é invocada depois que a chave é desativada.

8. Criar uma função criptografada por CMEK (1a geração)

Esta seção aborda a criação de funções de 1a geração. Se você já tiver criado uma função de 2a geração, prossiga para a próxima seção.

Agora que você tem um repositório do Artifact Registry configurado com a CMEK ativada e concedeu ao Cloud Functions acesso à sua chave, é possível implantar uma função criptografada usando essa chave.

Etapas para funções de 1a geração:

Criar o código-fonte da função de 1a geração

Embora este codelab use Node.js, você pode usar qualquer ambiente de execução com suporte.

Primeiro, crie um diretório e use cd nele.

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

Em seguida, crie o arquivo package.json.

touch package.json

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

Em seguida, crie o arquivo de origem 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

Implante a Função do Cloud de 1a geração usando a criptografia CMEK

Observação:o exemplo abaixo mostra como implantar uma função usando origens do diretório atual. Verifique se você está no mesmo diretório que o código-fonte da função.

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 conferir a chave CMEK na saída resultante, execute este comando:

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

Testar a função de 1a geração

Para testar a função, use o comando curl:

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

curl $FUNCTION_URL

o que resulta no seguinte:

Hello World!

Enquanto a chave de criptografia estiver ativada, a função retornará o sucesso para o autor da chamada. No entanto, quando a chave de criptografia é desativada, o autor da chamada recebe um erro.

Na próxima seção, você vai ver o que acontece quando a função é invocada depois que a chave é desativada.

9. Invocar uma função criptografada por CMEK em que a chave de criptografia foi desativada

Nesta seção final, você vai invalidar a chave e invocar a função novamente para conferir o erro resultante.

Desativar a chave de criptografia

Execute este comando para desativar a chave. Como este codelab cria apenas uma versão da chave, você vai desativar a versão 1.

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

As informações resultantes vão aparecer:

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

Invocar a função com uma chave desativada

Agora curl a função novamente.

curl $FUNCTION_URL

e não receberá uma resposta "Hello World".

Nos registros da função do Cloud,

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

Tentar visualizar recursos quando a chave CMEK está desativada

Nesta seção, os seguintes recursos ficarão indisponíveis quando a chave CMEK for desativada:

  • Código-fonte da função
  • Criação da imagem de contêiner a partir do seu código-fonte

Por exemplo, acessar a guia "Origem" da função do Cloud mostra um erro ao buscar o arquivo. Você receberá um erro semelhante se tentar visualizar o arquivo ZIP com o código-fonte diretamente no Cloud Storage.

ac3307bb05d30e19.png

Além disso, você não terá acesso para usar a imagem do contêiner para a função do Artifact Registry. Por exemplo, se você tentar implantar essa imagem de contêiner no Cloud Run, vai receber um erro informando que a imagem não foi encontrada.

Consulte a documentação das funções da CMEK para acessar uma lista completa de recursos criptografados.

10. Parabéns

Parabéns, você concluiu o codelab.

O que vimos

  • Como criar uma chave CMEK em um keyring existente
  • Como criar um repositório do Artifact Registry
  • Como configurar a CMEK em uma função do Cloud

Para mais informações

Confira mais informações sobre o Cloud Functions e a CMEK nos seguintes links: