Como ativar Chaves de criptografia gerenciadas pelo cliente (CMEK, na sigla em inglês)

Este tópico aborda o suporte para Chaves de criptografia gerenciadas pelo cliente (CMEK, na sigla em inglês) no Secret Manager.

Visão geral

O Secret Manager fornece ferramentas para armazenar, gerenciar e acessar dados confidenciais nos seus aplicativos.

Por padrão, os secrets armazenados no Secret Manager são criptografados com criptografia padrão do Google. A criptografia padrão do Google permite que os payloads de secrets sejam criptografados por chaves gerenciadas pelo Google antes de serem gravados no armazenamento permanente, sem a necessidade de configuração. A criptografia padrão do Google é a melhor escolha para muitas organizações.

Para organizações que querem ter mais controle, a compatibilidade do CMEK com o Secret Manager permite que você configure a chave do Cloud KMS que protege os dados em repouso no Secret Manager. Se você desativar ou destruir permanentemente a chave CMEK, os dados criptografados com essa chave não poderão ser descriptografados e, portanto, ficarão inacessíveis.

Como o CMEK funciona no Secret Manager

Antes de gravar uma versão do secret no armazenamento permanente em um determinado local, o Secret Manager criptografa os dados com uma chave de criptografia de dados (DEK) exclusiva. Essa DEK é criptografada com uma chave específica de réplica, chamada chave de criptografia de chaves (KEK) que pertence ao serviço Secret Manager.

Ao usar o CMEK para o Secret Manager, a KEK é chamada de chave CMEK, que é uma chave simétrica gerenciada no Cloud KMS. A chave CMEK precisa estar no mesmo local do GCP que a réplica da versão secreta que ela criptografa.

Este guia explica como configurar o Secret Manager para usar a CMEK. Para mais informações gerais sobre a CMEK, incluindo como quando e por que ativar, consulte a documentação do Cloud Key Management Service.

Limitações

O CMEK está disponível apenas na API Secret Manager v1 e gcloud.

Antes de começar

É possível armazenar todos os recursos no mesmo projeto ou armazenar secrets e chaves em projetos separados. Leia Separação de tarefas do Cloud KMS para entender melhor essa decisão.

Conclua os pré-requisitos a seguir para configurar o Secret Manager e o Cloud KMS:

  • Secret Manager:

    • Crie ou use um projeto atual para armazenar os recursos do Secret Manager.
    • Se necessário, conclua as etapas na seção Como configurar o Secret Manager do guia de início rápido do Secret Manager.
  • Cloud KMS:

    • Crie ou use um projeto atual para armazenar os recursos do Cloud KMS.
    • Se necessário, ative a API Cloud KMS.

Defina as variáveis a seguir para os IDs dos projetos do Secret Manager e do Cloud KMS.

Linha de comando

$ export SM_PROJECT_ID="..."
$ export KMS_PROJECT_ID="..."

Faça a autenticação no Google Cloud:

gcloud

$ gcloud auth login

Como criar uma conta de serviço

Você precisa criar uma conta de serviço para cada projeto que exige chaves de criptografia gerenciadas pelo cliente. No momento, só é possível usar comandos da ferramenta de linha de comando gcloud para criar o tipo de conta de serviço necessário para chaves de criptografia gerenciadas pelo cliente.

Para criar uma conta de serviço com a ferramenta de linha de comando gcloud, execute o seguinte comando:

gcloud

$ gcloud beta services identity create \
    --service "secretmanager.googleapis.com" \
    --project "${SM_PROJECT_ID}"

O comando anterior retorna um nome de conta de serviço usando o seguinte formato:

service-[PROJECT_NUMBER]@gcp-sa-secretmanager.iam.gserviceaccount.com

Você concederá a esta conta de serviço acesso às chaves CMEK do Cloud KMS usadas para criptografar e descriptografar seus secrets.

Salve o nome da conta de serviço como uma variável de ambiente:

Linha de comando

# This is from the output of the command above
$ export SM_SERVICE_ACCOUNT="service-...."

As variáveis de ambiente para o projeto do Secret Manager, o projeto do Cloud KMS e a conta de serviço do Secret Manager precisam ser definidas durante todo o procedimento que você está seguindo.

CMEK com replicação automática

Nesta seção, abordamos os secrets configurados por meio de uma política de replicação automática.

Para secrets que usem a política de replicação automática, sua chave CMEK precisa estar localizada na multirregião global do Cloud KMS.

Crie uma chave simétrica do Cloud KMS na região global do Cloud KMS ou use uma atual. Neste exemplo, criamos um novo keyring chamado secret-manager-cmek. Em seguida, é criada uma nova chave chamada my-cmek-key.

gcloud

$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "global"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

Consiga o nome do recurso da chave e defina-o como uma variável de ambiente.

Linha de comando

$ export KMS_KEY_NAME="projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"

Conceda à conta de serviço o acesso ao Secret Manager para criptografar e descriptografar usando a chave CMEK. Esse comando concede o papel de criptografador/descriptografador do Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) na chave my-cmek-key do Cloud KMS à conta de serviço.

gcloud

