Concepts
Cluster. A Calimero 1.0 deployment is a cluster of merod nodes running in
Intel TDX. Each app instance is replicated by its own Raft log across them, so
any node answers for any app. client.apps.call commits through the log;
client.apps.view reads, strongly by default, or with consistency="stale"
from any replica at least as new as min_index.
Attestation. Before trusting a node, the client verifies its TDX quote. A
real quote is accepted only from an image that a signed mero-tee release lists
under one of tee_profiles (min_release sets a floor; debug profiles are
refused unless allow_debug_profiles=True). Development clusters serve mock
quotes, accepted only with allow_mock=True. app_hash also pins the bundle
the quote must bind.
Sealed channel. Requests are encrypted to the attested node’s key, so a TLS proxy in front of the node sees nothing.
The API, generated. Every route of the node’s API is a method on Client,
generated from core’s OpenAPI document: client.<group>.<method>(...), with
keyword arguments and a typed answer (see
using the client). The attestation, the sealed channel,
the passkey ceremonies and the event streams are hand-written, since they are
more than one route.
Accounts and passkeys. An account signs in with a WebAuthn passkey
(sign_up, sign_in, add_passkey). SoftPasskey is an in-memory one for
scripts and tests. Sensitive operations, and methods an app marks confirm,
answer 412 CONFIRM_REQUIRED first and need a fresh passkey assertion over
that exact request. The client answers with confirm=passkey, or with the
passkey set by use_passkey.
API keys. Services authenticate with cal_... keys
(client.auth.apikey_create, then use_api_key). A key can be scoped to apps
and methods, read-only, or time-limited. An upgrade key signs one app’s
upgrades in place of a passkey, for CI.
Apps. An app is a WebAssembly bundle (client.packages.bundle_put) or a
release of an installed package, instantiated with client.apps.create.
Access belongs to the owner, an organization, a team, a list of accounts, or
everyone (client.apps.access). An upgrade (client.apps.upgrade) changes
code only: the app moves to any newer release in one step, and its state stays
as the old code wrote it. A node whose runtime is older than the release’s
minRuntimeVersion refuses it with 409 RUNTIME_TOO_OLD. The app’s report
names the newest release it can reach (latestReachable) and why the latest
is not that one (latestBlocked).
Organizations and teams. v1’s namespaces are organizations and its groups
are teams. An organization’s members have roles (guest, member, admin,
owner). Teams nest, are joined by invite or open to everyone who reaches the
parent, and hold apps.
The operator. The operator runs the cluster through client.ops, with the
node’s ops token as the API key. Its decisions answer 428 OPERATOR_SIGNATURE_REQUIRED until they are signed with the operator’s Ed25519
key (use_operator_key, use_operator_signer or operator_proof=). The Ops
API has no read path into apps’ data.