Autor: Aghiles Ait Messaoud, PhD, Ingeniero de Software de Investigación que trabaja en iExec.
Introducción
La Parte 1 de esta serie estableció la base de la cadena de confianza de Nox: la verificación en el arranque que impide que una Máquina Virtual Confidencial (CVM) obtenga cualquier secreto a menos que haya arrancado una imagen del sistema operativo conocida y una pila de aplicaciones conocida en hardware Intel TDX atestiguado. Sin embargo, esa garantía se aplica internamente por la plataforma en el momento del arranque; por sí sola, no brinda a un usuario final ni a un auditor externo ninguna forma directa de comprobar, en un momento posterior, que un servicio Nox en ejecución sigue siendo exactamente la carga de trabajo que se atestiguó.
Este documento es la segunda parte de la serie y aborda ese vacío: atestación en tiempo de ejecución, la capacidad de cualquier parte para verificar, en cualquier momento durante la vida de una CVM, que un componente Nox está ejecutando de manera genuina el código esperado dentro de un Intel TDX Trust Domain (TD) real. Describimos (i) cómo se solicita una cotización TDX fresca desde una CVM en ejecución y qué contiene; (ii) los componentes desplegados alrededor de la flota TDX para descubrir las CVM en ejecución y exponer sus cotizaciones; (iii) la secuencia de extremo a extremo y la interfaz orientada al usuario que muestra esta evidencia; y (iv) el protocolo paso a paso mediante el cual una cotización es verificada, desde su firma hasta el docker-compose realmente ejecutado.
Se construye directamente sobre la base del TEE descrita en la Parte 1 y limita deliberadamente su alcance a la atestación en tiempo de ejecución tal como se muestra a través de la UI de Runtime Attestation. Los enlaces restantes de la cadena de confianza, el acoplamiento del código fuente y la gobernanza on-chain de las mediciones autorizadas, se tratan en partes posteriores.
El resto de este documento se organiza de la siguiente manera. En Fondo, recordamos qué es la atestación en tiempo de ejecución, cómo se estructura una cotización TDX y los tres campos de cotización en los que Nox confía. En Despliegue arquitectónico, describimos los componentes desplegados alrededor de los servidores TDX y los datos que intercambian. En Entorno de referencia, fijamos las versiones de los componentes en los que se basa este artículo. En Diagrama de secuencia, rastreamos el flujo de extremo a extremo mediante el cual la UI descubre las CVM en ejecución y las atestigua. En Presentación de la interfaz de usuario, presentamos la interfaz y sus tres niveles de atestación. En Pasos de atestación de un componente Nox, detallamos el protocolo de verificación aplicado a una sola CVM. Por último, en Trabajo futuro, describimos las mejoras planeadas: procedencia de la imagen, desafíos proporcionados por el usuario y verificadores adicionales de cotizaciones.
Fondo
En esta sección, revisamos los conceptos sobre los que se apoya este documento: qué es la atestación en tiempo de ejecución, cómo se estructura una cotización TDX y los tres campos de cotización en los que Nox confía, a saber report_data, los RTMRs y sus registros de eventos asociados.
Runtime Attestation
La atestación en tiempo de ejecución es el mecanismo que permite a cualquier parte remota verificar, bajo demanda y en cualquier momento durante la vida de una CVM, que un componente Nox realmente se está ejecutando dentro de un Intel TDX Trust Domain (TD) con el código y la configuración esperados. Mientras que la atestación en el momento del arranque (ver Parte 1) establece la cadena de confianza desde el hardware hasta dstack-OS, la atestación en tiempo de ejecución expone esa confianza a verificadores externos mediante un protocolo simple de desafío-respuesta.
Cotización TDX
Una cotización TDX es una estructura firmada criptográficamente producida por el Quoting Enclave de la plataforma. Contiene la evidencia que un verificador necesita para confiar en un TD y está firmada con una clave de atestación provista por Intel, de modo que cualquiera pueda validar su autenticidad siguiendo la cadena de certificados de regreso hasta la raíz de confianza de Intel. Los tres campos en los que Nox confía para la atestación en tiempo de ejecución (report_data, los RTMRs y sus registros de eventos asociados) se detallan a continuación.
report_data
report_data es un campo de 64 bytes cuyo contenido es elegido completamente por la carga de trabajo. TDX lo copia tal cual en la cotización firmada, lo que permite que una aplicación vincule datos arbitrarios con la atestación de hardware. Usos comunes son:
Vigencia / respuesta al desafío: incrustar un nonce proporcionado por el verificador, como lo hace la UI de Runtime Attestation, para demostrar que la cotización se generó bajo demanda.
Vinculación de identidad: incrustar el hash de una clave pública o certificado TLS (la base de RA-TLS, ver Parte 1), de modo que un canal seguro termine de forma demostrable dentro del TD.
Otras pruebas, como direcciones de billeteras blockchain o hashes del estado de la aplicación.
En Nox, la UI genera un desafío aleatorio y espera encontrar exactamente ese valor en el report_data de la cotización.
RTMRs
Los registros de medición en tiempo de ejecución (RTMRs) son el equivalente de TPM PCRs en TDX: registros de solo adición que no se pueden escribir directamente, solo extender mediante una cadena hash. Un TD expone cuatro de ellos, y dstack asigna a cada uno un rol bien definido:
RTMR0: el entorno de hardware / firmware virtual.
RTMR1: el kernel de Linux.
RTMR2: la línea de comandos del kernel y initrd.
RTMR3: mediciones específicas de la aplicación: app-id, os_image_hash, compose-hash, instance-id y key-provider.
El contenido inicial de memoria y la configuración del TD se capturan por separado en MRTD. Durante la verificación, RTMR0–RTMR2 (junto con MRTD) atestiguan la integridad de la cadena de arranque, mientras que RTMR3 atestigua que se está ejecutando el código y la configuración esperados de la aplicación. En Nox nos enfocamos en RTMR3, ya que vincula la cotización con el componente específico de Nox y su docker-compose.
registros de eventos
Un valor RTMR es un hash opaco: atestigua si las mediciones esperadas se incluyeron, pero no cuáles fueron. El registro de eventos es el registro legible por humanos de los eventos de medición individuales que se extendieron en un RTMR (en la práctica, RTMR3). Cada evento es una medición clave-valor como app-id, compose-hash, instance-id o key-provider, y cada evento se incorpora al registro con la fórmula de extensión:
RTMR3_new = SHA384(RTMR3_old || SHA384(event_log))
Un verificador reproduce el registro de eventos mediante esta fórmula y compara el registro recalculado con el valor rt_mr3 dentro de la cotización firmada. Si coinciden, los valores individuales de los eventos, en particular os_image_hash y compose_hash, pueden confiarse como representaciones fieles de la imagen del sistema operativo y del docker-compose realmente ejecutados por la CVM.
Despliegue arquitectónico
En esta sección, describimos los componentes desplegados alrededor de los servidores TDX para que funcione la UI de Runtime Attestation y mostramos la forma de los datos que intercambian.

