Crie e personalize cargas de trabalho


Uma carga de trabalho é criada por um autor de cargas de trabalho e processa os dados confidenciais com os quais os colaboradores de dados querem trabalhar.

Um autor de carga de trabalho tem de reunir os seguintes recursos para criar uma carga de trabalho:

  • Uma aplicação para processar os dados confidenciais. Pode escrever a sua aplicação em qualquer idioma que escolher, desde que crie uma imagem em contentor que o suporte.

  • Uma imagem em contentor para criar o pacote da aplicação com o Docker.

  • Um repositório no Artifact Registry para armazenar a imagem do Docker.

  • As políticas de lançamento definidas na imagem do contentor controlam a forma como uma carga de trabalho pode ser executada e restringem a capacidade de um operador de carga de trabalho malicioso.

Para implementar a carga de trabalho, uma Confidential VM é executada por um operador de carga de trabalho com base na imagem do Confidential Space. Este comando obtém a imagem contentorizada do Artifact Registry e executa-a.

Os colaboradores de dados têm de validar as atestações de uma carga de trabalho antes de poderem aceder aos respetivos dados.

Antes de começar

Escrever uma carga de trabalho para o Confidential Space é mais do que apenas código e depuração. Também tem de falar com os colaboradores de dados para avaliar as respetivas necessidades, configurar o seu ambiente, agrupar o código numa imagem contentorizada e trabalhar com um operador de carga de trabalho para se certificar de que tudo é implementado corretamente.

Fale com os colaboradores de dados

Antes de começar a escrever a sua aplicação, tem de conversar com os seus colaboradores de dados sobre os dados privados com os quais quer trabalhar. Seguem-se algumas perguntas que pode fazer:

  • Quais são os IDs das organizações envolvidas?

  • Quais são os números dos projetos envolvidos?

  • Quais são os Google Cloud recursos aos quais preciso de aceder e quais são os respetivos IDs e nomes?

  • Existem recursos aos quais preciso de aceder que não são geridos pelo Google Cloud IAM?

  • Como deve a aplicação comparar e processar os dados privados?

  • Em que formato deve estar o resultado?

  • Onde deve ser armazenado o resultado e deve ser encriptado?

  • Todos os colaboradores de dados veem o mesmo resultado ou os resultados são únicos para cada um?

Além disso, cada colaborador de dados também pode ter requisitos de privacidade únicos que tem de cumprir. É fundamental que nenhum dado privado seja exposto como resultado de uma carga de trabalho.

Crie a sua solução de espaço confidencial

É útil configurar dois (ou mais) projetos com as autorizações adequadas como um ambiente de teste, como em Crie o seu primeiro ambiente do Confidential Space. Tente espelhar as configurações dos projetos dos colaboradores de dados da melhor forma possível. Isto permite-lhe ganhar experiência com autorizações entre projetos e obter os dados de que precisa de recursos Google Cloud específicos. Também pode dar-lhe uma ideia dos papéis de operador de carga de trabalho e colaborador de dados e das respetivas responsabilidades.

Durante a fase inicial de criação, é útil observar as seguintes práticas:

  • Quando trabalha como colaborador de dados, mantenha a validação da atestação ao mínimo para aumentar a velocidade de desenvolvimento.

  • Quando trabalhar como operador de carga de trabalho, use a imagem de depuração do espaço confidencial em vez da produção quando implementar a carga de trabalho. Isto dá-lhe mais formas de resolver problemas da carga de trabalho.

À medida que a sua aplicação amadurece e o respetivo estado se torna mais previsível, pode bloquear cada vez mais a sua solução com a validação de atestação e as políticas de lançamento, e mudar para a imagem do espaço confidencial de produção.

Depois de fazer com que a carga de trabalho funcione corretamente no ambiente de teste, pode mudar para os projetos dos colaboradores de dados com recursos reais, mas dados falsos, para poder demonstrar aos colaboradores de dados como tudo funciona. Neste momento, pode começar a trabalhar com um operador de carga de trabalho independente.

Quando tudo estiver a funcionar e o resultado for o esperado, pode começar a testar com dados de produção. Depois de os testes estarem concluídos e todas as partes aprovarem os resultados, a carga de trabalho está pronta para ser colocada em produção.

Tenha cuidado com a saída

Ao testar o código, pode ser tentador depurar imprimindo para STDOUT ou STDERR. Se optar por fazê-lo, tenha cuidado para não expor dados privados que outras partes possam ler acedendo aos registos. Antes de o código começar a funcionar em produção, certifique-se de que não produz nada além do estritamente necessário.

O mesmo se aplica ao resultado final. Apenas fornecer um resultado final que não comprometa a privacidade e a confidencialidade dos dados originais.

Crie uma imagem contentorizada com o Docker

As aplicações têm de ser comprimidas numa imagem contentorizada criada pelo Docker, que é armazenada no Artifact Registry. Quando uma carga de trabalho é implementada, a imagem do Docker é extraída do repositório do Artifact Registry pela imagem do espaço confidencial, executada e a aplicação pode começar a trabalhar nos recursos do projeto adequados.

