Security
The architecture is the security model.
This page says what we do, including what we do not have yet.
What we never receive
Many age checks ask for an ID document or a selfie, which means identity data passes through someone. Tessio asks for one claim (such as being over 18) and gets the answer from the EU age verification app (the EU Digital Identity Wallet follows once our access certificate is issued). The credential behind that answer, the EU age verification attestation, contains age booleans and nothing else: no name, no date of birth, no document number, no portrait.
That is the security model. There is no document store to breach and no identity data to retain, because it never crosses the wire. This is a property of the protocol, not a promise about our behaviour, which means you can verify it yourself instead of trusting us.
What we do store
Check records: a yes or no per check, with your reference, timestamps and how the check went: each step, the error codes of any failed attempt and which issuer, trusted list and certificate vouched for the credential. In Tessio.Cloud, deleted once your plan’s retention period has passed, as the privacy policy sets out. No name, date of birth, document or photo of the person being checked.
Your account: dashboard user emails and passwords, with passwords hashed with Argon2id and session tokens stored only as SHA-256 hashes.
API keys: shown to you once, then only a SHA-256 hash and a short prefix are stored. Keys are revocable from the dashboard.
An audit log of administrative actions in your account.
Two step verification is available on every dashboard account (TOTP, RFC 6238, with single use recovery codes). It is a gate rather than a prompt: until the second factor is presented, a correct password produces a session that authenticates nothing. Codes cannot be reused, and attempts are rate limited per account as well as per source address, so guessing cannot be widened by changing address.
Where it runs
Production runs on dedicated infrastructure in Helsinki, Finland (Hetzner), inside the EU. All traffic is TLS, and customer data is stored and processed in the EU.
Every tenant is isolated at the query level: each data access is scoped by tenant id, and cross tenant isolation is covered by automated tests that run on every change.
Webhooks you can verify
Webhook deliveries are signed with HMAC-SHA256 using your endpoint secret, with a timestamp in the signed payload so replays are detectable. The verification snippet is in the developer docs.
Endpoints must be HTTPS. A signature proves a delivery is genuine and unaltered, which is not the same as keeping it private, so we refuse plain HTTP endpoints rather than leaving that choice to you.
Availability and backups
Deploys are health gated with automatic rollback: a release that fails its health check never stays live.
Backups run in three layers, all inside the EU: a daily whole server snapshot, a nightly database dump kept on the server for 15 days and an encrypted copy of every dump on separate storage, kept for 15 days too, which takes its own daily snapshots.
The dumps are encrypted before they are written, and the key that decrypts them is deliberately not on the servers, so a backup cannot be read by anyone who compromises the machine that produced it. The restore path is not a theory: a production dump has been retrieved from the off site copy without involving the production server, decrypted and restored, with the result checked against expected contents.
Externally verifiable
The verifier underneath Tessio.Cloud is open source (Apache-2.0, on NuGet), so you can read exactly what it does. It passes the OpenID Foundation conformance suite for OpenID4VP 1.0 HAIP verifiers in both credential formats the EU wallet uses. We also run free validators for the EU identity ecosystem at labs.tessio.eu.
What we do not have yet
We list these gaps because you would find them anyway, and it is better coming from us.
- No SOC 2 or ISO 27001 certification. We are early, and we will certify when a customer's procurement requires it. Until then, this page and the open source code are offered in place of a report.
- EU Digital Identity Wallet verification is pending an access certificate. That wallet checks who is asking before releasing anything. We applied for the relying party access certificate on 5 August 2026 and do not yet hold it. The EU age verification app is a different path and does not require one, and that path completes real checks in production today.
- We verify standard attestations, not yet zero knowledge proofs. Both transports the age verification profile defines are live in production, and the verification page picks whichever the person's browser supports. The profile also describes a zero knowledge way to present the same attestation, and since release 1.1.0 of the specification a verifier is required to accept it. We do not verify those presentations yet. Ask us if that matters for your integration.
- One production issuer is live so far. A verifier decides whether an attestation is genuine by checking its signer against a published trusted list. Live checks anchor on the Commission's production list, which carries a single issuer today, so real coverage grows as member states publish theirs. Test checks anchor on the acceptance list, which is how sandbox integration works against the pilot's test issuers without those issuers ever passing a live check.
- Signup is open and a test project works as soon as you create one. Sending real traffic needs us to switch your organisation to live mode, so that part stays a conversation.
Reporting a vulnerability
Found something? Write to hello@tessio.eu and we will answer. The verifier is open source, so issues in it can also be reported on GitHub. We are a small team; you will be talking to the people who wrote the code.
Free validators for the EU identity ecosystem: labs.tessio.eu