Skip to main content
Most “cloud KMS” services let the cloud provider authorize key release. Phala’s On-Chain KMS replaces that backend with a smart contract on a public blockchain. The KMS will only release keys to a CVM whose attestation matches what’s whitelisted on-chain — and Lit Protocol cannot change the whitelist unilaterally. This page explains what’s on-chain, how to read it, and what “active” looks like.

Why On-Chain KMS

Without on-chain KMS, a TEE provider’s backend decides which CVMs get keys. That’s one trusted party. With on-chain KMS:
  • No central authority. A smart contract is the only thing that can authorize key release. Phala’s backend does not sign transactions on Lit’s behalf.
  • Public, auditable governance. Every code-version whitelist change is a Base transaction. Anyone can read the history on Basescan.
  • Multi-party control. The contract owner is a Safe multisig of Lit signers — no single party (including Lit) can change the whitelist alone.
For the canonical design, see Phala: Understanding On-Chain KMS and Cloud vs On-Chain KMS.

The contracts

Two contracts on Base together gate key release for the Lit Chipotle CVM:

Phala KMS — 0x2f83…Ba9C

A shared Phala contract that maintains the registry of KMS nodes, approved dstack OS images, and approved KMS aggregated measurements. It also acts as a factory for per-application DstackApp contracts.

DstackApp — 0x3F91…05FfC

The application-specific contract for Lit Chipotle. Its address is the app_id returned by GET /info. Anyone can confirm this matches:

How key release is gated

The flow on every CVM boot:
  1. The CVM generates an Intel TDX attestation quote covering its hardware, OS, and the compose hash of the code it loaded.
  2. The KMS verifies the quote against Intel’s root certificates.
  3. The KMS reads the on-chain state:
    • Is the OS image in Phala KMS.allowedOsImages?
    • Is the KMS measurement in Phala KMS.kmsAllowedAggregatedMrs?
    • Is the compose hash in DstackApp.allowedComposeHashes?
    • Is the device ID in DstackApp.allowedDeviceIds?
  4. Only if all four pass does the KMS release the keys this CVM is allowed to use.
This means: even if Lit Protocol pushed a malicious Docker image, the CVM running it would not be able to obtain the root keys unless the new compose hash was first whitelisted on Base — which requires Safe signers to approve a transaction visible on Basescan.

Confirming the KMS is active

“Active” for on-chain KMS means three things hold simultaneously. You can verify each on Basescan or with cast.

1. The live compose hash is whitelisted

A true here proves the currently-running code is authorized by on-chain governance. A false would mean the CVM is running code that the KMS would refuse to release keys to — which should never happen in production, because the CVM cannot boot without keys.

2. The DstackApp owner is the Safe multisig

This proves no single party can modify the compose-hash whitelist. The Safe at 0xF688…1098 requires multiple signers to approve any change.

3. The CVM’s app_id matches the DstackApp address

The two must match (case-insensitive). This proves the CVM you’re talking to is actually attached to the on-chain governance contract you’re auditing — not some other lookalike contract.

Auditing the governance history

Every governance action that changed the KMS configuration is a Base transaction. On the DstackApp’s Basescan page, the Transactions tab shows every addComposeHash and removeComposeHash call ever made. Each is a Safe execution requiring multiple signatures. To understand a specific deployment:
  1. Find the deployment date in Lit’s release notes (or git log).
  2. Find the addComposeHash transaction on Basescan around that date.
  3. Open the Safe transaction (linked from the Basescan tx) — you can see which signers approved it.
This is the same audit trail used by the Phala Trust Center when it shows the on-chain governance state.

What’s next