Criar e conceder acesso a recursos confidenciais


Os colaboradores de dados precisam configurar os seguintes recursos para que os dados confidenciais sejam acessíveis a uma carga de trabalho:

Além disso, os colaboradores de dados precisam escolher onde os resultados da carga de trabalho do Confidential Space serão armazenados e se eles serão exclusivos para cada colaborador ou compartilhados. Por exemplo, é possível gerar o mesmo resultado em vários buckets do Cloud Storage pertencentes a cada colaborador de dados.

Armazenar seus dados criptografados

É possível usar qualquer serviço Google Cloud que armazene dados para hospedar seus dados confidenciais. Por exemplo, você pode usar um dos seguintes serviços:

Verifique se esses dados estão criptografados em repouso, usando recursos integrados ou algo como o Cloud Key Management Service (Cloud KMS).

Autorizar a carga de trabalho com um WIP

Um WIP é o mecanismo que o Confidential Space usa para permitir que uma carga de trabalho externa acesse e trabalhe com seus dados confidenciais como uma identidade federada. Uma identidade federada é uma entidade externa tratada como um principal no seu projeto. Isso permite conceder papéis do IAM a ela para dar acesso a recursos específicos ou personificar contas de serviço para fazer o mesmo.

Como colaborador de dados, você configura um provedor em um WIP que define as regras para entidades que se autenticam como uma identidade federada. Para o Confidential Space, você precisa definir o seguinte em um provedor:

  • Um serviço de atestado: esse serviço verifica se a carga de trabalho é uma instância de VM confidencial e, por fim, retorna um token de atestado do OpenID Connect (OIDC) ao provedor de WIP. O operador de carga de trabalho define o serviço de atestado usado, que precisa corresponder ao serviço de atestado adicionado ao provedor WIP para que o acesso seja concedido.

  • Mapeamentos de atributos: atributos nos tokens de acesso do Security Token Service que são mapeados para declarações feitas pela entidade de autenticação. Nesse caso, a instância de VM que está executando a carga de trabalho. As declarações são feitas pela própria instância de VM, pela imagem do Confidential Space e pelo contêiner de carga de trabalho, e são transmitidas ao provedor WIP pela carga de trabalho. Esses atributos são usados para coisas como trilhas de auditoria no Cloud Logging e para conceder papéis pelo IAM com base na autenticação de declarações de entidades, como resumos de contêineres de imagens de carga de trabalho. Leia mais sobre mapeamentos de atributos.

  • Uma política de comprovação: uma série de condições que as entidades de autenticação precisam atender para ter acesso, com base nas declarações feitas.

Quando uma carga de trabalho é iniciada, o inicializador do Confidential Space envia o relatório de atestado para um serviço de atestado definido pelo operador da carga de trabalho, que verifica a instância da VM confidencial e retorna um token de atestado OIDC. Esse token dura uma hora e é atualizado automaticamente.

Em seguida, o token de atestado é transmitido ao provedor de WIP pela carga de trabalho, e o provedor o usa para verificar se as declarações atendem à política de atestado definida no provedor. Se sim, a carga de trabalho terá acesso aos recursos confidenciais.

Acesso a cargas de trabalho externas

Antes de configurar um WIP e um provedor, escolha como a carga de trabalho vai acessar seus recursos: acesso direto a recursos ou representação de conta de serviço.

Acesso direto a recursos

Recomendamos o método de acesso direto a recursos para cargas de trabalho.

Esse método envolve a configuração de uma identidade federada em um provedor WIP vinculada às declarações de uma entidade autenticadora. Assim, uma carga de trabalho pode ser autorizada a acessar recursos diretamente por vinculações do IAM, com base em atributos como o resumo da imagem do contêiner da carga de trabalho.