Ao criar a sua imagem do Docker, tenha em conta o seguinte:

Capacidades adicionais do Linux

A carga de trabalho do Confidential Space é executada num contentor do Linux através do containerd. Este contentor é executado com as capacidades do Linux predefinidas.

Para adicionar capacidades, pode usar tee-added-capabilities.

Limites de disco e memória

O espaço confidencial redimensiona automaticamente a partição com estado do disco de arranque quando usa tamanhos de disco de arranque maiores. O tamanho da partição é aproximadamente o tamanho do disco de arranque menos 5 GB.

Como parte das proteções do sistema de ficheiros de integridade do espaço confidencial, o espaço confidencial armazena etiquetas de integridade do disco na memória. Isto usa aproximadamente 1% de sobrecarga de memória para cada byte de disco. Por exemplo, um disco de 100 GB requer 1 GB de memória e um disco de 10 TB requer 100 GB de memória.

Certifique-se de que se mantém dentro dos limites de memória da VM. A memória de troca está desativada nas VMs do espaço confidencial, o que significa que a utilização excessiva de memória pode falhar a carga de trabalho. Certifique-se de que a seleção da máquina suporta a utilização de memória da carga de trabalho, além da sobrecarga de integridade do disco.

Tokens OIDC expirados

É disponibilizado um token OIDC para o seu volume de trabalho consumir quando é iniciado. Contém declarações de atestação validadas sobre a VM da sua carga de trabalho e é armazenado no contentor da carga de trabalho em /run/container_launcher/attestation_verifier_claims_token. O token expira após 60 minutos.

Se o token expirar, é tentada uma atualização em segundo plano através da retirada exponencial até ter êxito. Se uma atualização falhar (devido a problemas de rede, uma interrupção do serviço de atestação ou outro motivo), o código da carga de trabalho tem de conseguir processar essa falha.

A sua carga de trabalho pode processar uma falha na atualização do token de uma das seguintes formas:

  • Ignore o token expirado, assumindo que já não é necessário após a utilização inicial.

  • Aguarde até que o token expirado seja atualizado com êxito.

  • Saia da carga de trabalho.

Montagens de riscos na memória

O espaço confidencial suporta a adição de espaços temporários na memória. Isto usa a memória disponível na VM do espaço confidencial. Uma vez que o espaço de trabalho usa a memória da VM confidencial, tem as mesmas propriedades de integridade e confidencialidade que a VM confidencial.

Pode usar tee-dev-shm-size para aumentar o tamanho da montagem da memória partilhada /dev/shm para a carga de trabalho. O tamanho /dev/shm é especificado em KB.

Pode usar tee-mount para especificar montagens tmpfs no contentor em execução através de configurações separadas por ponto e vírgula. As apps type e source estão sempre tmpfs. O destination é o ponto de montagem que interage com a política de lançamento tee.launch_policy.allow_mount_destinations. Opcionalmente, pode especificar o tmpfstamanho em bytes. O tamanho predefinido é 50% da memória da VM.

Portas de entrada

Por predefinição, as VMs do espaço confidencial funcionam com uma regra de firewall para bloquear todas as portas de entrada. Quando usar uma versão de imagem do espaço confidencial 230600 ou superior, pode especificar portas de entrada a manter abertas no Dockerfile ao criar a imagem da carga de trabalho.

Para abrir portas, adicione a palavra-chave EXPOSE ao seu Dockerfile, juntamente com o número da porta a manter aberta e um protocolo opcional de tcp ou udp. Se não especificar o protocolo para uma porta, são permitidos TCP e UDP. Segue-se um exemplo Dockerfile que expõe portas de entrada:

FROM alpine:latest
EXPOSE 80
EXPOSE 443/tcp
EXPOSE 81/udp
WORKDIR /test
COPY salary /test
ENTRYPOINT ["/test/salary"]
CMD []

Consoante a imagem base que usar, algumas portas podem já estar expostas. O seu Dockerfile expõe apenas portas adicionais. Não pode bloquear portas que já tenham sido abertas pela imagem base.

Os operadores de cargas de trabalho devem certificar-se de que as portas expostas estão abertas na respetiva firewall de VPC antes de executar a carga de trabalho. Os números de porta podem ser fornecidos pelo autor da carga de trabalho ou extraídos das informações da imagem do Docker.

As portas expostas são registadas na consola e são redirecionadas para o Cloud Logging quando usa a variável de metadados tee-container-log-redirect.

Políticas de lançamento

As políticas de lançamento substituem as variáveis de metadados da VM definidas pelos operadores de cargas de trabalho para restringir ações maliciosas. Um autor de carga de trabalho pode definir políticas com uma etiqueta como parte da criação da respetiva imagem do contentor.

Por exemplo, num Dockerfile:

LABEL "tee.launch_policy.allow_cmd_override"="true"

Num ficheiro BUILD do Bazel:

container_image(
    ...
    labels={"tee.launch_policy.allow_cmd_override":"true"}
    ...
)

As políticas de lançamento disponíveis estão na tabela seguinte:

