System Overview

mero-tee TEE infrastructure — 3 components, 6 endpoints, mutual attestation

3
components
6
API endpoints
3
image profiles
2
trust planes

High-Level Architecture

The mero-tee system secures Calimero node storage through hardware-attested key management. merod nodes run inside TDX confidential VMs. On boot, each node contacts the KMS to obtain its storage encryption key. The KMS validates the node’s TDX attestation before releasing the key via Phala dstack’s deterministic key derivation.

merod Nodes GCP TDX CVM Calimero peer-to-peer nodes Encrypted storage at rest TDX attestation on boot Built by Packer + Ansible Image profiles: debug | debug-ro | locked-ro mero-kms-phala TDX CVM Validates TDX attestations Challenge-response key release Policy enforcement (MRTD, RTMRs) Endpoints: /health /challenge /get-key /attest mero-kms-phala/ · Rust · Axum Phala dstack HW root Deterministic key derivation TDX quote generation Sealed storage root Unix socket at DSTACK_SOCKET_PATH HTTPS socket GitHub Releases Attestation policy JSON Versioned by MERO_KMS_VERSION tag fetch policy on boot Image Builder Packer (GCP) + Ansible provisioning Profiles set RTMR3 runtime events builds CVM image Attestation Verifier React SPA + /api/verify Public verification portal POST /attest Intel Trust Authority Quote verification & JWT issuance verify Peer-to-Peer Network Other merod nodes · gossipsub · sync
merod Nodes
KMS
dstack
Policy
Image Builder
Verifier
ITA

mero-kms-phala Deep Dive

The KMS is a stateless Rust HTTP service (Axum) that runs inside a TDX enclave alongside Phala dstack. Its sole purpose is to validate remote attestations and release deterministic storage encryption keys.

API Endpoints

GET /health
Readiness probe. Returns 200 when policy is loaded and service is ready.
POST /challenge
Accepts { peerId }. Returns { challengeId, nonce }. Nonce is cryptographically random, TTL-bound.
POST /get-key
Accepts { challengeId, quote, signature }. Validates signature, verifies TDX quote against policy, derives key via dstack. Returns encrypted key material.
POST /attest
Accepts { nonce }. Requests a TDX quote from dstack with nonce || report_data, returns the raw quote for remote verification.

Internal Architecture

AppState

Shared Axum state holding Config (from env) and ChallengeStore (InMemory or Redis). The store maps challengeId → (nonce, peerId, expiry).

Policy Engine

On startup, fetches attestation policy from GitHub releases (or env). Policy specifies allowed MRTD, RTMR0–3 values, TCB status allowlists, and profile constraints.

Key Modules

config.rs
Parses all environment variables into a typed Config struct. Validates required fields at startup.
policy.rs
Fetches, parses, and validates attestation policy JSON. Supports SHA-256 pinning via MERO_KMS_POLICY_SHA256.
challenge_store.rs
Trait-based challenge storage. InMemoryStore (default) or RedisStore when REDIS_URL is set.
runtime_event.rs
RTMR3 runtime event encoding for profile cohort separation.
handlers/challenge.rs
POST /challenge handler: generates nonce, stores challenge, returns response.
handlers/get_key.rs
POST /get-key handler: consumes challenge, verifies signature, checks quote, derives key.
handlers/attest.rs
POST /attest handler: self-attestation for the KMS itself.
handlers/errors.rs
Centralized ServiceError enum with Into<Response> for all error types.

Node Images

The mero-tee/ subfolder contains infrastructure-as-code for building GCP TDX confidential VM images. Packer defines the image, Ansible provisions the OS and merod binary.

Build Profiles

debug

Full SSH access, verbose logging, no read-only filesystem. For local development and testing. Writes a debug RTMR3 event.

development

debug-read-only

SSH access but read-only root filesystem. For staging validation. Writes a debug-read-only RTMR3 event.

staging

locked-read-only

No SSH, read-only filesystem, minimal attack surface. For production. Writes a locked-read-only RTMR3 event.

production

Each profile writes a distinct RTMR3 runtime event during boot. The KMS attestation policy specifies which RTMR3 values are acceptable, creating cryptographic cohort separation — a debug node can never obtain production keys.

Build Pipeline

1

Packer Init

GCP image builder provisions a Confidential VM instance with TDX guest support enabled.

2

Ansible Provision

Installs merod binary, systemd units, network config, and TDX guest tools. Sets profile marker at /etc/mero-kms/image-profile.

3

Image Seal

Captures the GCP image. The image hash becomes the MRTD measurement — any tampering changes the measurement and attestation fails.

Attestation Verifier

A public-facing web application that allows anyone to verify the attestation status of a Calimero KMS instance. Built with React and a serverless API backend.

Frontend (React SPA)

User enters a KMS URL. The app calls the verifier API which fetches a quote from the KMS and submits it to Intel Trust Authority for verification. Results are displayed with detailed attestation claims.

Backend (/api/verify)

Serverless function that: (1) calls POST /attest on the target KMS with a fresh nonce, (2) forwards the quote to Intel Trust Authority, (3) validates the ITA JWT response, (4) returns structured verification results.

Verification Chain

1

Browser → /api/verify

User submits KMS URL with binding data. Serverless function generates a nonce.

2

Verifier → KMS /attest

Serverless function calls the KMS POST /attest with the nonce.

3

KMS → dstack

KMS asks dstack to produce a TDX quote binding nonce || report_data.

4

Verifier → ITA

Quote is forwarded to Intel Trust Authority for cryptographic verification.

5

ITA → JWT

ITA returns a signed JWT with attestation claims (measurements, TCB level, advisory IDs).

6

Browser ← Results

Parsed JWT claims are returned to the browser and displayed in a human-readable format.