Autor: Aghiles Ait Messaoud, PhD, Engenheiro de Software de Pesquisa na iExec.
Introdução
A Parte 1 desta série estabeleceu a base da cadeia de confiança da Nox: a verificação na inicialização que impede uma Máquina Virtual Confidencial (CVM) de obter qualquer segredo, a menos que tenha iniciado um conjunto conhecido de imagem de sistema operacional e uma pilha de aplicações conhecida em hardware Intel TDX atestado. Essa garantia, no entanto, é imposta internamente pela plataforma no momento da inicialização; por si só, ela não oferece a um usuário final ou a um auditor externo nenhuma forma direta de verificar, em um momento posterior, que um serviço Nox em execução ainda é exatamente a carga de trabalho que foi atestada.
Este documento é a segunda parte da série e trata essa lacuna: atestação em tempo de execução, a capacidade de qualquer parte verificar, em qualquer ponto durante a vida útil de uma CVM, que um determinado componente Nox está genuinamente executando o código esperado dentro de um verdadeiro Intel TDX Trust Domain (TD). Explicamos (i) como uma cotação TDX nova é solicitada a uma CVM em execução e o que ela contém; (ii) os componentes implantados ao redor da frota TDX para descobrir as CVMs em execução e expor suas cotações; (iii) a sequência ponta a ponta e a interface voltada ao usuário que apresentam essa evidência; e (iv) o protocolo passo a passo pelo qual uma cotação é verificada, da assinatura até o docker-compose realmente executado.
Ele se baseia diretamente na fundação do TEE descrita na Parte 1 e deliberadamente limita seu escopo à atestação em tempo de execução conforme apresentada via Runtime Attestation UI. Os links restantes da cadeia de confiança, o vínculo com o código-fonte e a governança em cadeia dos measurements autorizados, são tratados em partes posteriores.
O restante deste documento está organizado da seguinte forma. Em Fundo, relembramos o que é atestação em tempo de execução, como uma cotação TDX é estruturada e os três campos de cotação nos quais o Nox se baseia. Em Implantação arquitetural, descrevemos os componentes implantados ao redor dos servidores TDX e os dados que eles trocam. Em Ambiente de referência, fixamos as versões dos componentes sobre as quais este artigo se baseia. No Diagrama de Sequência, rastreamos o fluxo ponta a ponta pelo qual a UI descobre as CVMs em execução e as atesta. Em Apresentação da Interface do Usuário, apresentamos a interface e seus três níveis de atestação. Em Etapas de atestação de um componente Nox, detalhamos o protocolo de verificação aplicado a uma única CVM. Por fim, em Trabalho futuro, descrevemos as melhorias planejadas: procedência da imagem, desafios fornecidos pelo usuário e verificadores adicionais de cotação.
Fundo
Nesta seção, revisamos os conceitos em que este documento se baseia: o que é atestação em tempo de execução, como uma cotação TDX é estruturada e os três campos de cotação nos quais o Nox confia, a saber report_data, os RTMRs e seus logs de eventos associados.
Runtime Attestation
Atestação em tempo de execução é o mecanismo que permite que qualquer parte remota verifique, sob demanda e a qualquer momento durante a vida útil de uma CVM, que um componente Nox está genuinamente em execução dentro de um real Intel TDX Trust Domain (TD), com o código e a configuração esperados. Enquanto a atestação no tempo de boot (ver Parte 1) estabelece a cadeia de confiança do hardware até o dstack-OS, a atestação em tempo de execução expõe essa confiança para verificadores externos por meio de um simples protocolo de resposta a desafio (challenge-response).
Cotação TDX
Uma cotação TDX é uma estrutura assinada criptograficamente produzida pelo Quoting Enclave da plataforma. Ela carrega a evidência de que um verificador precisa para confiar em um TD e é assinada com uma chave de atestação fornecida pela Intel, de modo que qualquer pessoa possa validar sua autenticidade percorrendo a cadeia de certificados até a raiz de confiança da Intel. Os três campos nos quais o Nox se baseia para atestação em tempo de execução (report_data, os RTMRs e seus logs de eventos associados) são detalhados abaixo.
report_data
report_data é um campo de 64 bytes cujo conteúdo é escolhido inteiramente pela workload. A TDX o copia verbatim para a cotação assinada, o que permite que uma aplicação vincule dados arbitrários à atestação do hardware. Usos comuns são:
Atualidade / resposta ao desafio: incorporar um nonce fornecido por um verificador, como faz o Runtime Attestation UI, para provar que a cotação foi gerada sob demanda.
Vinculação de identidade: incorporar o hash de uma chave pública ou certificado TLS (a base do RA-TLS, ver Parte 1), de modo que um canal seguro seja encerrado de forma demonstrável dentro do TD.
Outras provas, como endereços de carteira blockchain ou hashes de estado da aplicação.
No Nox, a UI gera um desafio aleatório e espera encontrar exatamente esse valor no report_data da cotação.
RTMRs
Registros de Medição em Tempo de Execução (RTMRs) são o equivalente em TDX dos PCRs de TPM: registradores somente para anexar (append-only) que não podem ser escritos diretamente; apenas são estendidos através de uma cadeia de hash. Um TD expõe quatro deles, e o dstack atribui a cada um um papel bem definido:
RTMR0: o ambiente virtual de hardware / firmware.
RTMR1: o kernel do Linux.
RTMR2: a linha de comando do kernel e initrd.
RTMR3: medições específicas do aplicativo: app-id, os_image_hash, compose-hash, instance-id e key-provider.
O conteúdo inicial da memória e a configuração do TD são capturados separadamente em MRTD. Durante a verificação, RTMR0–RTMR2 (juntamente com MRTD) atestam a integridade da cadeia de boot, enquanto RTMR3 atesta que o código e a configuração esperados da aplicação estão em execução. No Nox, focamos em RTMR3, pois ele vincula a cotação ao componente específico do Nox e ao seu docker-compose.
logs de eventos
Um valor de RTMR é um hash opaco: ele atesta se as medições esperadas foram incorporadas, mas não quais foram. O log de eventos é o registro legível para humanos dos eventos individuais de medição que foram estendidos em um RTMR (na prática, RTMR3). Cada evento é uma medição chave-valor como app-id, compose-hash, instance-id ou key-provider, e cada evento é incorporado no registrador com a fórmula de extensão:
RTMR3_new = SHA384(RTMR3_old || SHA384(event_log))
Um verificador reproduz o log de eventos por meio desta fórmula e compara o registrador recalculado com o valor rt_mr3 dentro da cotação assinada. Se eles coincidirem, os valores individuais dos eventos, notadamente os_image_hash e compose_hash, podem ser confiáveis como representações fiéis da imagem do SO e do docker-compose realmente executados pela CVM.
Implantação arquitetural
Nesta seção, descrevemos os componentes implantados ao redor dos servidores TDX para fazer o Runtime Attestation UI funcionar e ilustramos o formato dos dados que eles trocam.

