Pillar 4 / Cryptographic proof-of-residency ledger
A signed receipt for every inference, checkable by anyone.
Each response carries an Ed25519 signature over where the request went and why. Receipts become leaves in an hourly SHA-256 Merkle tree with a published root, so an auditor verifies inclusion offline without trusting YTT Secunet.
Response header / eu-central
x-ytt-proof-signature: eyJhbGciOiJFZERTQSIs.eyJ2IjoyLCJyZXF1ZXN0._O9pOfHIlZjwm_4a
pack eu-gdpr-strict@4.2.0 allow
route ep_scw_par / fr-par / FR-PAR-1
leaf 418,207 of 913,604 / eu 09:00Z
verify signature OK, inclusion OK
Three real receipts in compact JWS form: an EU allow, a Swiss request signed with a customer-held key, and a signed denial. The inspector splits each into its three base64url segments, decodes header and payload, and verifies the Ed25519 signature in your browser. Change one field and watch the check fail.
x-ytt-proof-signature: eyJhbGciOiJFZERTQSIsImtpZCI6Imp1cmlzcm91dGUtZXUtMjAyNnE0IiwidHlwIjoianItcmVjZWlwdCtqd3MifQ.eyJ2IjoyLCJyZXF1ZXN0X3NoYTI1NiI6IjVkOTdlMmJjMjllNDkwNzIwZDJkZjQyYzFhMmMxYTAzMWZiOWE3NTRiOTIwMTE0Y2U3OWIyZjk1MDExOTVlYjQiLCJ0ZW5hbnQiOiJ0bnRfZGVfNDQxNyIsInBvbGljeSI6eyJwYWNrIjoiZXUtZ2Rwci1zdHJpY3QiLCJ2ZXJzaW9uIjoiNC4yLjAiLCJkZWNpc2lvbiI6ImFsbG93In0sImVuZHBvaW50IjoiZXBfc2N3X3BhciIsInByb3ZpZGVyX3JlZ2lvbiI6ImZyLXBhciIsImZhY2lsaXR5IjoiRlItUEFSLTEiLCJqdXJpc2RpY3Rpb24iOiJFVSIsInVwc3RyZWFtX2NlcnRfc2hhMjU2IjoiZTU5MWQyOTUwNDhjNzk0ZTI4M2U2ZDk2NzAyOGExOTBjZmFjYTQyZDMzZmFlNTVmOTA5ZTBlNmI1ZWE1Njc3MSIsIm1vZGVsIjoibGxhbWEtMy4zLTcwYi1pbnN0cnVjdCIsInpkciI6dHJ1ZSwidHMiOiIyMDI2LTExLTA2VDA5OjQxOjI3LjMxOFoifQ._O9pOfHIlZjwm_4achH5OhRSmcRaIiWUvtsfs1bjN17URWyy7YSbytLd4OBjabgDms41E0MRGw1_FL5Te8zJCw
Segment 1 / JOSE header
{
"alg": "EdDSA",
"kid": "jurisroute-eu-2026q4",
"typ": "jr-receipt+jws"
}Segment 3 / Signature
- alg
- EdDSA (Ed25519, RFC 8037)
- signer
- YTT Secunet EU signing key
- bytes
- 64
Checked in your browser with WebCrypto against the public key for yttsecunet-eu-2026q4, over the exact bytes header.payload.
| Field | Value | What it establishes |
|---|---|---|
| v | 2 | Receipt schema version. The verifier refuses versions it does not know. |
| request_sha256 | 5d97e2bc29e490720d2df42c1a2c1a031fb9a754b920114ce79b2f9501195eb4 | SHA-256 of the canonicalised request. The prompt itself is never in the ledger. |
| tenant | tnt_de_4417 | Tenant whose domicile and pack drove the decision. |
| policy.pack | eu-gdpr-strict | Policy pack that evaluated the request. |
| policy.version | 4.2.0 | Exact pack version, pinned by X-YTT-Policy. |
| policy.decision | allow | allow or deny. Denials are receipted too. |
| endpoint | ep_scw_par | Registry id of the resolved endpoint. |
| provider_region | fr-par | The provider's own region identifier for that endpoint. |
| facility | FR-PAR-1 | Registry facility code: country, metro, site. |
| jurisdiction | EU | Legal zone the endpoint belongs to. |
| upstream_cert_sha256 | e591d295048c794e283e6d967028a190cfaca42d33fae55f909e0e6b5ea56771 | Thumbprint of the certificate the gateway validated in the TLS 1.3 handshake. |
| model | llama-3.3-70b-instruct | Model id sent upstream (or requested, on a deny). |
| zdr | true | Zero data retention attested for the endpoint at decision time. |
| ts | 2026-11-06T09:41:27.318Z | Gateway timestamp, UTC, millisecond precision. |
Checking the signature against the published key.
From routing decision to published root
- 01
Decide
The policy pack evaluates the request and the router resolves an in-zone endpoint, or denies.
- 02
Connect
TLS 1.3 handshake with the upstream. The certificate is validated and its SHA-256 thumbprint recorded.
- 03
Mint
The receipt is built with a fixed field order. The request is hashed; the prompt is not copied.
- 04
Sign
Ed25519 compact JWS with the zone key, or with your HSM-held key on Sovereign Dedicated.
- 05
Return
X-YTT-Proof-Signature on the response; on streamed responses it arrives as a trailer.
- 06
Commit
H(0x00 || receipt) becomes a leaf in the zone's tree for the current hour.
- 07
Publish
At the top of the hour the root is signed, published and copied into your tenant export.
Steps 1 to 5 happen inside the request and count toward the gateway's 8 ms p99 budget. Steps 6 and 7 are off the request path.
The EU zone committed 913,604 receipts between 09:00 and 10:00 UTC. To show the first receipt above is one of them, you need 20 sibling hashes, not the other 913,603 receipts. Each level hashes 0x01 || left || right; leaves use a 0x00 prefix, following the RFC 6962 construction, so an interior node can never pass as a leaf.
- zone
- eu
- hour
- 2026-11-06T09:00Z
- leaf
- 418,207
- tree_size
- 913,604
- leafH(0x00 || receipt) = computing
- 00726400140d..0182a1...
- 01233f824c13..323ecb...
- 026b0771ed2d..aa280a...
- 0307d2620468..058b56...
- 04e60c528b53..086bba...
- 05...e85927c507..21906b
- 06...1eaffe2efc..b8a8aa
- 0759b90369a5..8040d6...
- 08b0d5f03ac4..944610...
- 09...d20a28de3e..18789e
- 10...61629e23b5..0714cb
- 11...7186522e60..c91408
- 12...107cd1ff36..df922c
- 13cce152b1e9..51aa34...
- 147f8d4cf5e9..6515cc...
- 15...067d4e2693..a51252
- 16...d0ef736a4f..d0ada9
- 1766238bafee..2e4d32...
- 18d8597a9ecc..3549ba...
- 19...00f703d2f8..71f450
computed root computing
published root c491873cfc541f04da65aeed03d719388c454ddec457f2f9bcec8bce4daec0e5
Hashing with WebCrypto...
The verifier is open source and deliberately small, so an auditor's own engineer can read all of it. It checks the JWS signature against a pinned public key, recomputes the leaf hash, walks the inclusion proof, compares the result with the hourly root and checks the root's own signature.
It makes no network calls. A supervisory authority can run it on an air-gapped machine against a bundle the controller exported, and reach the same result YTT Secunet would. Unknown receipt versions are refused rather than guessed at, because canonicalisation is where schemes like this usually break.
Pin keys out of band. Public keys are published per zone and quarter, and on Sovereign Dedicated the key is yours, so the auditor can take it from your key ceremony record rather than from us.
# 1. One receipt, copied from a response header
ytt-verify receipt \
--jws receipts/7f3a2c.jws \
--pubkey keys/yttsecunet-eu-2026q4.pub
# receipt OK EdDSA kid=yttsecunet-eu-2026q4 decision=allow jurisdiction=EU
# 2. Inclusion in the published 09:00 root for the EU zone
ytt-verify inclusion \
--receipt receipts/7f3a2c.jws \
--proof proofs/7f3a2c.json \
--root roots/eu-2026-11-06T09.json \
--pubkey keys/yttsecunet-eu-2026q4.pub
# inclusion OK leaf 418207 / tree_size 913604 / 20 hashes
# 3. A whole DPA export, stop at the first mismatch
ytt-verify batch \
--bundle dpa-export-2026-10.tar.gz \
--pubkey keys/yttsecunet-eu-2026q4.pub --strict| Question | Receipt answers it | Basis, or what else you need |
|---|---|---|
| Was this request routed to an endpoint inside the allowed jurisdiction? | yes | The signed receipt names the jurisdiction, endpoint, provider region id and facility, minted at routing time. |
| Which policy pack, and which version, made the decision? | yes | Pack id and version are in the payload. Your Git history shows what that version contained. |
| Did the connection actually go to the endpoint named? | yes | Compare upstream_cert_sha256 with the certificate the registry pinned for that endpoint. A receipt naming one endpoint while the TLS session went to another does not match. |
| Was a receipt altered or back-dated after publication? | yes | Its inclusion proof will not reproduce a root you mirrored at the time. Any edit changes every hash up to the root. |
| Did YTT Secunet leave requests out of the ledger? | partly | Each hourly root commits to a tree_size. Reconcile it with your own request counts per tenant and hour; a gap shows up as a count mismatch, not as a missing hash. |
| Did the provider process the request only inside that facility? | no | A receipt shows where YTT Secunet sent the request, not what happened inside the provider. That rests on the provider's contract, certifications and, where offered, hardware attestation. |
| Did the provider retain the prompt? | no | zdr records the retention terms attested for the endpoint at decision time. It is not an observation of the provider's storage. |
| Is the processing lawful under the GDPR or the AI Act? | no | Lawful basis, DPIA and transfer impact assessment remain the controller's. Receipts are evidence for those documents, not a substitute. |
In short: a receipt proves where YTT Secunet routed a request and under which policy version, and that the record has not changed since publication. It does not prove legal compliance, and we would rather say so here than have an auditor say it for us.
- 20 hashes
- prove inclusion in a tree of up to 1,048,576 receipts; proof length grows with log2 of the tree size
- RFC 6962 Merkle tree construction
- 64 bytes
- per Ed25519 signature, deterministic, with no per-signature nonce to get wrong
- RFC 8032, used in JWS via RFC 8037
- 1 root / hour
- per zone, signed, published and copied into every tenant's export
- YTT Secunet proof ledger design
- < 8 ms
- p99 added gateway latency, policy evaluation plus receipt minting
- YTT Secunet production telemetry, 2026
Does a receipt prove that we comply with the GDPR?
No. It proves where a request was routed and under which policy, with a signature and a Merkle commitment that make later edits detectable. Compliance also depends on lawful basis, transparency, your DPIA, your transfer impact assessment and the provider's own conduct. Receipts are strong evidence for the technical part of those documents.
What stops YTT Secunet from rewriting old receipts?
Publication. Each hourly root is published and copied into your tenant export as it is produced, and you can mirror it into your own storage or a timestamping service. Once you hold a root, a rewritten receipt under it cannot produce a matching inclusion proof.
Who holds the signing keys?
On Growth and Enterprise Sovereign, receipts are signed with per-zone YTT Secunet keys that rotate quarterly; the kid in the JWS header names the key. On Sovereign Dedicated the signing key sits in your HSM, so receipts for your traffic cannot be produced without your key.
Is any prompt content in the ledger?
No. The receipt carries a SHA-256 hash of the canonicalised request. Prompts and completions stream through memory and are never written to disk, so the ledger holds metadata and hashes only.
Do auditors need access to YTT Secunet to verify?
No. ytt-verify is open source and runs offline. Given a receipt, its inclusion proof, the hourly root and the public key, it checks everything locally, which means an auditor can run it on an air-gapped laptop against a bundle you exported.
How long are receipts kept?
90 days on Growth and 7 years on Enterprise Sovereign. On Sovereign Dedicated the ledger is stored in your environment under your own retention policy. Exports you take remain valid evidence after the retention window, because verification only needs the bundle and the public key.
Sovereign route ready
Stop risking 4% global turnover GDPR fines on AI inference.
Deploy sovereign, cryptographically proven AI routing in 15 minutes.