O acesso direto a recursos tem as seguintes vantagens:

  • Configurar um ambiente do Confidential Space leva menos etapas, já que os colaboradores de dados não precisam configurar contas de serviço para uma conta de serviço de carga de trabalho personificar.

  • A carga de trabalho só pode acessar recursos específicos, conforme determinado pelo IAM. Isso é mais seguro do que o método de representação de conta de serviço, em que contas de serviço com permissões excessivas ou direitos de representação podem dar a um usuário mal-intencionado mais acesso do que o pretendido.

  • Cada acesso a recursos é registrado com a identidade federada de uma instância de VM de carga de trabalho, em vez da identidade de uma conta de serviço representada que pode ser compartilhada por várias cargas de trabalho. A identidade de uma instância de VM de carga de trabalho pode incluir detalhes como o resumo da imagem de um contêiner, o número do projeto em que a carga de trabalho está operando e o ID da instância de VM que executa a carga de trabalho, fornecendo uma trilha de auditoria mais detalhada.

  • Não é necessário mapear a propriedade da instância de VM selfLink para o atributo google.subject em um provedor de WIP. Valores selfLink muito longos podem exceder o limite de 127 bytes desse atributo, causando falha na autenticação do provedor WIP.

Representação da conta de serviço:

O método de representação da conta de serviço envolve cada colaborador de dados configurando uma conta de serviço para descriptografar os dados particulares e anexando essa conta de serviço ao próprio WIP. Eles também especificam a conta de serviço da carga de trabalho no provedor WIP, o que permite que ela use uma identidade temporária das contas de serviço dos colaboradores de dados para recuperar e operar os dados confidenciais.

A representação de conta de serviço só deve ser usada nos seguintes cenários:

O método de personificação da conta de serviço pode não autenticar um provedor WIP se uma instância de VM tiver uma propriedade selfLink muito longa. Isso acontece porque a declaração sub no token de atestado, que é definida como o valor selfLink, é mapeada no provedor WIP para o atributo google.subject, que tem um limite de 127 bytes.

Para valores de selfLink da instância de VM que excedam 127 bytes, renomeie as instâncias de VM para encurtar o selfLink ou use o método de acesso direto a recursos.

Configurar um WIP e um provedor

As etapas para configurar um provedor variam dependendo se você usa acesso direto a recursos ou representação de conta de serviço.

Acesso direto a recursos

O método de acesso direto a recursos envolve a configuração de um WIP e um provedor e, em seguida, a configuração de papéis do IAM com base em um resumo específico da imagem do contêiner de carga de trabalho.

Configurar um WIP e um provedor

Para configurar um WIP e um provedor, siga estas instruções:

  1. Crie o WIP:

    gcloud iam workload-identity-pools create DATA_COLLABORATOR_POOL_NAME \
        --location=global
    
  2. Crie um provedor OIDC no WIP:

    gcloud iam workload-identity-pools providers create-oidc attestation-verifier \
        --location=global \
        --workload-identity-pool=DATA_COLLABORATOR_POOL_NAME \
        --issuer-uri="https://confidentialcomputing.googleapis.com/" \
        --allowed-audiences="https://sts.googleapis.com" \
        --attribute-mapping="google.subject=\"gcpcs::\"+assertion.submods.container.image_digest+\"::\"+assertion.submods.gce.project_number+\"::\"+assertion.submods.gce.instance_id,attribute.image_digest=assertion.submods.container.image_digest" \
        --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' \
            && 'STABLE' in assertion.submods.confidential_space.support_attributes"
    

    Este exemplo usa os seguintes valores:

    • Um issuer-uri de https://confidentialcomputing.googleapis.com/, o que significa que o atestado do Google Cloud é usado como o serviço de atestado.

    • Um allowed-audiences de https://sts.googleapis.com. Esse é o Security Token Service do Google, que troca credenciais por tokens de acesso.

    • Um attribute-mapping de google.subject, com o seguinte valor:

      \"gcpcs::\"+assertion.submods.container.image_digest+\"::\"+assertion.submods.gce.project_number+\"::\"+assertion.submods.gce.instance_id,attribute.image_digest=assertion.submods.container.image_digest
      

      Esse valor é construído usando a Common Expression Language (CEL). Os valores a seguir são atribuídos ao atributo gcpcs e aparecem no Cloud Logging sempre que a carga de trabalho acessa recursos:

      • assertion.submods.container.image_digest: o resumo da imagem do contêiner da carga de trabalho.

      • assertion.submods.gce.project_number: o número do projeto da instância de VM.

      • assertion.submods.gce.instance_id: o ID da instância de VM.

      Além disso, attribute.image_digest é definido como assertion.submods.container.image_digest, o resumo da imagem do contêiner da carga de trabalho. Esse atributo é mapeado para que você possa conceder papéis do IAM à identidade federada com base em um resumo de imagem específico.

      É possível mapear qualquer uma das asserções de carga de trabalho disponíveis, desde que o comprimento total do valor google.subject seja menor que 127 bytes.

    • Os seguintes attribute-conditions, que formam uma política de atestado. Se essas condições corresponderem às declarações da carga de trabalho, ela poderá acessar os recursos confidenciais como uma identidade federada:

      • assertion.swname == 'CONFIDENTIAL_SPACE': verifica se o Confidential Space é o software em execução na VM, com todas as garantias de segurança integradas.

      • 'STABLE' in assertion.submods.confidential_space.support_attributes: Verifica se a imagem de produção do Confidential Space está sendo usada e tem o atributo de suporte STABLE.

      Para mais condições de atributo que podem ser usadas, consulte Criar uma política de atestado.

