

The tempting shortcut
Confidential computing has become easy to buy. Every major cloud now offers confidential VMs: Intel TDX or AMD SEV-SNP machines whose memory the host cannot read. So when a customer asks for stronger guarantees about their data, the obvious move is to take the stack you already run and put it inside them.
It sounds like a weekend project. In practice it is the start of a long one, because a confidential VM protects one machine, and your app is ten.
This post walks through what "just put it in a TEE" turns into for a typical SaaS stack, and why Calimero takes a different shape: one attested node with every layer built in.
What a typical stack looks like
Take an ordinary multi-tenant product:
- a TLS-terminating load balancer or proxy;
- an API service and a handful of internal services;
- a database cluster, with replicas and failover;
- a queue and a cache;
- disks, snapshots and backups;
- a secrets manager holding the keys that tie it together.
Each of these is a place where customer data exists in plaintext at some point. A confidential VM around one of them protects that one. The data is still readable everywhere else it travels.
Moving it into TEEs, piece by piece
Here is what the exercise actually involves.
Every service needs its own attested image. Each one has to be built reproducibly, measured, and published with its measurements so that something can check it. Five services means five images to measure, attest and keep track of.
Every hop needs attested encryption. Plain TLS between services is not enough: a service must check that the peer it is talking to is the attested image it expects, not merely a host with a valid certificate. That means building attestation into every connection.
TLS still ends at a proxy. The load balancer in front usually runs outside any enclave. Unless you move termination inside, every request is readable at the edge.
The database is the hardest part. It holds every customer's data in one place. Sealing it means a confidential database with sealed replicas, encrypted failover, and encrypted backups whose keys only attested replicas can get.
Disks, snapshots and backups sit outside. They need their own encryption, with keys released only to attested machines.
You build the key service. Something has to decide which machine gets which key, based on attestation. That service must itself run in a TEE and be attested, or it becomes the weakest link.
Note: None of this is impossible. It is simply a platform team's worth of work, and it is work your customers never see.
The release problem
The cost does not stop once it is built. In a TEE, an image's measurements are its identity. Change the code and the measurements change. So every release of every service becomes a security change:
- Rebuild each service's sealed image.
- Publish new measurements for every image.
- Update attestation and key-release policies.
- Re-provision secrets to the new enclaves.
- Migrate the database inside its enclave.
- Repeat at every customer who runs their own copy.
A team that used to ship several times a day now has a security process wrapped around each deploy.
A different shape: one attested node
Calimero starts from the opposite end. Instead of sealing each tier, it puts every tier inside one node image, and runs that same node everywhere.
Inside every node:
| Layer | Who provides it |
|---|---|
| Frontend | You: your web UI, shipped inside the signed bundle |
| Application logic | You: your code, in Rust or JavaScript, compiled to WebAssembly |
| Runtime | Built in: a WebAssembly sandbox |
| Replicated state | Built in: each app instance replicated across attested nodes |
| Storage | Built in: encrypted at rest |
| Networking | Built in: encrypted, attested node-to-node connections |
| Identity and access | Built in: passkeys, organizations, teams, API keys |
| Sealed hardware | Built in: Intel TDX attestation |
There is one image to measure and attest, and one kind of node to add when you need capacity. Your part is the logic and the frontend, signed together into one bundle.
No central database to seal
The database problem goes away by not having a central database at all. A Calimero app is a sharded monolith: every node runs the whole app, and the app's data is split into app instances, one per customer, team or document, whatever unit fits your product.
Each app instance is replicated by its own Raft log across three or more attested nodes. Calls are applied in one order, reads can be strongly consistent, and the instance keeps serving when a node is lost. Instances are independent, so you scale by adding instances and nodes rather than growing one database.
That also changes the blast radius. In a shared database, one breach or outage reaches every tenant. Here, an app instance lives only on the attested nodes that replicate it.
Releases that don't touch attestation
A node's measurements cover the node image, not the apps on it. Your app ships as a signed bundle, and the node checks the publisher's signature before running it. So releasing a new version of your app:
- does not change node measurements or keys;
- needs no new attestation policies and no secrets to move;
- is one upgrade operation, applied on every node;
- migrates each app instance's data when that instance is upgraded, with the same result on every replica.
The app's owner approves the upgrade with a passkey, unless the deployment gives that decision to its operator. Shipping goes back to being a deploy, not a security review.
Sealed transport, end to end
The proxy problem is handled by the clients. The browser, Rust, Python and CLI clients verify a node's attestation before they send anything, then seal each request to a transport key that the node's hardware quote vouches for. That key is created inside the VM at start-up and never leaves it. There is no TLS proxy outside the enclave that can read traffic, because the session ends inside the node.
When DIY still makes sense
To be fair to the shortcut: if your sensitive workload is a single stateless service, with no database and few releases, wrapping it in a confidential VM may be all you need. The same goes for workloads that can't be expressed as WebAssembly apps, or teams that already run a mature confidential-computing platform of their own.
The DIY path gets expensive when the data is stateful, shared across tiers, released often and deployed at more than one customer. That is most SaaS products, and it is the case Calimero is built for.
Summary
| Question | Stack of TEEs | Calimero |
|---|---|---|
| Images to attest | One per service, database and key service | One node image |
| Where data lives | One central database for every tenant | Each app instance on its own attested replicas |
| Where TLS ends | Usually at a proxy outside the enclave | Inside the node, sealed to an attested key |
| Key service | Built and attested by you | Built in, itself attested |
| A release | New measurements, policies and secrets per service | One signed bundle, nothing to re-attest |
If you want to see how the pieces fit, read how it works, see how a node proves what it runs, or start on Calimero Cloud.