Política Tipo Descrição

tee.launch_policy.allow_capabilities

Interage com:

Booleano (a predefinição é false) Determina se o operador da carga de trabalho pode adicionar capacidades do Linux adicionais ao contentor da carga de trabalho.

tee.launch_policy.allow_cgroups

Interage com:

  • Operador de carga de trabalho: a variável de metadados tee-cgroup-ns.
Booleano (a predefinição é false) Determina se o contentor de carga de trabalho pode incluir uma montagem de cgroup com espaço de nomes em /sys/fs/cgroup.

tee.launch_policy.allow_cmd_override

Interage com:

Booleano (a predefinição é false) Determina se o CMD especificado no Dockerfile do contentor de carga de trabalho pode ser substituído por um operador de carga de trabalho com o valor de metadados tee-cmd.

tee.launch_policy.allow_env_override

Interage com:

String separada por vírgulas Uma string separada por vírgulas de nomes de variáveis de ambiente permitidos que podem ser definidos por um operador de carga de trabalho com tee-env-ENVIRONMENT_VARIABLE_NAME valores de metadados.

tee.launch_policy.allow_mount_destinations

Interage com:

  • Operador de carga de trabalho: a variável de metadados tee-mount.
String separada por dois pontos

Uma string separada por dois pontos dos diretórios de montagem permitidos que o operador da carga de trabalho pode montar usando tee-mount.

Por exemplo: /run/tmp:/var/tmp:/tmp

tee.launch_policy.log_redirect

Interage com:

String definida

Determina como o registo funciona se tee-container-log-redirect estiver definido como true por um operador de carga de trabalho.

Os valores válidos são:

  • debugonly (predefinição): só permite redirecionamentos stdout e stderr quando usa uma imagem de depuração.
  • always: permitir sempre os redirecionamentos de stdout e stderr.
  • never: nunca permitir redirecionamentos stdout e stderr.

tee.launch_policy.monitoring_memory_allow

Interage com:

String definida

Determina como funciona a monitorização da utilização da memória da carga de trabalho se tee-memory-monitoring-enable for definido como true por um operador de carga de trabalho.

Os valores válidos são:

  • debugonly (predefinição): só permite a monitorização da utilização da memória quando usa uma imagem de depuração.
  • always: permitir sempre a monitorização da utilização de memória.
  • never: nunca permitir a monitorização da utilização de memória.

Várias execuções de cargas de trabalho

Para garantir um ambiente limpo, uma VM tem de ser reiniciada para reiniciar uma carga de trabalho. Isto encripta o disco da VM com uma chave efémera para resolver o vetor de ataque de modificação de uma imagem de carga de trabalho no disco depois de ter sido transferida e medida.

Isto também adiciona custos gerais, como o tempo de arranque e a obtenção da imagem da carga de trabalho para cada execução da carga de trabalho. Se estes custos gerais afetarem demasiado o desempenho da carga de trabalho, pode codificar um reinício da carga de trabalho na própria carga de trabalho, ao custo de aumentar o seu perfil de risco.

Grupos de controlo com espaço de nomes

A carga de trabalho do espaço confidencial é executada sem uma montagem de cgroup por predefinição.

Para gerir cgroups no contentor de carga de trabalho, pode usar tee-cgroup-ns. Isto cria uma montagem em /sys/fs/cgroup no sistema de ficheiros do contentor.

Imagens de contentores reproduzíveis

A criação de uma imagem de contentor de forma reproduzível pode ajudar a aumentar a confiança entre as partes. Pode criar imagens reproduzíveis com o Bazel.

Recursos não geridos pelo Google Cloud IAM

Para aceder a recursos não geridos pelo Google Cloud IAM, a sua carga de trabalho tem de especificar um público-alvo personalizado.

Para mais informações, consulte o artigo Aceda a recursos não geridos pela Google Cloud IAM.

Imagens de contentores assinadas

Pode assinar uma imagem do contentor com uma chave pública, que um colaborador de dados pode usar para atestação em vez de especificar um resumo da imagem na respetiva política de WIP.

Isto significa que os colaboradores de dados não precisam de atualizar as respetivas políticas de WIP sempre que uma carga de trabalho é atualizada, e a carga de trabalho pode continuar a aceder a recursos protegidos sem interrupções.

Pode usar o Sigstore Cosign para assinar a imagem do contentor. Para garantir que o espaço confidencial pode obter as assinaturas, os operadores de cargas de trabalho têm de adicionar as informações de assinatura à variável de metadados tee-signed-image-repos antes de implementar a carga de trabalho.

Durante a execução, as assinaturas são enviadas para o serviço de atestação do espaço confidencial para validação. O serviço de atestação devolve um token de reivindicações de atestação que contém as reivindicações de assinatura validadas. Segue-se um exemplo de uma reivindicação de assinatura:

"image_signatures": [
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key1",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256"
  },
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key2",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256",
  },
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key3",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256",
  }
]

Para configurar a assinatura de imagens de contentores, consulte o codelab de imagens de contentores assinadas.