Conceder papéis do IAM à identidade federada

Depois de criar um provedor de WIP, é possível conceder à identidade federada um papel do IAM com base em se o resumo do contêiner da imagem da carga de trabalho da identidade corresponde a um valor esperado.

O exemplo a seguir demonstra como conceder a uma identidade federada a capacidade de descriptografar uma chave específica do Cloud Key Management Service:

gcloud kms keys add-iam-policy-binding \
    projects/DATA_COLLABORATOR_PROJECT_ID/locations/global/keyRings/DATA_COLLABORATOR_KEYRING_NAME/cryptoKeys/DATA_COLLABORATOR_KEY_NAME \
    --member="principalSet://iam.googleapis.com/projects/DATA_COLLABORATOR_PROJECT_NUMBER/locations/global/workloadIdentityPools/DATA_COLLABORATOR_POOL_NAME/attribute.image_digest/WORKLOAD_CONTAINER_IMAGE_DIGEST" \
    --role=roles/cloudkms.cryptoKeyDecrypter

Representação da conta de serviço:

O método de representação de conta de serviço envolve o seguinte:

  1. Criar contas de serviço em cada um dos projetos de colaborador de dados e conceder permissão para descriptografar os dados confidenciais.

  2. Criar WIPs em cada um dos projetos de colaborador de dados e anexar a conta de serviço de cada projeto que acabou de ser criada ao respectivo WIP.

  3. Criar provedores de WIP em cada WIP, que especificam a conta de serviço da carga de trabalho como a conta que pode representar as contas de serviço do colaborador de dados.

Configurar contas de serviço para descriptografar dados confidenciais

  1. Crie as contas de serviço nos projetos do colaborador de dados:

    gcloud iam service-accounts create DATA_COLLABORATOR_SERVICE_ACCOUNT_NAME
    

    Conceda às contas de serviço as permissões necessárias para descriptografar os dados confidenciais. Por exemplo, é possível criptografar arquivos confidenciais no Cloud Storage com o Cloud KMS. Portanto, é necessário conceder à conta de serviço permissão para descriptografar esses dados:

    gcloud kms keys add-iam-policy-binding \
        projects/DATA_COLLABORATOR_PROJECT_ID/locations/global/keyRings/DATA_COLLABORATOR_KEYRING_NAME/cryptoKeys/DATA_COLLABORATOR_KEY_NAME \
        --member=serviceAccount:DATA_COLLABORATOR_SERVICE_ACCOUNT_NAME@DATA_COLLABORATOR_PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/cloudkms.cryptoKeyDecrypter
    

Configurar um WIP e um provedor