Para que funcione la UI de Runtime Attestation, cinco componentes principales colaboran:
Portal de la UI de Runtime Attestation: La interfaz a la que accede el usuario para visualizar el proceso de Runtime Attestation. Ya está desplegada del lado de iExec en https://trust.noxprotocol.io/ , pero también se puede reconstruir y desplegar en computadores personales usando su código fuente (https://github.com/iExec-Nox/nox-attestation-portal). La UI solicita nox-cvms-exporter-aggregator para obtener la lista de CVM activas junto con, para cada una, su cotización recién obtenida y docker-compose. El agregador en sí contacta a cada CVM dstack-quote-service, por lo que la UI nunca habla directamente con las CVM.
nox-cvms-exporter: un servicio anfitrión que se conecta al hipervisor dstack (dstack-vmm) para recopilar la lista de CVM activas (su URL de dstack-quote-service) en la máquina TDX local y se la envía al nox-cvms-exporter-aggregator.
nox-cvms-exporter-aggregator: un servicio desplegado en Azure Kubernetes Service que agrega la lista de CVM activas recibida de cada nox-cvms-exporter individual. Para cada CVM listada, luego contacta el dstack-quote-service de la CVM para obtener su cotización fresca (vinculada al desafío de la UI) y su docker-compose, y devuelve la lista enriquecida al portal de la UI de Runtime Attestation.
Proof of Cloud Trust Server: servidor de iExec para Proof of Cloud (http://github.com/proofofcloud/trust-server) para comprobar si una cotización fue emitida desde una máquina TDX incluida en lista blanca y no revocada. Los detalles del proceso de inclusión en lista blanca de Proof of Cloud se documentan en la Parte I de nuestra serie de artículos.
Phala PCCS: caché local de Phala para almacenar datos de soporte (TCB Infos, certificados PCK de Intel y la lista de revocación de certificados) para verificar una cotización.
Entorno de referencia
En esta sección, fijamos las versiones exactas de los componentes involucrados en la UI de Runtime Attestation, para que el comportamiento descrito en el resto de este artículo pueda reproducirse y, a medida que estos componentes evolucionan, se pueda comparar con una línea base conocida.

Diagrama de secuencia
En esta sección, rastreamos la secuencia de extremo a extremo mediante la cual la UI de Runtime Attestation descubre las CVM en ejecución y las atestigua, desde abrir el portal hasta mostrar el resultado.

Este diagrama describe cómo la UI de Runtime Attestation descubre las Confidential VMs (CVMs) que se ejecutan en toda la flota TDX y las atestigua.
Abrir portal: El usuario abre el portal, ya sea directamente a través de la instancia alojada en iExec https://trust.noxprotocol.io o construyendo y ejecutando por su cuenta el repositorio de código fuente (https://githu b.com/iExec-Nox/nox-attestation-portal )Al cargar, la UI genera un único desafío aleatorio (32 bytes) que se espera que esté vinculado en las cotizaciones recopiladas.
Solicitud de descubrimiento: La UI llama al endpoint GET /cvms del agregador, pasando su desafío como parámetro de consulta (?challenge=...). Este parámetro es obligatorio ya que el desafío debe reenviarse a las CVM para vincular las cotizaciones devueltas.
Fan-out a exportadores: Para cada máquina TDX en su lista de exportadores configurada, el agregador llama a GET {base_url}/cvms en paralelo. El desafío no se reenvía en esta etapa; solo se usa más adelante, cuando se obtienen las cotizaciones.
Enumeración local de CVM: Cada exportador consulta su dstack-vmm local (POST /prpc/Status?json) para listar las VMs que se ejecutan en esa máquina.
Respuesta del VMM: dstack-vmm devuelve la lista de VMs sin procesar. El exportador filtra las VMs cuyo estado esté detenido/eliminado y excluye las CVM del sistema kms y dstack-gateway.
Respuesta del exportador: El exportador construye la URL base de cada servicio de cotización de la CVM y devuelve las CVM agrupadas por app_id , donde cada instancia incluye { instance_id, url, machine_id }.
Solicitud de cotización (enriquecimiento): El agregador enriquece cada instancia con su cotización nueva: para cada instancia, el agregador llama al GET del servicio de cotización de la CVM {url}/quote?data={challenge}, reenviando el desafío de la UI para que la cotización devuelta quede vinculada a él.
Respuesta de la cotización: El servicio de cotización devuelve { quote, event_log } ya que la UI necesita la cotización para la verificación de la firma y el registro de eventos para la reproducción de RTMR3.
Solicitud de manifiesto: Concurrentemente con la solicitud de cotización, el agregador llama al mismo servicio de cotización de la CVM GET {url}/info para recuperar el manifiesto de despliegue.
Respuesta del manifiesto: El servicio de cotización devuelve su carga /info, de la cual el agregador extrae el manifiesto docker-compose (tcb_info.app_compose).
Combinar y responder: El agregador reagruppa las instancias enriquecidas por app_id y devuelve a la UI la lista fusionada; cada instancia ahora incluye { instance_id, machine_id, quote: { quote, event_log }, app_compose }. El campo url se mantiene interno al agregador y nunca se expone a la UI, por lo que el navegador no tiene forma de acceder directamente a las CVM. El archivo JSON de abajo ilustra un ejemplo de una entrada agregada enviada por el nox-cvms-exporter-aggregator a la UI de atestación.
{
"app_id": "a1b2c3...",
"name": "nox-component-cvm",
"instances": [
{
"instance_id": "i-0abc123",
"machine_id": "Node 1",
"quote": {
"quote": "0x0400...", # cotización TDX (hex)
"event_log": [ ... ] # registro de eventos RTMR3
},
"app_compose": "..." # manifiesto docker-compose (YAML)
},
{
"instance_id": "i-0def456",
"machine_id": "Node 2",
"quote": {
"quote": "0x0400...",
"event_log": [ ... ]
},
"app_compose": "..."
}
]
}
Verificar y mostrar: Para cada CVM devuelta, la UI verifica la atestación localmente y muestra las CVMs junto con el resultado. Este protocolo de verificación se detalla en la sección Pasos de atestación de un componente Nox.
Presentación de la interfaz de usuario
En esta sección, presentamos la UI de Runtime Attestation y los tres niveles de atestación que expone al usuario.

UI de Runtime Attestation tal como se muestra en NOX · Chain of Trust https://trust.noxprotocol.io
La captura anterior muestra la UI de Runtime Attestation. Al cargar, el panel izquierdo lista los componentes de Nox en ejecución en las máquinas TDX del testnet, cada uno anotado con su número de réplicas (p. ej., 6 para nox-kms). La interfaz ofrece tres niveles de atestación del componente Nox:
Verificación completa: Al hacer clic en el botón Verify all, se verificarán todas las instancias de CVM de todos los componentes Nox
.Verificación a nivel de componente: Este nivel se habilita una vez que se elige un componente Nox en el panel del lado izquierdo. Al hacer clic en Verify all, se verificarán todas las instancias de CVM del componente Nox elegido, independientemente de su máquina subyacente.
Verificación a nivel de instancia: Este nivel también se habilita una vez que se elige un componente Nox en el panel del lado izquierdo. Al hacer clic en Verify, solo se verificará la instancia específica del componente Nox elegido.
Pasos de atestación de un componente Nox
En esta sección, detallamos el protocolo de verificación paso a paso aplicado a una sola CVM de componente Nox, y describimos qué muestra la UI una vez que cada comprobación ha pasado.

El protocolo de verificación aplicado a una CVM de componente Nox procede de la siguiente manera:
Obtén una cotización nueva: la interfaz genera un desafío aleatorio y obtiene, a través del agregador, una cotización nueva vinculada a ese desafío (ver Diagrama de secuencia ). Se espera que el desafío se inserte en el report_data del informe de la cotización.
Verificar la firma de la cotización y la cadena de certificados: la firma de la cotización y su cadena de certificados hasta Intel son validadas por un verificador DCAP. En la implementación actual, esto se ejecuta localmente en el navegador mediante un Phala dcap-qvl incrustado (biblioteca de verificación de cotizaciones: githubl). El qvl obtiene los datos de verificación (la información TCB y la cadena de certificados enraizada en Intel) desde el dstack PCCS (Servicio de almacenamiento en caché de certificados de aprovisionamiento alojado en Phala) y realiza la comprobación por sí mismo. En paralelo, la cotización se envía al servidor de Proof of Cloud trust, que informa si la máquina atestada pertenece a un parque en la nube incluido en una lista blanca (certificado). Este resultado de prueba de nube es informativo y no bloqueante: si el servidor de confianza no está disponible o agota el tiempo de espera, la atestación continúa.
Verificar la vigencia de la cotización: la vigencia de la cotización se confirma verificando que el desafío aleatorio generado por la interfaz se encuentra incrustado en el report_data de la cotización.
Mostrar valores RTMR: un paso informativo que extrae y muestra los valores RTMR de la cotización.
Reproducir RTMR3: los registros de eventos devueltos junto con la cotización (en la respuesta del agregador) se usan para reproducir RTMR3 siguiendo la fórmula de Intel: RTMR3_new = SHA384(RTMR3_old || SHA384(event_log)). Si el RTMR3 reproducido coincide con el atestado (en la cotización), los valores del registro de eventos os_image_hash y compose_hash pueden considerarse confiables como representaciones del sistema operativo ejecutado y del docker-compose ejecutado.
Verificar la imagen del sistema operativo: el registro de eventos RTMR3 del os_image_hash se extrae y se proporciona un enlace de descarga para que, si es necesario, la imagen y su hash puedan comprobarse manualmente. En iExec, esta imagen es dstackOS.
Verificar el hash de compose: se hace hash del docker-compose (app_compose, provisto en la respuesta del agregador) y el resultado se compara con el compose_hash incrustado como un registro de eventos RTMR3.
Una vez que se realizan estos pasos de verificación, el docker-compose correspondiente al compose-hash de la CVM atestada se muestra como se ve en la imagen de abajo.

El docker-compose de la CVM abarca tres servicios:
nox-component: el servicio empresarial ejecutado en la CVM (p. ej., nox-kms)
quote-service: el servicio usado para obtener la cotización y los registros de eventos requeridos para atestar la CVM
fluent-bit: servicio exportador de logs de iExec para observabilidad interna
Trabajo futuro
En esta sección, presentamos las mejoras planeadas para el flujo de atestación: procedencia de la imagen, desafíos proporcionados por el usuario y verificadores adicionales de cotizaciones.
Procedencia de la imagen
Hasta ahora, la atestación se detiene cuando mostramos el docker compose que lista las imágenes ejecutadas en la CVM atestada. Un siguiente paso es aprovechar la infraestructura de Sigstore para firmar el flujo de trabajo de GitHub Actions que generó cada imagen, durante su construcción, y publicar la atestación SLSA (Supply-chain Levels for Software Artifacts) identificada por el checksum sha256 de la imagen (subject-name) en GitHub y el registro docker de la imagen. Una entrada de Rekor también se enviará naturalmente. Al hacerlo, podremos ampliar los pasos de verificación mencionados en este artículo atestiguando el origen de cada imagen de Nox (es decir, el flujo de construcción y el commit del repositorio de GitHub).
Desafío ingresado por el usuario
Actualmente, para probar la vigencia de una cotización, usamos un desafío generado automáticamente que la UI transmite al agregador como un parámetro de consulta, el cual luego lo reenvía a cada servicio de cotización. Fortaleceremos este proceso permitiendo a los usuarios de la UI introducir su propio desafío para obtener un nivel adicional de confianza en la vigencia de la cotización.
Múltiples verificadores
Actualmente, usamos Phala qvl como el único método de verificación para comprobar la firma de Intel y la cadena de certificados de una cotización. Agregaremos métodos de verificación adicionales, ya sea como respaldos o como comprobaciones obligatorias si están disponibles, para mejorar la confianza en el resultado de la verificación. Los posibles verificadores a añadir son dstack-verifier alojado en iExec y Intel Trust Authority.

