What Should You Verify?
Basic verification: Confirm your application code (reportData and compose-hash) runs in genuine TEE hardware. Suitable for most use cases. Advanced verification: Everything from Basic, plus RTMR3 event log replay, on-chain governance checks, and source code provenance. Required for high-assurance applications (DeFi, confidential AI, sensitive data).Basic Verification
Verify your application code runs in genuine TEE hardware. This verification confirms:- Your specific data (reportData) is present in the quote
- Your application configuration (compose-hash) matches what’s deployed
- The quote comes from genuine Intel TDX hardware
This code runs on the verifier side (end users or auditors checking your CVM), not inside the CVM itself.
Prerequisites
Your application must expose attestation endpoints. See Get Attestation for how to set this up inside your CVM. Fetch all required data from your CVM:Step 1: Verify reportData
Check that reportData contains the expected challenge or public key:Step 2: Verify compose-hash
The compose-hash is a SHA256 hash of your app-compose.json configuration file (which includes your docker-compose.yaml plus metadata). This hash proves which exact Docker images are running. Verify the configuration you fetch from the CVM matches what’s attested in RTMR3:Step 3: Verify quote signature
Verify the TDX quote was signed by genuine Intel hardware. This uses Phala Cloud’s verification API (alternatively, you can use dcap-qvl locally for trustless verification):Advanced Verification
For high-assurance applications, verify additional security properties beyond Basic Verification:- RTMR3 event log replay: Cryptographically prove the boot sequence
- Docker image digests: Ensure images are pinned to specific versions
- On-chain governance: Verify only authorized configs can run
- Source code provenance: Link images back to audited source code
All verification steps must run outside the CVM. Only verification that happens outside the TEE provides security guarantees.
Prerequisites
Complete Basic Verification first. You’ll need the same data (quote, event_log, app_compose, calculated hash).Step 1: Verify RTMR3 event log replay
RTMR3 uses a hash chain where each event extends the previous value. The event log records three events during boot:compose-hash- Your application configurationinstance-id- Unique CVM instance identifierkey-provider- KMS that distributed encryption keys
RTMR3_new = SHA384(RTMR3_old || SHA384(event)).
To verify this:
- Parse the event log and extract all RTMR3 events (where
imr === 3) - Start with initial RTMR3 value (48 zero bytes)
- For each event digest in order:
- Pad digest to 48 bytes if needed
- Compute:
RTMR3 = SHA384(RTMR3 || digest)
- Compare final replayed RTMR3 with the
rtmr3value from the quote
TODO: The dstack SDK does not currently export a
replayRtmrs() utility function for external verifiers. For production use, refer to the Rust verification implementation or use trust-center for complete RTMR3 replay verification.Step 2: Verify Docker image digests
Docker images must be pinned by SHA256 digest, not mutable tags. Tags likenginx:latest can point to different images over time, breaking verification.
Verify all images in your app-compose use immutable digests:
Step 3: Verify on-chain governance (optional)
If your application uses on-chain governance, verify the compose-hash is whitelisted. This ensures only authorized application versions can boot:Step 4: Verify source code provenance
Link Docker image digests back to audited source code using cryptographic build provenance. Recommended: Sigstore for GitHub builds Sigstore cryptographically links container images to specific GitHub commits and workflows. When you build images via GitHub Actions, Sigstore automatically signs the build with GitHub’s identity, creating unforgeable proof. Platform components use Sigstore: Set up Sigstore signing in your GitHub Actions workflow to provide the same cryptographic build provenance for your applications. Alternative: Reproducible builds For maximum verifiability, use reproducible builds where anyone can rebuild from source and get identical digests. Publish your Dockerfile and build instructions. This requires careful environment control but removes the need to trust any build service.Attack Scenarios Prevented
Compromised Docker registry: The TEE verifies image digests against compose-hash before pulling. Even if the registry serves malicious images, digest verification fails. Code substitution: The compose-hash in RTMR3 is recorded by TEE hardware during boot. No one can modify it without invalidating the attestation quote signature. Unauthorized updates: On-chain governance (if enabled) ensures only whitelisted compose hashes can boot. Malicious developers cannot deploy unapproved versions. Event log tampering: RTMR3 event log replay cryptographically proves the events are authentic. Modification causes replay to produce different RTMR3 that won’t match the quote.Verification Checklist
Complete application verification requires checking:- All Docker images use SHA256 digests (not tags)
- Calculated compose-hash matches expected value
- RTMR3 event log replays to quoted RTMR3 value
- Attested compose-hash matches calculated hash
- compose-hash is whitelisted on-chain (if using governance)
- reportData contains expected challenge/public key
- Image digests link to audited source code (Sigstore or reproducible builds)
Tools and Resources
- dstack SDK -
getComposeHash()andreplayRtmrs()methods - RTMR3 Calculator - Web tool for compose-hash calculation
- Verification Script - Complete Python example
- trust-center - Reference implementation