Para que o Runtime Attestation UI funcione, cinco componentes principais colaboram:
Portal do Runtime Attestation UI: A interface acessada pelo usuário para visualizar o processo de Runtime Attestation. Ela já está implantada no lado da iExec em https://trust.noxprotocol.io/, mas também pode ser reconstruída e implantada em computadores pessoais usando seu código-fonte (https://github.com/iExec-Nox/nox-attestation-portal). A UI solicita nox-cvms-exporter-aggregator para obter a lista de CVMs ativas juntamente com, para cada uma, sua cotação recém-obtida e docker-compose. O agregador em si contata cada CVM dstack-quote-service, então a UI nunca conversa diretamente com as CVMs.
nox-cvms-exporter: um serviço host que se conecta ao hipervisor dstack (dstack-vmm) para coletar a lista de CVMs ativas (seus URLs de dstack-quote-service) na máquina TDX local e envia isso ao nox-cvms-exporter-aggregator.
nox-cvms-exporter-aggregator: um serviço implantado no Azure Kubernetes Service que agrega a lista de CVMs ativas recebidas de cada nox-cvms-exporter individual. Para cada CVM listada, ele então contata o dstack-quote-service da CVM para buscar sua cotação nova (vinculada ao desafio da UI) e seu docker-compose, e retorna a lista enriquecida para o portal do Runtime Attestation UI.
Proof of Cloud Trust Server: servidor iExec para Proof of Cloud (http://github.com/proofofcloud/trust-server) para verificar se uma cotação foi emitida por uma máquina TDX permitida (whitelisted) e não revogada. Os detalhes do processo de inclusão na lista do Proof of Cloud estão documentados na Parte I da nossa série de artigos.
Phala PCCS: cache local da Phala para armazenar colaterais (TCB Infos, certificados PCK da Intel e lista de revogação de certificados) para verificar uma cotação.
Ambiente de referência
Nesta seção, fixamos as versões exatas dos componentes envolvidos no Runtime Attestation UI, para que o comportamento descrito no restante deste artigo possa ser reproduzido e, à medida que esses componentes evoluem, comparado com uma linha de base conhecida.

Diagrama de Sequência
Nesta seção, rastreamos a sequência ponta a ponta pela qual o Runtime Attestation UI descobre as CVMs em execução e as atesta, desde a abertura do portal até a exibição do resultado.

Este diagrama descreve como o Runtime Attestation UI descobre as Confidential VMs (CVMs) em execução na frota TDX e as atesta.
Abrir portal: O usuário abre o portal, seja diretamente pela instância hospedada pela iExec https://trust.noxprotocol.io ou construindo e executando o repositório de origem (https://githu b.com/iExec-Nox/nox-attestation-portal ) Ao carregar, a UI gera um único desafio aleatório (32 bytes) que deve ser vinculado às cotações coletadas.
Solicitação de descoberta: A UI chama o endpoint GET /cvms do agregador, passando seu desafio como parâmetro de consulta (?challenge=...). Esse parâmetro é obrigatório, pois o desafio precisa ser repassado às CVMs para vincular as cotações retornadas.
Fan-out para exportadores: Para cada máquina TDX na lista configurada de exportadores, o agregador chama GET {base_url}/cvms em paralelo. O desafio não é encaminhado nesta etapa; ele é usado apenas mais tarde, ao buscar as cotações.
Enumeração local de CVMs: Cada exportador consulta seu dstack-vmm local (POST /prpc/Status?json) para listar as VMs executando nessa máquina.
Resposta do VMM: o dstack-vmm retorna a lista bruta de VMs. O exportador filtra VMs cujo status está parado/removido e exclui as CVMs de sistema kms e dstack-gateway.
Resposta do exportador: O exportador monta a URL base do serviço de cotação de cada CVM e retorna as CVMs agrupadas por app_id, com cada instância carregando { instance_id, url, machine_id }.
Solicitação de cotação (enriquecimento): O agregador enriquece cada instância com sua cotação nova: para cada instância, o agregador chama o GET do serviço de cotação da CVM {url}/quote?data={challenge}, repassando o desafio da UI para que a cotação retornada seja vinculada a ele.
Resposta da cotação: o serviço de cotação retorna { quote, event_log } já que a UI precisa da cotação para a verificação de assinatura e do log de eventos para a reprodução do RTMR3.
Solicitação de manifesto: Em paralelo à solicitação de cotação, o agregador chama o mesmo GET do serviço de cotação da CVM {url}/info para recuperar o manifesto de implantação.
Resposta do manifesto: o serviço de cotação retorna sua carga útil de /info; a partir dela, o agregador extrai o manifesto do docker-compose (tcb_info.app_compose).
Mesclar & responder: O agregador reorganiza as instâncias enriquecidas por app_id e retorna a lista mesclada para a UI; cada instância agora carrega { instance_id, machine_id, quote: { quote, event_log }, app_compose }. O campo url é mantido interno ao agregador e nunca é exposto à UI, de modo que o navegador não tem como alcançar as CVMs diretamente. O arquivo JSON abaixo ilustra um exemplo de entrada agregada enviada pelo nox-cvms-exporter-aggregator à UI de atestação.
{
"app_id": "a1b2c3...",
"name": "nox-component-cvm",
"instances": [
{
"instance_id": "i-0abc123",
"machine_id": "Node 1",
"quote": {
"quote": "0x0400...", # cotação TDX (hex)
"event_log": [ ... ] # log de evento RTMR3
},
"app_compose": "..." # manifesto docker-compose (YAML)
},
{
"instance_id": "i-0def456",
"machine_id": "Node 2",
"quote": {
"quote": "0x0400...",
"event_log": [ ... ]
},
"app_compose": "..."
}
]
}
Verificar & exibir: Para cada CVM retornada, a UI verifica a atestação localmente e exibe as CVMs junto com o resultado. Esse protocolo de verificação é detalhado na seção Etapas de atestação de um componente Nox.
Apresentação da Interface do Usuário
Nesta seção, apresentamos o Runtime Attestation UI e os três níveis de atestação que ele expõe ao usuário.

Runtime Attestation UI como exibido no NOX · Cadeia de Confiança https://trust.noxprotocol.io
A captura de tela acima mostra o Runtime Attestation UI. Ao carregar, o painel à esquerda lista os componentes do Nox em execução nas máquinas TDX do testnet, cada um anotado com o número de réplicas (por exemplo, 6 para nox-kms). A interface oferece três níveis de atestação de componente do Nox:
Verificação completa: Ao clicar no botão Verify all, todas as instâncias de CVM de todos os componentes Nox serão verificadas
.Verificação no nível do componente: Esse nível fica disponível assim que um componente Nox é escolhido no painel à esquerda. Uma vez clicado em Verify all, todas as instâncias de CVM do componente Nox escolhido serão verificadas independentemente da máquina subjacente.
Verificação no nível de instância: Esse nível também fica disponível assim que um componente Nox é escolhido no painel à esquerda. Ao clicar em Verify, apenas a instância específica do componente Nox escolhido será verificada.
Etapas de atestação de um componente Nox
Nesta seção, detalhamos o protocolo de verificação passo a passo aplicado a uma única CVM de componente Nox e descrevemos o que a UI exibe uma vez que cada verificação foi concluída.

O protocolo de verificação aplicado a uma CVM de componente Nox prossegue da seguinte forma:
Obtenha uma cotação nova: o UI gera um desafio aleatório e obtém, via agregador, uma cotação nova vinculada a esse desafio (veja Diagrama de Sequência ). O desafio deve ser incorporado no report_data do relatório da cotação.
Verifique a assinatura da cotação e a cadeia de certificados: a assinatura da cotação e sua cadeia de certificados até a Intel são validadas por um verificador DCAP. Na implementação atual, isso é executado localmente no navegador via um Phala dcap-qvl incorporado (biblioteca de verificação de cotação: githubl ). O qvl busca os colaterais de verificação (as informações TCB e a cadeia de certificados enraizada na Intel) em dstack PCCS (Serviço de Cache de Certificados de Provisionamento hospedado pela Phala) e realiza a verificação por conta própria. Em paralelo, a cotação é enviada ao Proof of Cloud trust server , que informa se a máquina atestada pertence a um parque de nuvem (certificado) incluído na lista de permissões. Esse resultado de prova de nuvem é informativo e não bloqueante: se o servidor de confiança estiver indisponível ou atingir o tempo limite, a atestação ainda prossegue.
Verifique a atualidade da cotação: a atualidade da cotação é confirmada verificando que o desafio aleatório gerado pelo UI está incorporado no report_data da cotação.
Exibir valores de RTMR: uma etapa informativa que extrai e exibe os valores de RTMR da cotação.
Reproduzir (replay) RTMR3: os logs de eventos retornados junto com a cotação (na resposta do agregador) são usados para reproduzir o RTMR3 seguindo a fórmula da Intel: RTMR3_new = SHA384(RTMR3_old || SHA384(event_log)). Se o RTMR3 reproduzido corresponder ao atestado (na cotação), os valores dos logs de eventos os_image_hash e compose_hash podem ser confiáveis como representações do sistema operacional executado e do docker-compose.
Verifique a imagem do SO: o log de evento RTMR3 do os_image_hash é extraído, e é fornecido um link de download para que a imagem e seu hash possam ser verificados manualmente, se necessário. Na iExec, essa imagem é dstackOS.
Verifique o compose-hash: o docker-compose (app_compose, fornecido na resposta do agregador) é hasheado, e o resultado é comparado ao compose_hash incorporado como um log de evento de RTMR3.
Depois que essas etapas de verificação são realizadas, o docker-compose correspondente ao compose-hash da CVM atestada é exibido conforme mostrado na imagem abaixo.

O docker-compose da CVM abrange três serviços:
nox-component: o serviço de negócios executado na CVM (por exemplo, nox-kms)
quote-service: o serviço usado para obter a cotação e os logs de eventos necessários para atestar a CVM
fluent-bit: serviço exportador de logs da iExec para observabilidade interna
Trabalho futuro
Nesta seção, descrevemos as melhorias planejadas para o fluxo de atestação: procedência da imagem, desafios fornecidos pelo usuário e verificadores adicionais de cotação.
Procedência da imagem
Até o momento, a atestação é interrompida quando exibimos o docker compose que lista as imagens executadas na CVM atestada. Um próximo passo é aproveitar a infraestrutura do Sigstore para assinar o workflow do GitHub Actions que gerou cada imagem, durante sua construção, e publicar a atestação do SLSA (Supply-chain Levels for Software Artifacts) identificada pelo checksum sha256 da imagem (subject-name) no GitHub e no registry docker da imagem. Uma entrada do Rekor também será naturalmente enviada. Ao fazer isso, poderemos estender as etapas de verificação mencionadas neste artigo atestando a procedência de cada imagem do Nox (isto é, workflow de build e commit do repositório do GitHub).
Desafio fornecido pelo usuário
Atualmente, para testar a atualidade de uma cotação, usamos um desafio gerado automaticamente que é transmitido da UI para o agregador como um parâmetro de consulta; então ele o repassa para cada serviço de cotação. Vamos fortalecer esse processo permitindo que usuários da UI insiram seu próprio desafio para obter um nível adicional de confiança na atualidade da cotação.
Vários verificadores
Atualmente, usamos o Phala qvl como o único método de verificação para checar a assinatura Intel e a cadeia de certificados de uma cotação. Adicionaremos métodos adicionais de verificação, como alternativas ou como verificações obrigatórias quando disponíveis, para melhorar a confiança no resultado da verificação. Os possíveis verificadores a adicionar são o iExec-hosted dstack-verifier e o Intel Trust Authority.

