Security
The architecture is the security model.
This page says what we actually do, in plain terms, including what we do not have yet. Every claim here is checked against the running system before it is published.
What we never receive
Most age verification means an ID document or a selfie, so the vendor ends up holding identity data. Tessio asks the EU Digital Identity Wallet for one claim, such as being over 18. 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 retention policy to audit, because the identity data 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 outcomes: a yes or no per check, with your reference and timestamps. No personal data of the person being checked.
Your account: dashboard user emails and passwords. Passwords are hashed with Argon2id. Session tokens are 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. Data does not leave 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 independent layers, all inside the EU: a daily whole server snapshot, a nightly database dump kept on the server for 14 days, and an encrypted copy of every dump on separate storage that 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
Stated here because you would find out 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: most of what those audits cover does not exist here to audit, because we do not hold identity data.
- 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, which is true of every relying party in Europe right now. 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, optional for a verifier to accept, and 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 respond quickly. 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