Para configurar um WIP e um provedor, siga estas instruções em cada projeto de colaborador de dados:

  1. Crie o WIP:

    gcloud iam workload-identity-pools create DATA_COLLABORATOR_POOL_NAME \
        --location=global
    
  2. Anexe a conta de serviço que será representada ao WIP, com o papel roles/iam.workloadIdentityUser:

    gcloud iam service-accounts add-iam-policy-binding \
        DATA_COLLABORATOR_SERVICE_ACCOUNT_NAME@DATA_COLLABORATOR_PROJECT_ID.iam.gserviceaccount.com \
        --member="principalSet://iam.googleapis.com/projects/DATA_COLLABORATOR_PROJECT_NUMBER/locations/global/workloadIdentityPools/DATA_COLLABORATOR_POOL_NAME/*" \
        --role=roles/iam.workloadIdentityUser
    
  3. Crie um provedor OIDC no WIP e defina a conta de serviço da carga de trabalho para que ela possa personificar a conta de serviço do colaborador de dados:

    gcloud iam workload-identity-pools providers create-oidc attestation-verifier \
        --location=global \
        --workload-identity-pool=DATA_COLLABORATOR_POOL_NAME \
        --issuer-uri="https://confidentialcomputing.googleapis.com/" \
        --allowed-audiences="https://sts.googleapis.com" \
        --attribute-mapping="google.subject=assertion.sub" \
        --attribute-condition="assertion.submods.container.image_digest == 'WORKLOAD_CONTAINER_IMAGE_DIGEST' \
    && 'WORKLOAD_SERVICE_ACCOUNT_NAME@WORKLOAD_OPERATOR_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts \
    && assertion.swname == 'CONFIDENTIAL_SPACE' \
    && 'STABLE' in assertion.submods.confidential_space.support_attributes"
    

    Este exemplo usa os seguintes valores:

    • Um issuer-uri de https://confidentialcomputing.googleapis.com/, o que significa que o atestado do Google Cloud é usado como o serviço de atestado.

    • Um allowed-audiences de https://sts.googleapis.com. Esse é o Security Token Service do Google, que troca credenciais por tokens de acesso.

    • Um attribute-mapping de google.subject, com o valor assertion.sub. Esse é o selfLink da instância de VM, conforme definido na declaração sub no token de comprovação.

      A instância de VM selfLink aparece no Cloud Logging sempre que a carga de trabalho acessa recursos.

    • Os seguintes attribute-conditions, que formam uma política de atestado. Se essas condições corresponderem às declarações da carga de trabalho, ela poderá acessar recursos como uma identidade federada:

      • assertion.submods.container.image_digest == 'WORKLOAD_CONTAINER_IMAGE_DIGEST': verifica se o resumo da imagem do contêiner da carga de trabalho corresponde ao valor esperado.

      • 'WORKLOAD_SERVICE_ACCOUNT_NAME@WORKLOAD_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts: verifica se a conta de serviço anexada à carga de trabalho corresponde à conta de serviço esperada e a usa para representar a conta de serviço do colaborador de dados.

      • assertion.swname == 'CONFIDENTIAL_SPACE': verifica se o Confidential Space é o software em execução na VM, com todas as garantias de segurança integradas.

      • 'STABLE' in assertion.submods.confidential_space.support_attributes: Verifica se a imagem de produção do Confidential Space está sendo usada e tem o atributo de suporte STABLE.

      Para mais condições de atributo que podem ser usadas, consulte Criar uma política de atestado.

Criar uma política de atestado

Como parte da criação de um WIP, é necessário criar uma política de atestado. As declarações de uma entidade autenticadora precisam corresponder à sua política para acessar seus dados.

As políticas são escritas em Common Expression Language (CEL) e são compostas por uma série de instruções que podem ser encadeadas com o operador &&.

As instruções usam asserções da imagem do Confidential Space, da imagem do contêiner de carga de trabalho ou da instância de VM como variáveis, e o valor especificado como a expressão. Por exemplo, confira uma política que exige que a carga de trabalho use o Confidential Space, uma imagem do Confidential Space STABLE e que a zona em que a instância de VM da carga de trabalho está sendo executada seja us-central1-a:

assertion.swname == 'CONFIDENTIAL_SPACE' \
&& 'STABLE' in assertion.submods.confidential_space.support_attributes" \
&& assertion.submods.gce.zone == "us-central1-a"

Consulte declarações de atestado para mais informações.

Declarações de atestado

As declarações disponíveis para criar uma política de atestado são detalhadas na tabela a seguir. As políticas podem validar declarações feitas pela imagem do Confidential Space, pelo contêiner de carga de trabalho e pela instância de VM.

Declarações de imagem

Declaração Tipo Descrição

assertion.dbgstat

Interage com:

String definida

Verifica se a imagem do Confidential Space é a versão de depuração ou de produção.

Os valores válidos são:

  • enable: verifique se a imagem de depuração está sendo usada.
  • disabled-since-boot: verifique se a imagem de produção está sendo usada.
