Don’t take our word for it. Click it.
A running reference deployment in production mode, in two tiers. Tier 1 — bring your own EUDI wallet for the standard issue-and-present round-trip any conformant wallet can do. Tier 2 — the PSDP-protocol demos a generic wallet can’t run: an unlinkable cross-site age proof, a capped AI agent that gets denied at its limit, a real zero-knowledge over-18 proof, a passkey step-up, and a signed-credential login. Each demo says what it shows, and what it deliberately mocks.
Try it with your own EUDI wallet
The plain OID4VCI + OID4VP
round-trip, by QR — any conformant EUDI wallet can do
this. Issue a PID into your wallet, then present back just
age_over_18 with selective disclosure. Nothing here is
PSDP-specific; the interoperability is the point.
The full wallet round-trip, by QR
PSDP’s reference issuer mints a demo EU PID
(SD-JWT VC) over standard OID4VCI; you scan it into a
real EUDI wallet, then present it back over OID4VP
disclosing only age_over_18 — no date of birth. This
is the standard, interoperable flow:
any conformant EUDI wallet can run it (Sphereon and
Lissi complete the round-trip on this stack today).
Honest scope: this is a per-presentation check with holder key-binding — it is not the cross-relying-party-unlinkable PSDP proof. That one lives in Tier 2 below. Demo issuer, demo data — real signatures, no real-world proofing.
What a stock wallet can’t do
These run PSDP’s own circuits and protocol —
they show what a generic wallet can’t. Each one is keyless, runs on
this same stack under PSDP_PRODUCTION=1, and says what it
shows and what is simulated.
Same you, two sites — and they still can’t link you
Enter a date of birth, then “visit” Site A
and Site B. The page fires two
real Groth16/BN254 proofs against
POST /verify/age — same birthdate, two different
relying parties. Both come back over_age: true, but the two
rp_nullifier values are visibly different.
Each proof reveals only {issuer root, site-scoped nullifier, age ≥ 18} — never your date of birth — so even if Site A and Site B collude they cannot tell it’s the same person. Reference-grade: a single-party deterministic setup (not a ceremony), and in this self-contained demo the reference holder’s secret is reconstructed in-process server-side. The unlinkability property itself is modeled and machine-checked but partial overall — not “unlinkability-certified”. Two real proofs take about 10–20 seconds.
Prove you’re over 18 — real zero-knowledge
Pick a date of birth and mint a real Groth16/BN254
zero-knowledge proof against POST /verify/age,
right here, with no API key. The relying party learns one boolean
— age_over_18 — and a per-site nullifier; the
proof and receipt reveal no date of birth.
Reference-grade: the proving system uses a single-party deterministic trusted setup — not a multi-party ceremony — so it is not production-secure against a determined forger. A real proof takes about 10–15 seconds; that is the honest cost of real ZK.
Hand an AI agent a capped wallet — watch it get denied at the cap
Issue a key-bound, attenuating delegation chain
— principal → team-lead → worker — where the worker
gets a tighter metered spend cap (€40) than its
parent (€100). The page then runs two purchase.execute
spends of €30 each against /agent/chain/demo: the first
is authorized, the second is denied
cap_exceeded because the running total
(€60) > €40.
Real crypto: each sub-delegation is cryptographically signed by its parent (attenuating, accountable), the cap is enforced at action time (not advisory), and every attempt — allowed and denied — is recorded in an auditor-only sealed audit record. The credentials are demo-issued with ephemeral keys (reference-grade).
Step up to multi-factor — your real device passkey
Sign in at the demo OpenID provider for a password-tier credential
(AAL1), then add a passkey from this device
and step up to AAL2. The step-up runs a real
navigator.credentials.get() assertion
(ECDSA P-256) that proves possession of the
passkey you just enrolled — a same-holder proof, not a matching
email — and the upgraded credential is Ed25519-signed
and carries a faithful assurance vector (IAL/AAL/FAL).
This uses your real device passkey — Touch ID, Windows Hello, or a security key — doing real ECDSA P-256; the same-holder proof and the upgraded credential are real. The identity provider is a clearly-labelled simulation that does no real-world identity proofing, so a passkey raises only the authenticator-assurance axis (AAL) and never unlocks identity claims. No personal data is shown. [MFA-1]
Your browser doesn’t expose WebAuthn
(navigator.credentials is unavailable), so the live
passkey step-up can’t run here. Open this on a device with a
platform passkey or a security key, or
talk to us for a walkthrough — we
won’t fake the prompt.
Bring your own login
Sign in at an OpenID provider and walk out with a signed PSDP
credential. The page shows its work: the id_token is
validated against the provider’s published JWKS, and the minted
credential’s Ed25519 issuer signature is verified in front of
you — the response comes back verified: true, no API
key needed.
The built-in identity provider is a simulated OpenID
provider served by this same app, and it does no real-world identity
proofing — its RS256 signatures are real, its identities
(demo-user-001) are not.
If you’d rather curl
The same stack serves machine endpoints that stay open in production. Two to start with — no key, no signup.
$ curl -s https://psdp-eudi.fly.dev/verify/payment/demo
{"sample": "sepa_instant_50eur", "accepted": true,
"errors": [], "receipt": {"authorized_payee": "MERCHANT:DE-…",
"amount": "50.00", "currency": "EUR",
"sca_method": ["possession", "inherence"],
"risk_decision": "allow", …}}
Runs the payment-authorization verifier over a bundled SEPA-Instant sample credential and returns the JSON receipt. The sample is canned — verification time is pinned inside the sample’s validity window, and no money moves. It is an API response, not a page.
$ curl -s https://psdp-eudi.fly.dev/.well-known/openid-credential-issuer
{"credential_issuer": "…",
"authorization_servers": […],
"credential_endpoint": "…",
"credential_configurations_supported": {…}}
The live OID4VCI issuer metadata
this deployment serves to wallets — the same document a wallet
fetches before asking for a credential. Nothing is mocked: it is the real
metadata document this deployment serves (the issuer identity is a demo
one).
Reference deployment — what runs, and what’s simulated
Every demo on this page runs on this same host, against the same reference stack that produces the numbers on the rest of this site — there is no separate demo environment.
PSDP is a reference implementation; production hardening is in
progress. These demos exist so you can check our claims, not so
we can make new ones.
Where a path uses demo crypto or a demo issuer, the response says so
explicitly. In production mode (PSDP_PRODUCTION=1) the
verifier refuses mock proofs — submissions are rejected with
mock_crypto_rejected_in_production — and startup
checks enforce production configuration before serving. The Tier 2
demos are exactly the ones that pass end to end under that flag: a real
(reference-grade) zero-knowledge age proof and its cross-site unlinkable
variant, a key-bound metered-cap agent delegation, a real passkey
step-up, and a real signed-credential login.
The numbers behind this stack — conformance runs, wallet interop, the theorem map — live on the evidence page, each with its source artifact.
Seen enough to have questions?
Bring what you saw to a 30-minute gap scan — engineering to engineering, no deck.