Uma carga de trabalho é criada por um autor e processa os dados confidenciais com que os colaboradores de dados querem trabalhar.
Um autor de carga de trabalho precisa reunir os seguintes recursos para criar uma carga de trabalho:
Um aplicativo para processar os dados confidenciais. Você pode escrever seu aplicativo em qualquer idioma, desde que crie uma imagem de contêiner compatível.
Uma imagem conteinerizada para empacotar o aplicativo usando o Docker.
Um repositório no Artifact Registry para armazenar a imagem do Docker.
Políticas de inicialização definidas na imagem do contêiner que controlam como uma carga de trabalho pode ser executada e restringem a capacidade de um operador de carga de trabalho malicioso.
Para implantar a carga de trabalho, uma VM confidencial é executada por um operador de carga de trabalho com base na imagem do Confidential Space. Isso recupera a imagem contêinerizada do Artifact Registry e a executa.
Os colaboradores de dados precisam validar os atestados de uma carga de trabalho antes de acessar os dados.
Antes de começar
Escrever uma carga de trabalho para o Confidential Space é mais do que apenas código e depuração. Você também precisa conversar com os colaboradores de dados para avaliar as necessidades deles, configurar seu ambiente, empacotar o código em uma imagem contêinerizada e trabalhar com um operador de carga de trabalho para garantir que tudo seja implantado corretamente.
Converse com os colaboradores de dados
Antes de começar a escrever seu aplicativo, você precisa conversar com os colaboradores de dados sobre os dados privados que eles querem que você trabalhe. Algumas perguntas que você pode fazer são:
Quais são os IDs das organizações envolvidas?
Quais são os números dos projetos envolvidos?
Quais são os recursos do Google Cloud que preciso acessar e quais são os IDs e nomes deles?
Há recursos que preciso acessar que não são gerenciados pelo IAM do Google Cloud?
Como o aplicativo deve comparar e processar os dados particulares?
Em que formato a saída precisa estar?
Onde a saída precisa ser armazenada e se ela precisa ser criptografada?
Todos os colaboradores de dados estão vendo o mesmo resultado ou as saídas são exclusivas para cada um?
Além disso, cada colaborador de dados também pode ter requisitos de privacidade exclusivos que você precisa atender. É de vital importância que nenhum dado particular seja exposto como resultado de uma carga de trabalho.
Criar sua solução do Confidential Space
É útil configurar dois (ou mais) projetos com as permissões adequadas como um ambiente de teste, como em Criar seu primeiro ambiente do Confidential Space. Tente espelhar as configurações do projeto dos colaboradores de dados da melhor forma possível. Assim, você pode ganhar experiência com permissões entre projetos e extrair os dados necessários de recursos específicos do Google Cloud . Ele também pode dar uma ideia das funções de operador de carga de trabalho e colaborador de dados e suas responsabilidades.
Durante a fase inicial de criação, é útil observar as seguintes práticas:
Ao trabalhar como colaborador de dados, mantenha a validação de atestado no mínimo para acelerar o desenvolvimento.
Ao trabalhar como operador de carga de trabalho, use a imagem de depuração do Confidential Space em vez da produção ao implantar a carga de trabalho. Assim, você tem mais maneiras de resolver problemas com a carga de trabalho.
À medida que seu aplicativo amadurece e o estado dele se torna mais previsível, você pode bloquear cada vez mais a solução com a validação de atestado e as políticas de lançamento, e mudar para a imagem Confidential Space de produção.
Depois que a carga de trabalho estiver funcionando corretamente no ambiente de teste, você poderá alternar para o teste nos projetos dos colaboradores de dados com recursos reais, mas dados falsos para demonstrar aos colaboradores de dados como tudo funciona. Nesse ponto, você pode começar a trabalhar com um operador de carga de trabalho independente.
Quando tudo estiver funcionando e a saída estiver como esperado, você poderá começar a testar com dados de produção. Depois que o teste for concluído e todas as partes aprovarem os resultados, a carga de trabalho estará pronta para ser colocada em produção.
Cuidado com a saída
Ao testar seu código, pode ser tentador depurar imprimindo em STDOUT
ou
STDERR
. Se você optar por fazer isso, tenha cuidado para não expor dados
particulares que outras partes possam ler ao acessar os registros. Antes que o código comece
a funcionar na produção, verifique se ele não está gerando nada além do
estritamente necessário.
O mesmo vale para a saída final. Forneça apenas um resultado final que não comprometa a privacidade e a sensibilidade dos dados originais.
Criar uma imagem conteinerizada com o Docker
Os aplicativos precisam ser empacotados em uma imagem em contêiner criada pelo Docker, que é armazenada no Artifact Registry. Quando uma carga de trabalho é implantada, a imagem do Docker é extraída do repositório do Artifact Registry pela imagem do Confidential Space, executada e o aplicativo pode começar a trabalhar nos recursos de projeto adequados.
Ao criar sua imagem do Docker, considere o seguinte:
Limites de disco e memória
O Confidential Space redimensiona automaticamente a partição stateful do disco de inicialização ao usar tamanhos maiores de disco de inicialização. O tamanho da partição é aproximadamente o tamanho do disco de inicialização menos 5 GB.
Como parte das proteções do sistema de arquivos de integridade do Confidential Space, ele armazena tags de integridade do disco na memória. Isso usa aproximadamente 1% de sobrecarga de memória para cada byte do 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.
Mantenha os limites de memória da VM. A troca de memória está desativada nas VMs do Confidential Space, o que significa que o uso excessivo de memória pode causar uma falha na carga de trabalho. Verifique se a seleção de máquina oferece suporte ao uso de memória da carga de trabalho, além da sobrecarga de integridade do disco.
Tokens OIDC expirados
Um token OIDC é disponibilizado para consumo pela carga de trabalho quando ela é iniciada. Ele
contém declarações de atestado verificadas sobre a VM da carga de trabalho e é armazenado no
contêiner de carga de trabalho em
/run/container_launcher/attestation_verifier_claims_token
. O token expira
após 60 minutos.
Se o token expirar, uma atualização será feita em segundo plano usando a espera exponencial até ser bem-sucedida. Se uma atualização falhar (devido a problemas de rede, uma falha do serviço de atestado ou outra causa), o código da carga de trabalho precisará ser capaz de lidar com essa falha.
A carga de trabalho pode lidar com uma falha na atualização do token de uma das seguintes maneiras:
Ignorar o token expirado, supondo que ele não seja mais necessário após o uso inicial.
Aguardar a atualização do token expirado.
Sair da carga de trabalho.
Montagens de scratch na memória
O Confidential Space oferece suporte à adição de espaços de rascunho na memória. Isso usa a memória disponível na VM do Confidential Space. Como o espaço temporário usa a memória da VM confidencial, ele tem as mesmas propriedades de integridade e confidencialidade da VM confidencial.
Use
tee-dev-shm-size
para aumentar o tamanho do mount de memória compartilhada /dev/shm
para a carga de trabalho.
O tamanho do /dev/shm
é especificado em KB.
É possível usar
tee-mount
para especificar
montagens de tmpfs no contêiner em execução usando configurações separadas por ponto e vírgula. O type
e o source
são sempre tmpfs
. O destination
é
o ponto de montagem, que interage com a
política de inicialização tee.launch_policy.allow_mount_destinations
. Opcionalmente,
especifique o tamanho do tmpfs
em bytes. O tamanho padrão é 50% da memória da VM.
Portas de entrada
Por padrão, as VMs do Confidential Space operam com uma regra de firewall para bloquear todas as portas de entrada. Ao usar a versão de imagem do Confidential Space 230600 ou mais recente,
é possível especificar as portas de entrada que devem permanecer abertas no Dockerfile
ao criar
a imagem da carga de trabalho.
Para abrir portas, adicione a palavra-chave EXPOSE
ao Dockerfile
, com o número da porta que deve permanecer aberto e um protocolo opcional de tcp
ou udp
. Se você
não especificar o protocolo para uma porta, o TCP e o UDP serão permitidos. Confira um
exemplo de 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 []
Dependendo da imagem base usada, algumas portas podem já estar expostas. O
Dockerfile
só expõe portas adicionais. Ele não pode bloquear portas que já
foram abertas pela imagem de base.
Os operadores de carga de trabalho precisam garantir que as portas expostas estejam abertas no firewall da 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 registradas no console e redirecionadas para o Cloud Logging ao usar 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 carga de trabalho para restringir ações maliciosas. Um autor de carga de trabalho pode definir políticas com um rótulo como parte da criação da imagem do contêiner.
Por exemplo, em um Dockerfile
:
LABEL "tee.launch_policy.allow_cmd_override"="true"
Em um arquivo BUILD do Bazel:
container_image(
...
labels={"tee.launch_policy.allow_cmd_override":"true"}
...
)
As políticas de lançamento disponíveis estão na seguinte tabela:
Política | Tipo | Descrição |
---|---|---|
Interage com:
|
Booleano (o padrão é false ) |
Determina se o
CMD
especificado na Dockerfile do contêiner de carga de trabalho pode ser
substituído por um operador de carga de trabalho com o valor de metadados
tee-cmd .
|
Interage com:
|
String separada por vírgulas |
Uma string separada por vírgulas de nomes de variável de ambiente permitidos que
podem ser definidos por um operador de carga de trabalho com
valores de metadados
tee-env-ENVIRONMENT_VARIABLE_NAME .
|
Interage com:
|
String separada por dois-pontos |
Uma string separada por dois-pontos de diretórios de montagem permitidos que o operador de carga de trabalho pode montar usando Por exemplo: |
Interage com:
|
String definida |
Determina como a geração de registros funciona se
Os valores válidos são:
|
Interage com:
|
String definida |
Determina como o monitoramento do uso de memória da carga de trabalho funciona se
Os valores válidos são:
|
Várias execuções de carga de trabalho
Para garantir um ambiente limpo, é preciso reiniciar uma VM para recomeçar uma carga de trabalho. Isso criptografa o disco da VM com uma chave temporária para lidar com o vetor de ataque da modificação de uma imagem de carga de trabalho no disco após o download e a medição.
Isso também adiciona sobrecargas, como tempo de inicialização e extração da imagem da carga de trabalho a cada execução da carga de trabalho. Se essas sobrecargas afetarem muito o desempenho da carga de trabalho, é possível codificar uma reinicialização para a própria carga de trabalho ao custo de aumentar seu perfil de risco.
Imagens de contêiner reproduzíveis
Criar uma imagem de contêiner de maneira reproduzível pode ajudar a aumentar a confiança entre as partes. É possível criar imagens reproduzíveis com o Bazel.
Recursos não gerenciados pelo IAM do Google Cloud
Para acessar recursos não gerenciados pelo IAM do Google Cloud , sua carga de trabalho precisa especificar um público-alvo personalizado.
Para mais informações, consulte Acessar recursos não gerenciados pelo Google Cloud IAM.
Imagens de contêiner assinadas
É possível assinar uma imagem de contêiner com uma chave pública, que um colaborador de dados pode usar para atestado em vez de especificar um resumo de imagem na política de WIP.
Isso significa que os colaboradores de dados não precisam atualizar as políticas de trabalho em andamento sempre que uma carga de trabalho é atualizada, e a carga de trabalho pode continuar acessando os recursos protegidos sem interrupções.
É possível usar a Sigstore Cosign para
assinar a imagem do contêiner. Para garantir que o Confidential Space possa buscar as
assinaturas, os operadores de carga de trabalho precisam adicionar as informações de assinatura à
variável de metadados tee-signed-image-repos
antes de implantar a carga de trabalho.
Durante a execução, as assinaturas são enviadas ao serviço de atestado do Confidential Space para verificação. O serviço de atestado retorna um token de declaração de atestado que contém as declarações de assinatura verificadas. Confira um exemplo de declaraçã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 contêiner, consulte o codelab de imagens de contêiner assinadas.