How the evidence chain works
Follow an event from its contents to a Merkle root and a signed receipt.
A new event. A commitment to the history.
With evidence signing enabled, each recorded event gets a hash: a fixed-length fingerprint of its contents. The SDK adds it to a Merkle tree, which combines the event fingerprints into one root. A device signature binds the new event, the previous root and the updated root together.
Four events → one Merkle root
Event 4 · signed receipt
- Event fingerprint
- payload hash
- Added to tree
- leaf hash
- Previous history
- root 3
- Updated history
- root 4
- Ledger position
- index 3 / count 4
Device signature binds these fields together
Verification needs a trusted signing key and the history your service expects. A valid signature protects the recorded contents; establishing their source, meaning, and relationship to a person requires separate checks. Detecting omitted later events requires an independently retained, authenticated checkpoint.
What is written and signed?
The SDK hashes the canonical event bytes with SHA-256, derives a leaf hash and appends that leaf to the local ledger. It computes the updated root over all ordered leaves. Existing leaves stay unchanged.
The device signs the receipt’s event hash, leaf hash, previous and updated roots, zero-based index and count. The signed payload also binds its schema version, signing time, key identity and platform assertion metadata. The first receipt has no previous root.
What does App Attest bind?
When an App Attest assertion is obtained, it binds the server challenge, event payload hash and device signing-key identity. The device signature then binds the Merkle roots and that assertion’s metadata into the receipt. The receipt records the platform state so verification can distinguish a local signature from a challenged platform assertion. Your service must validate the App Attest registration and assertion, challenge freshness, and replay protection. A recorded platform state alone does not establish server acceptance.
How does a verifier detect changed or missing history?
Recompute the event hashes and tree roots, verify device signatures, and check the linked roots and ledger positions. Changes to recorded contents or ordering break those checks against an authentic signed history. The evidence source establishes what an event means; cryptography establishes its integrity.
To detect a missing tail, retain a signed checkpoint outside the phone: its root and event count commit to how far the history had reached. The SDK can produce that checkpoint; the host must publish it to an external holder. Your service must authenticate its signature, establish trust in its signing key, and enforce the expected count and root. An independently retained, authenticated checkpoint makes an older, shorter history detectable.