Skip to content

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

Receipt inspector: decode the header, then try to tamper with it

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.

HTTP/2 200 response headerVerifying

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
fcef6939f1c89598f09bfe1a7211f93a145299c45a222594bedb1fb356e3375ed4456cb2ed849bcad2dde0e06369b8039ace351343111b0d7f14be537bccc90b

Checked in your browser with WebCrypto against the public key for yttsecunet-eu-2026q4, over the exact bytes header.payload.

Segment 2 / Payload (receipt v2)
FieldValueWhat it establishes
v2Receipt schema version. The verifier refuses versions it does not know.
request_sha2565d97e2bc29e490720d2df42c1a2c1a031fb9a754b920114ce79b2f9501195eb4SHA-256 of the canonicalised request. The prompt itself is never in the ledger.
tenanttnt_de_4417Tenant whose domicile and pack drove the decision.
policy.packeu-gdpr-strictPolicy pack that evaluated the request.
policy.version4.2.0Exact pack version, pinned by X-YTT-Policy.
policy.decisionallowallow or deny. Denials are receipted too.
endpointep_scw_parRegistry id of the resolved endpoint.
provider_regionfr-parThe provider's own region identifier for that endpoint.
facilityFR-PAR-1Registry facility code: country, metro, site.
jurisdictionEULegal zone the endpoint belongs to.
upstream_cert_sha256e591d295048c794e283e6d967028a190cfaca42d33fae55f909e0e6b5ea56771Thumbprint of the certificate the gateway validated in the TLS 1.3 handshake.
modelllama-3.3-70b-instructModel id sent upstream (or requested, on a deny).
zdrtrueZero data retention attested for the endpoint at decision time.
ts2026-11-06T09:41:27.318ZGateway timestamp, UTC, millisecond precision.

Checking the signature against the published key.

From routing decision to published root

  1. 01

    Decide

    The policy pack evaluates the request and the router resolves an in-zone endpoint, or denies.

  2. 02

    Connect

    TLS 1.3 handshake with the upstream. The certificate is validated and its SHA-256 thumbprint recorded.

  3. 03

    Mint

    The receipt is built with a fixed field order. The request is hashed; the prompt is not copied.

  4. 04

    Sign

    Ed25519 compact JWS with the zone key, or with your HSM-held key on Sovereign Dedicated.

  5. 05

    Return

    X-YTT-Proof-Signature on the response; on streamed responses it arrives as a trailer.

  6. 06

    Commit

    H(0x00 || receipt) becomes a leaf in the zone's tree for the current hour.

  7. 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.

Merkle inclusion path for one receipt

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
LevelLeft childRight child
  1. leafH(0x00 || receipt) = computing
  2. 00726400140d..0182a1...
  3. 01233f824c13..323ecb...
  4. 026b0771ed2d..aa280a...
  5. 0307d2620468..058b56...
  6. 04e60c528b53..086bba...
  7. 05...e85927c507..21906b
  8. 06...1eaffe2efc..b8a8aa
  9. 0759b90369a5..8040d6...
  10. 08b0d5f03ac4..944610...
  11. 09...d20a28de3e..18789e
  12. 10...61629e23b5..0714cb
  13. 11...7186522e60..c91408
  14. 12...107cd1ff36..df922c
  15. 13cce152b1e9..51aa34...
  16. 147f8d4cf5e9..6515cc...
  17. 15...067d4e2693..a51252
  18. 16...d0ef736a4f..d0ada9
  19. 1766238bafee..2e4d32...
  20. 18d8597a9ecc..3549ba...
  21. 19...00f703d2f8..71f450

computed root computing

published root c491873cfc541f04da65aeed03d719388c454ddec457f2f9bcec8bce4daec0e5

Hashing with WebCrypto...

Verify offline with ytt-verify

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.

bashauditor laptop, no network
# 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

What an auditor can and cannot conclude from a receipt

QuestionReceipt answers itBasis, or what else you need
Was this request routed to an endpoint inside the allowed jurisdiction?yesThe signed receipt names the jurisdiction, endpoint, provider region id and facility, minted at routing time.
Which policy pack, and which version, made the decision?yesPack id and version are in the payload. Your Git history shows what that version contained.
Did the connection actually go to the endpoint named?yesCompare 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?yesIts 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?partlyEach 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?noA 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?nozdr 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?noLawful 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

Frequently asked questions

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.