$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Crie um secret com replicação automática. O nome do recurso da chave CMEK é armazenado como metadados no secret.

gcloud

$ gcloud beta secrets create my-secret \
    --replication-policy "automatic" \
    --kms-key-name "${KMS_KEY_NAME}" \
    --project "${SM_PROJECT_ID}"

API

Defina o valor de replication.automatic.customerManagedEncryption.kmsKeyName como o nome do recurso da chave CMEK.

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets?secretId=my-secret" \
    --request "POST" \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --data-binary @- <<EOF
{
  "replication":{
    "automatic":{
      "customerManagedEncryption":{
        "kmsKeyName": "${KMS_KEY_NAME}"
      }
    }
  }
}
EOF

Agora, sempre que uma versão do secret é criada nesse secret, o payload dessa versão é automaticamente criptografado usando a chave antes de ser gravado no armazenamento permanente, desde que a conta de serviço tenha acesso à chave CMEK. Se a conta de serviço perder o acesso ou se a chave ficar indisponível, uma tentativa de criar uma nova versão do secret ou acessar uma versão atual retornará um erro.

Adicione uma nova versão do secret. Observe que você não precisa especificar o nome do recurso da chave do Cloud KMS. Ele é lido com base nos metadados do secret.

gcloud

$ echo -n "abcd1234" | gcloud beta secrets versions add "my-secret" \
    --project "${SM_PROJECT_ID}" \
    --data-file -

A versão do secret é criada mesmo que o autor da chamada não tenha acesso direto para usar a chave CMEK. A conta de serviço do Secret Manager, em vez do autor da chamada, é responsável por criptografar e descriptografar os secrets ao ler ou gravar.

Da mesma forma, você não precisa de acesso direto à chave CMEK para acessar o secret. A conta de serviço acessa a chave e criptografa ou descriptografa o nome em seu nome.

Acesse a versão do secret que você acabou de criar:

gcloud

$ gcloud beta secrets versions access latest \
    --project "${SM_PROJECT_ID}" \
    --secret "my-secret"

Como atualizar a configuração do CMEK

Crie novas chaves do KMS simétricas na multirregião global do Cloud KMS.

gcloud

$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

Conceda à conta de serviço acesso ao Secret Manager para criptografar e descriptografar usando a nova chave CMEK. Esse comando concede o papel de criptografador/descriptografador do Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) na chave my-other-key do Cloud KMS à conta de serviço.

gcloud

$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "global" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Para modificar a configuração do CMEK em um secret, atualize a replicação no secret com os novos nomes de recursos da chave do Cloud KMS.

gcloud

$ gcloud beta secrets replication update my-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication": {
    "automatic":{
      "customerManagedEncryption":{
        "kmsKeyName": "projects/${KMS_PROJECT_ID}/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
      }
    }
  }
}
EOF

CMEK com replicação gerenciada pelo usuário

Nesta seção, abordamos os secrets configurados com uma política de replicação gerenciada pelo usuário. Uma política de replicação gerenciada pelo usuário permite controlar o local do GCP em que o secret é armazenado. Os secrets estão sempre acessíveis em todos os locais do GCP.

Os secrets com uma política de replicação gerenciada pelo usuário precisam usar as chaves do Cloud KMS que mapeiam exatamente para os locais em que as versões do secret estão armazenadas. Este guia armazena uma chave secreta em dois locais separados: us-east1, us-central1. As solicitações de acesso ao secret são roteadas para um desses locais.

Em cada uma das duas regiões, crie um keyring e uma chave do Cloud KMS com a finalidade de criptografia ou use uma atual. Neste exemplo, você cria um novo keyring chamado secret-manager-cmek e, em seguida, cria uma chave chamada my-cmek-key em cada região.

gcloud

# us-east1
$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

# us-central1
$ gcloud kms keyrings create "secret-manager-cmek" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1"

$ gcloud kms keys create "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

Conceda à conta de serviço a permissão do Secret Manager para criptografar e descriptografar usando a chave CMEK. Para isso, conceda o papel de criptografador/descriptografador do Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) para cada chave CMEK individualmente ou para todas as chaves no projeto.

gcloud

# us-east1
$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

# us-central1
$ gcloud kms keys add-iam-policy-binding "my-cmek-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Crie um secret ativado para CMEK com replicação gerenciada pelo usuário. O nome do recurso da chave CMEK é armazenado como metadados no secret.

gcloud

$ cat <<EOF > replication-policy.json
{
  "userManaged":{
    "replicas":[
      {
        "location":"us-east1",
        "customerManagedEncryption":{
          "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
        }
      },
      {
        "location":"us-central1",
        "customerManagedEncryption":{
          "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
        }
      }
    ]
  }
}
EOF

$ gcloud beta secrets create my-ummr-secret \
    --replication-policy-file replication-policy.json \
    --project "${SM_PROJECT_ID}"

API

Defina o valor de replication.userManaged.replicas.customerManagedEncryption.kmsKeyName com os nomes dos recursos das chaves CMEK.

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets?secretId=my-ummr-secret" \
--request "POST" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @- <<EOF
{
  "replication":{
    "userManaged":{
      "replicas":[
        {
          "location":"us-east1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
          }
        },
        {
          "location":"us-central1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key"
          }
        }
      ]
    }
  }
}
EOF

