Architecture
The architecture of Enclave OS Virtual, running OCI containers inside Confidential VMs with end-to-end attestation via RA-TLS.
Enclave OS Virtual runs OCI containers inside Intel TDX (or AMD SEV-SNP) Confidential VMs with end-to-end attestation. Every container image digest, environment variable, volume mount, and platform configuration is measured into a deterministic Merkle tree and carried in X.509 certificate extensions via RA-TLS. Clients can verify the full workload stack on a single TLS connection: the certificate identifies the workload, the evidence exchange proves it.
High-Level Topology
┌────────────────────────────────────────────────────────┐
│ Intel TDX / AMD SEV-SNP Confidential VM │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Enclave OS (Virtual) │ │
│ │ │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ │ │ ra-tls- │ │ Workload │ │ Management │ │ │
│ │ │ caddy │ │ Launcher │ │ Server │ │ │
│ │ │ (TLS + │ │ (containerd│ │ (HTTP on │ │ │
│ │ │ reverse │ │ lifecycle)│ │ localhost)│ │ │
│ │ │ proxy) │ │ │ │ │ │ │
│ │ └─────┬──────┘ └─────┬──────┘ └────────────┘ │ │
│ │ │ │ │ │
│ │ │ ┌──────────┴──────────┐ │ │
│ │ │ │ containerd │ │ │
│ │ │ └──────────┬──────────┘ │ │
│ │ │ ┌──────────┴──────────┐ │ │
│ │ └────┤ OCI Containers │ │ │
│ │ │ ┌─────┐ ┌──────┐ │ │ │
│ │ │ │App │ │ DB │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ └─────┘ └──────┘ │ │ │
│ │ └─────────────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ dm-verity root │ measured boot (RTMRs) │ erofs rootfs │
└────────────────────────────────────────────────────────┘Three components run inside the Confidential VM:
- Caddy RA-TLS is a Caddy server with a custom TLS issuance module that generates RA-TLS certificates. It acts as a reverse proxy, terminating TLS at the edge and forwarding plaintext to containers on localhost. Each container gets its own hostname and its own RA-TLS certificate with per-container OID extensions.
- Workload Launcher manages the OCI container lifecycle via containerd. It pulls digest-pinned images, creates containers, runs health checks, and wires up Caddy routes dynamically.
- Management Server exposes an HTTP API on localhost for loading and unloading containers at runtime, authenticated via OIDC bearer tokens. It also serves health, readiness, status, and Prometheus metrics endpoints over RA-TLS.
How It Works
-
Boot. The VM starts from a dm-verity protected, fully measured image built with the Privasys cvm-images project. Every boot stage is measured into the TDX RTMRs, and every byte of the root filesystem is verified against a hash tree whose root is part of the measurement.
-
Dynamic loading. The manager starts with zero containers. Operators call
POST /api/v1/containers(authenticated via OIDC bearer token) to load containers at runtime. Each request specifies a digest-pinned OCI image reference, environment variables, volumes, and ports. -
Pull and verify. OCI images are pulled via containerd. Each image digest is verified against the pinned
@sha256:...reference in the load request. -
Merkle tree. A platform Merkle tree and per-container Merkle trees are recomputed after every load or unload. Leaves include the CA certificate, image digests, environment variables, volume configuration, and runtime version.
-
RA-TLS certificates. The Merkle roots and container metadata are embedded as X.509 extensions in RA-TLS certificates. The TDX quote is not in the certificate: it is served on the connection by the evidence exchange and bound to the certificate's key.
-
TLS handshake and evidence. Clients connecting via TLS receive a certificate chain that states which OS image booted, which containers are deployed (by digest), and how they are configured; the evidence exchange then proves which TEE is running and that the certificate key lives inside it.
-
Health and metrics. The management API exposes
/healthz,/readyz,/api/v1/status, and Prometheus/metricsover RA-TLS atmanager.<machine-name>.<hostname>. -
Trusted time. The manager never reads the guest's host-steered clock for a security decision. Token and voucher windows, quote freshness, certificate validity and peer verdicts read a trusted time, confirmed against the platform monitor's signed polls and NTS servers. Caddy's RA-TLS module takes its issuing time from the manager over a root-only local socket.
RA-TLS via Caddy
The RA-TLS module is a Caddy tls.issuance module that generates RA-TLS certificates inside the Confidential VM. It serves the same deterministic and challenge evidence exchange as Enclave OS Mini.
The module abstracts hardware-specific logic behind an Attester interface. Each TEE backend (TDX, SEV-SNP) lives in its own file and registers itself at init time.
Supported Backends
| Backend | Hardware | Status |
|---|---|---|
tdx | Intel TDX | Supported |
sev-snp | AMD SEV-SNP | Planned |
How Certificates Are Generated
Certificate (per hostname, 24 hours):
- An ECDSA P-256 key pair is generated inside the TEE.
- An X.509 certificate carrying the OID extensions is signed by the operator-provisioned intermediary CA. It carries no quote.
- The certificate is cached by certmagic and renewed every 24 hours; the key is kept across re-mints that change only extension values.
Evidence (on request, POST /__privasys/attest):
- The module checks that the request's
leafnames a key it holds. - Deterministic mode: the cached quote for that key is served, minted once with
report_data = SHA-512( SHA-256(SPKI_DER) || quote_time ), whereSPKI_DERis the DER-encodedSubjectPublicKeyInfoof the leaf public key andquote_timeis the minting minute carried in the response. - Challenge mode:
hctxis derived from the connection's TLS exporter with the client's 32-bytecontext, and a fresh quote is obtained from the configured backend (/sys/kernel/config/tsm/reportfor TDX) withreport_data = SHA-512( SHA-256(SPKI_DER) || context || hctx ). - The response is served and the connection is tagged
X-Privasys-Attestation: deterministicorchallenge.
SNI-Based Routing
Each container gets its own hostname derived from the workload manifest:
- Management API:
manager.<machine-name>.<hostname> - Container
myapp:myapp.<machine-name>.<hostname> - Internal containers (e.g. databases): no external hostname, accessible only on localhost
When a client connects, the RA-TLS module selects the certificate matching the SNI hostname. Each certificate carries per-container OID extensions (image digest, config Merkle root, volume encryption status).
Per-Container OID Extensions
Every container's RA-TLS certificate includes extensions specific to that container:
| OID | Name | Value |
|---|---|---|
1.3.6.1.4.1.65230.4.1 | Container App Id | Platform-assigned app identity (apps.id, raw 16-byte UUID), stamped by the measured manager (omitted when the platform supplied none) |
1.3.6.1.4.1.65230.4.2 | Container Image Digest | Raw SHA-256 digest of the OCI image |
1.3.6.1.4.1.65230.4.3 | Container Image Ref | Full OCI image reference string |
1.3.6.1.4.1.65230.5.1 | Container Config Merkle Root | SHA-256 root of the container's config tree |
1.3.6.1.4.1.65230.6.1 | Container Volume Key Source | "vault:<handle>" or "byok:<fingerprint>" (present only when an encrypted volume is attached) |
1.3.6.1.4.1.65230.7.1 | Attested Dependency Set | Canonical encoding of the container's pinned dependencies, stamped by the runtime |
The platform-level certificate (served for the management hostname) carries the platform OIDs (arcs 1 to 3) including the runtime version hash (OID 1.1), the image profile (OID 1.2), the combined workloads hash (OID 2.4), and the data encryption key origin (OID 3.1).
Requirements
- A Confidential VM running Intel TDX or AMD SEV-SNP
- A hardened base image with dm-verity and measured boot
- An intermediary CA certificate and private key (private PKI)
- An OIDC provider for management API authentication
- containerd installed on the VM
What to Read Next
- Containers and Workload Manifest: How containers are loaded, configured, and managed
- Hardened Guest Images: The dm-verity base image and trust chain from silicon to userland
- Disk Encryption: LUKS2+AEAD encryption for the OS data partition and per-container volumes
- Trusted Time: How the manager checks the host's clock before any verification decision