Exemplos

O código a seguir verifica se a versão de depuração da imagem do Confidential Space está sendo usada:

assertion.dbgstat == "enable"

O código a seguir verifica se a versão de produção da imagem do Confidential Space está sendo usada:

assertion.dbgstat == "disabled-since-boot"
assertion.submods.confidential_space.support_attributes Matriz de strings

Verifica se a versão de segurança do TEE é uma imagem de produção do Confidential Space. As imagens de depuração do Confidential Space não têm um atributo de suporte definido.

Há três atributos de suporte:

  • LATEST: essa é a versão mais recente da imagem e é compatível. A imagem LATEST também é STABLE e USABLE.
  • STABLE: esta versão da imagem é compatível e monitorada em busca de vulnerabilidades. Uma imagem STABLE também é USABLE.
  • USABLE: uma imagem com apenas esse atributo não tem suporte e não é mais monitorada em busca de vulnerabilidades. Use por sua conta e risco.
  • EXPERIMENTAL: uma imagem com apenas esse atributo usa recursos de visualização. Ele é destinado apenas a testes e nunca deve ser usado na produção. Uma imagem EXPERIMENTAL nunca tem os atributos LATEST, STABLE ou USABLE.
Exemplo

O código a seguir verifica se uma versão estável da imagem do Confidential Space está sendo usada:

"STABLE" in assertion.submods.confidential_space.support_attributes
assertion.swname String definida

Verifica o software em execução na entidade de atestado. O valor é sempre CONFIDENTIAL_SPACE.

Exemplo
assertion.swname == "CONFIDENTIAL_SPACE"
assertion.swversion Matriz de strings

Verifica a versão do software da imagem do Confidential Space. Recomendamos usar assertion.submods.confidential_space.support_attributes para acessar a versão mais recente de uma imagem.

Exemplo
int(assertion.swversion[0]) == 230103

Declarações de contêiner

Declaração Tipo Descrição

assertion.submods.container.cmd_override

Interage com:

Matriz de strings

Verifica os comandos e parâmetros do CMD usados na imagem da carga de trabalho.

Exemplos

O código a seguir verifica se o CMD da imagem da carga de trabalho não foi substituído:

size(assertion.submods.container.cmd_override) == 0

O código a seguir verifica se program é o único conteúdo nas substituições do CMD:

assertion.submods.container.cmd_override == ['program']

assertion.submods.container.env

Interage com:

objeto JSON

Verifica se as variáveis de ambiente e os respectivos valores foram transmitidos explicitamente para o contêiner.

Exemplo

O código a seguir verifica se a variável de ambiente example-env-1 está definida como value-1 e example-env-2 está definida como value-2.

assertion.submods.container.env == {"example-env-1": "value-1", "example-env-2": "value-2"}

assertion.submods.container.env_override

Interage com:

String

Verifica se o operador de carga de trabalho substituiu as variáveis de ambiente no contêiner.

Exemplos

O código a seguir verifica se o operador de carga de trabalho não substituiu a variável de ambiente example:

!has(assertion.submods.container.env_override.example)

O código a seguir verifica se o operador de carga de trabalho não substituiu nenhuma variável de ambiente:

size(assertion.submods.container.env_override) == 0
assertion.submods.container.image_digest String

Verifica o resumo da imagem do contêiner da carga de trabalho. Especificar essa condição permite que várias partes concordem com uma carga de trabalho autorizada que tenha permissão para acessar os dados delas.

Exemplo
assertion.submods.container.image_digest == "sha256:837ccb607e312b170fac7383d7ccfd61fa5072793f19a25e75fbacb56539b86b"
assertion.submods.container.image_id String

Verifica o ID da imagem do contêiner da carga de trabalho.

Exemplo
assertion.submods.container.image_id == "sha256:652a44b0e911271ba07cf2915cd700fdfa50abd62a98f87a57fdebc59843d93f"

assertion.submods.container.image_reference

Interage com:

String

Verifica o local do contêiner da carga de trabalho em execução sobre a imagem do Confidential Space.

Exemplo
assertion.submods.container.image_reference == "us-docker.pkg.dev/PROJECT_ID/WORKLOAD_CONTAINER:latest"

assertion.submods.container.image_signatures

Interage com:

objeto JSON

Verifica se a imagem tem uma determinada assinatura ou se foi assinada por uma chave pública e um algoritmo de assinatura. Especificar essa condição permite que várias partes concordem com uma carga de trabalho autorizada que tenha permissão para acessar os dados delas.

A declaração pode incluir os seguintes elementos:

  • key_id: a impressão digital hexadecimal da chave pública. Para encontrar a impressão digital, execute o seguinte comando:

    openssl pkey -pubin -in public_key.pem -outform DER | openssl sha256

    Em que public_key.pem é sua chave pública no formato PEM.

  • signature: a assinatura em um payload associado ao contêiner assinado e que segue o formato de assinatura simples.
  • signature_algorithm: o algoritmo usado para assinar a chave. Opções:

    • RSASSA_PSS_SHA256 (RSASSA-PSS com um resumo SHA-256)
    • RSASSA_PKCS1V15_SHA256 (RSASSA-PKCS1 v1_5 com um resumo SHA-256)
    • ECDSA_P256_SHA256 (ECDSA na curva P-256 com um resumo SHA-256)
Exemplo
assertion.swname == 'CONFIDENTIAL_SPACE' && ['ECDSA_P256_SHA256:PUBLIC_KEY_FINGERPRINT'].exists(fingerprint, fingerprint in assertion.submods.container.image_signatures.map(sig, sig.signature_algorithm+':'+sig.key_id)) && 'serviceaccount.iam.gserviceaccount.com' in assertion.google_service_accounts"

assertion.submods.container.restart_policy

Interage com:

String definida

Verifica a política de reinicialização do inicializador do contêiner quando a carga de trabalho é interrompida.

Os valores válidos são:

  • Never (padrão)
  • Always
  • OnFailure
Exemplo
assertion.submods.container.restart_policy == "Never"

Declarações de VM

Declaração Tipo Descrição

assertion.google_service_accounts

Interage com:

Matriz de strings

Verifica se uma conta de serviço especificada está conectada à VM que está executando a carga de trabalho ou se foi listada usando tee-impersonate-service-accounts nos metadados da VM.

Exemplo
workload-service-account@my-project.iam.gserviceaccount.com in assertion.google_service_accounts
assertion.hwmodel String

Verifica a tecnologia de Computação confidencial subjacente. As plataformas compatíveis são as seguintes:

  • GCP_AMD_SEV
  • INTEL_TDX
Exemplo
assertion.hwmodel == "GCP_AMD_SEV"

assertion.submods.confidential_space.monitoring_enabled

Interage com:

Booleano

Verifica o estado de monitoramento na entidade de atestado.

Exemplo
assertion.submods.confidential_space.monitoring_enabled.memory == true
assertion.submods.gce.instance_id String

Verifica o ID da instância de VM.

Exemplo
assertion.submods.gce.instance_id == "0000000000000000000"
assertion.submods.gce.instance_name String

Verifica o nome da instância de VM.

Exemplo
assertion.submods.gce.instance_name == "workload-vm"
assertion.submods.gce.project_id String

Verifica se a VM está executando um projeto Google Cloud com o ID do projeto especificado.

Exemplo
assertion.submods.gce.project_id == "project-id"
assertion.submods.gce.project_number String

Verifica se a VM está em execução em um projeto Google Cloud com o número de projeto especificado.

Exemplo
assertion.submods.gce.project_number == "00000000000"

assertion.submods.gce.zone

Interage com:

  • Operador de carga de trabalho: o valor --zone .
String

Verifica se a VM está em execução na zona especificada.

Exemplo
assertion.submods.gce.zone == "us-central1-a"

assertion.submods.nvidia_gpu.cc_mode

Interage com:

String definida

Verifica o status do driver de computação confidencial da NVIDIA. Os valores válidos são:

  • OFF: nenhum dos recursos de computação confidencial da NVIDIA está ativo.
  • ON: o hardware, o firmware e o software da NVIDIA H100 ativaram totalmente os recursos de computação confidencial.
  • DEVTOOLS: a GPU está em um modo de computação confidencial parcial que corresponde aos fluxos de trabalho do modo ON, mas desativa as proteções de segurança.
Exemplo
assertion.submods.nvidia_gpu.cc_mode == "ON"