Agora, sempre que uma versão do secret é criada nesse secret, o payload dessa versão é automaticamente criptografado usando a chave antes de ser gravado no armazenamento permanente, desde que a conta de serviço tenha acesso à chave CMEK. Se a conta de serviço perder o acesso ou se a chave ficar indisponível, uma tentativa de criar uma nova versão do secret ou acessar uma versão atual retornará um erro.

Adicione uma nova versão do secret. Observe que você não precisa especificar o nome do recurso da chave do Cloud KMS. Ele é lido com base nos metadados do secret.

gcloud

$ echo -n "abcd1234" | gcloud beta secrets versions add "my-ummr-secret" \
    --project "${SM_PROJECT_ID}" \
    --data-file -

A versão do secret é criada mesmo que o autor da chamada não tenha acesso direto para usar a chave CMEK. A conta de serviço do Secret Manager, em vez do autor da chamada, é responsável por criptografar e descriptografar os secrets ao ler ou gravar.

Da mesma forma, você não precisa de acesso direto à chave CMEK para acessar o secret. A conta de serviço acessa a chave e criptografa ou descriptografa o nome em seu nome.

Acesse a versão do secret que você acabou de criar.

gcloud

$ gcloud beta secrets versions access latest \
    --project "${SM_PROJECT_ID}" \
    --secret "my-ummr-secret"

Como atualizar a configuração do CMEK

Crie duas novas chaves do KMS simétricas nas mesmas regiões do secret.

gcloud

# us-east1
$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

# us-central1
$ gcloud kms keys create "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --purpose "encryption"

Conceda à conta de serviço o acesso ao Secret Manager para criptografar e descriptografar usando as novas chaves CMEK. Esse comando concede o papel de criptografador/descriptografador do Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) nas chaves my-other-key do Cloud KMS à conta de serviço.

gcloud

# us-east1
$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-east1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

# us-central1
$ gcloud kms keys add-iam-policy-binding "my-other-key" \
    --project "${KMS_PROJECT_ID}" \
    --location "us-central1" \
    --keyring "secret-manager-cmek" \
    --member "serviceAccount:${SM_SERVICE_ACCOUNT}" \
    --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Para modificar a configuração do CMEK em um secret, atualize a replicação no secret com os novos nomes de recursos da chave do Cloud KMS.

gcloud

$ gcloud beta secrets replication update my-ummr-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --location=us-east1 \
    --project "${SM_PROJECT_ID}"

$ gcloud beta secrets replication update my-ummr-secret \
    --set-kms-key="projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key" \
    --location=us-central1 \
    --project "${SM_PROJECT_ID}"

Para atualizar simultaneamente várias chaves em um secret, é possível receber e definir a política de replicação por meio de um arquivo.

gcloud

$ gcloud beta secrets replication get my-ummr-secret --project "${SM_PROJECT_ID}" --format=json > replication-policy.json

# update the file to reflect desired CMEK configuration
$ edit replication-policy json

$ gcloud beta secrets replication set my-ummr-secret \
    --replication-policy-file=replication-policy.json \
    --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-ummr-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication":{
    "userManaged":{
      "replicas":[
        {
          "location":"us-east1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-east1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
          }
        },
        {
          "location":"us-central1",
          "customerManagedEncryption":{
            "kmsKeyName":"projects/${KMS_PROJECT_ID}/locations/us-central1/keyRings/secret-manager-cmek/cryptoKeys/my-other-key"
          }
        }]
      }
    }
  }
EOF

Como visualizar a configuração do CMEK da versão do secret

Para inspecionar os metadados da versão do secret, incluindo se a versão do secret é ativada para CMEK e o nome do recurso da versão da chave CMEK, veja os metadados.

gcloud

$ gcloud beta secrets versions describe latest --secret my-secret --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret/versions/latest" \
    --request "GET" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json"

Isso retorna o nome completo do recurso do Cloud KMS da versão da chave usada para criptografar a versão do secret.

{
  "name": "projects/[PROJECT_NUMBER]/secrets/my-secret/versions/1",
  "createTime": "2020-07-...",
  "state": "ENABLED",
  "replicationStatus": {
    "automatic": {
      "customerManagedEncryption": {
        "kmsKeyVersionName": "projects/[KMS_PROJECT]/locations/global/keyRings/secret-manager-cmek/cryptoKeys/my-cmek-key/cryptoKeyVersions/1"
      }
    }
  }
}

Como desativar a CMEK

Atualize a política de replicação para remover a configuração de CMEK de um secret.

gcloud

$ gcloud beta secrets replication update my-secret --remove-cmek --project "${SM_PROJECT_ID}"

API

$ curl "https://secretmanager.googleapis.com/v1/projects/${SM_PROJECT_ID}/secrets/my-secret?updateMask=replication" \
    --request "PATCH" \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" \
    --header "Content-Type: application/json" \
    --data-binary @- <<EOF
{
  "replication":{
    "automatic":{}
  }
}
EOF

A seguir

  • Saiba mais sobre CMEK