Skip to content

System overview

A Calimero 1.0 cluster is a set of merod nodes, each a TDX confidential VM running a signed mero-tee image. Each app instance is replicated by its own Raft log on a few of them (three by default): the leader runs a call and appends its outcome, the followers apply it. A system log holds the accounts, passkeys, API keys, organizations, packages and the app directory.

Any node answers any request. One that does not hold the app forwards the call to the app’s leader over a peer channel attested the same way.

CalimeroClient is one object per node URL. What it does for each request:

Step What Where
Attest (once per node key) GET /attestation?nonce=…, then verify the quote against policy fetchAttestedKey (src/cloud-v2/attestation.ts)
Open a session Noise NK to the attested transport key, POST /sealed/v2/handshake createSealedFetch (src/sealed/sealed.ts)
Send the request, its Authorization header and body sealed in POST /sealed/v2; the answer comes back in sealed frames, event streams too the same
Map the answer a refusal becomes a typed error errorFrom (src/cloud-v2/errors.ts)
Retry a 503 or a dropped connection, for calls and views, with the same idempotency key CalimeroClient

A node that restarts has a new transport key; the client attests it again, through the same policy, and resends once.

  • The release. The node names the mero-tee release it runs. The client refuses one below minReleaseVersion, fetches the release’s signed published-mrtds.json and checks its Sigstore signature against the mero-tee release workflow.
  • The quote. Intel’s signature chain and the TCB status, through @phala/dcap-qvl with Intel’s collateral; no debug TD; the registers of the release’s locked-read-only image.
  • The binding. The quote’s report data is the client’s nonce and SHA-256("calimero.tee-attest.transport-key.v1" ‖ app_hash ‖ transport_key), so the key the channel opens to is the one the TD made.

The server serving the release file, the network and the node’s choice of release are not trusted. See Trust and the sealed channel.

All of it is inside the sealed channel except /attestation and /health:

  • /auth/*: passkeys, sessions, API keys, aliases, the account’s approvals and usage.
  • /packages/* and /bundles: signed releases, and raw WASM on development clusters.
  • /apps/*: instances, calls (intents), views, events, blobs, presence, upgrades, access.
  • /orgs/* and /invites/*: organizations, teams, members, invites, upgrade runs, approvals.

/ops/* is the operator’s API, authenticated by an ops token; this client does not cover it (core’s meroctl does).