Open source · Self-hosted · No SaaS

One API call to the EU Digital Identity Wallet.

EUDIPLO runs on your own servers, between your application and your users' wallets. Ask for a proof of age or a verified identity, or issue credentials of your own. EUDIPLO runs the protocols, checks trust and revocation, and hands your backend a clean JSON result. The personal data never passes through anyone else's cloud.

Runs on your serversApache-2.0LF Decentralized TrustOpenID4VCI 1.0OpenID4VP 1.0

Under the hood

Have a wallet on your phone? Run this flow for real in about an hour →

How it works

You make one API call. EUDIPLO does the protocol work.

This is the complete backend side of the age check above, with the TypeScript SDK or plain HTTP from any language. Everything below the waterline is what EUDIPLO did to answer it.

checkout.js
import { EudiploClient } from '@eudiplo/sdk-core';

const eudiplo = new EudiploClient({ baseUrl, clientId, clientSecret });

// Ask the customer's wallet for proof of age
const request = await eudiplo.createPresentationRequest({ configId: 'age-over-18' });
showQrCode(request.crossDeviceUri);

// Resolves once EUDIPLO has verified the answer
const session = await eudiplo.waitForSession(request.sessionId);
grantAccess(session.credentials);
What your backend receiveswebhook
{
  "status": "completed",
  "session": "0b6f3a8e-6d0c-4b8e…",
  "credentials": [{
    "id": "pid",
    "values": [{
      "vct": "urn:eudi:pid:1",
      "age_equal_or_over": { "18": true }
    }]
  }]
}

Not on TypeScript? Every instance serves its OpenAPI 3.1 description at /api/docs-json and an interactive Swagger UI at /api/docs. Call the API from any stack, or generate a client for Java, Python, Go or .NET. API reference →

14

steps EUDIPLO ran for that one call

You don't build them, test them against the conformance suite, or rewrite them when the specs move.

  1. 01Build the DCQL query from your configurationOpenID4VP 1.0 · DCQL
  2. 02Sign the request with your access certificate and a fresh nonceSigned request object · x509_hash client ID
  3. 03Attach your registration certificate, so the wallet can show who is asking and whyverifier_info
  4. 04Offer the right channel: QR code, same-device link or the browser's credential pickerDigital Credentials API · ISO 18013-7 Annex C
  5. 05Keep the wallet-facing ID separate from your sessionOpenID4VP §13.3 · one-time response code
  6. 06Accept only an encrypted responsedirect_post.jwt · JWE
  7. 07Verify the issuer's signature on the credentialSD-JWT VC · ISO 18013-5 mdoc
  8. 08Check every disclosed claim against its digestSD-JWT selective disclosure
  9. 09Verify that the credential is bound to the holder's deviceKey binding JWT · mdoc DeviceAuth
  10. 10Check the issuer against your trust listETSI TS 119 602 lists of trusted entities
  11. 11Check that the credential is not revoked or suspendedToken Status List
  12. 12Match the answer to your query, claim by claimDCQL claims and values
  13. 13Record the session for audit and troubleshootingSession log · OpenTelemetry
  14. 14Deliver one clean result to your backendWebhook · REST · server-sent events

Issuing works the same way. One call to POST /api/issuer/offer, and EUDIPLO runs OpenID4VCI with pushed authorization requests, PKCE, DPoP, wallet and key attestation, batch issuance, status lists and wallet notifications.

Self-hosted by design

Your servers. Your keys. Your users' data.

EUDIPLO is software you run, not a service you rent. Install it on-premises, in your private cloud or in any EU data center. What your users share from their wallets reaches your systems and nobody else's.

A closed identity platform
Walleton the user's phone Vendor's clouddecrypts every answer, usually holds your keys Your backend
EUDIPLO
Walleton the user's phone
Your infrastructure EUDIPLOdecrypts the answer on your server Your backend

Personal data stays with you

The wallet encrypts its answer to a key your instance creates for that one request. It is decrypted on your server and goes straight to your backend.

Signing keys in your HSM

Create signing keys in an HSM over PKCS#11, AWS KMS or HashiCorp Vault. They are generated as non-exportable, and every signature happens inside.

Only what you need

Requests name the exact claims, and selective disclosure keeps everything else in the wallet. An age check gets a yes or no, not a birth date.

Deleted on your schedule

Session data is deleted or anonymized after a retention period you set per tenant, 24 hours by default. Request logging is off unless you turn it on.

Nothing phones home

No analytics, license checks or update checks. Traces and metrics go only to an OpenTelemetry collector you run, or nowhere with OTEL_SDK_DISABLED=true.

Code you can audit

Apache-2.0 and developed in the open. Your security team can read every line, and nothing depends on a vendor's uptime or pricing.

For service providers

Offer it as a service, with the same privacy for every customer.

EUDIPLO is multi-tenant. Hosting companies, identity providers and public IT service centers can run one installation for many customers. Each tenant has its own keys, certificates, trust lists, configurations, API clients and retention period, and every request is scoped to one tenant.

Your customers get wallet verification and issuance without running anything themselves, hosted where you choose, on code they can audit. espuni runs age verification for online platforms this way.

Tenants and access →
One EUDIPLO installation
shop.exampleown keys · own trust list · deleted after 1 h
bank.exampleown keys · HSM · deleted after 24 h
city.exampleown keys · own trust list · anonymized after 7 days

Use cases

What teams build with it

Each use case starts from a guide that ends in a working result.

VerifyOnline platforms, shops

Age verification

Ask for "over 18" and nothing else. Platforms that must protect minors under DSA Article 28 get a yes or no, without a name or birth date.

Asks for
age_over_18
Runs at
espuni, age verification as a service
Configure a verification →
VerifyBanks, insurers, telecoms

Customer onboarding

Fill in sign-up and KYC forms from the Personal ID that a Member State issued. No photo of an ID card, no manual review of typed-in data.

Asks for
given_namefamily_namebirthdateaddress
Formats
SD-JWT VC and mdoc, in one request
Integrate into your backend →
IssueEmployers, universities, associations

Your own credentials

Issue employee IDs, student cards, memberships or tickets into the same wallet. Claims can come from your login or your own API, and you can revoke each credential later.

Issues
SD-JWT VC or mdoc, bound to the holder's device
Login
Keycloak or any OpenID Connect provider
Issue your first credential →
TestWallet makers, national programs

Interoperability testing

Test a wallet against a conformant issuer and verifier with real certificates, trust lists and status lists, in one installation.

Runs at
EUDI Wallet Playground of the German EUDI ecosystem
Tested with
4 wallets, listed below
See wallet compatibility →

Why now

The EU has set the dates.

eIDAS 2.0 makes the wallet a standard way to prove who you are online, everywhere in the EU. Services that rely on identity have to be ready to accept it.

  1. eIDAS 2.0, Regulation (EU) 2024/1183, enters into force.

  2. The first implementing acts fix the wallet's technical rules and start the clock.

  3. Every Member State offers at least one EUDI Wallet to its citizens.

  4. Banks, telecoms, transport, energy, health, education and very large online platforms must accept the wallet when users choose it.

A summary for orientation, not legal advice. Check the exact obligations and dates for your sector.

In production

Running today, tested against the specs.

Who runs it

  • EUDI Wallet Playground

    The German EUDI ecosystem's playground for testing wallets and their interoperability.

  • espuni

    Multi-tenant age verification as a service for platforms under DSA Article 28.

  • EUDI Web Client Demo

    A public instance of the EUDIPLO admin interface.

Wallets it is tested with

Standards

Every change runs against the OpenID Foundation conformance suite for OpenID4VCI and OpenID4VP.

OpenID4VCI 1.0OpenID4VP 1.0DCQLSD-JWT VCISO 18013-5 mdocISO 18013-7 Annex CDigital Credentials APIToken Status ListETSI TS 119 602PAR · PKCE · DPoPOpenID Federation (partial)
Open source, Apache-2.0

Hosted by LF Decentralized Trust and developed in the open. No license fees, no per-transaction pricing, no lock-in.

View on GitHub ↗

Under the hood

One service between your systems and every wallet.

EUDIPLO runs next to your application, on your infrastructure. It holds the keys, keeps the sessions and talks to the trust ecosystem, so your application doesn't have to.

Your application

Creates requests and offers through the REST API or the TypeScript SDK. Your team manages everything in the admin interface or the CLI.

EUDIPLO

Issuer, verifier and trust anchor in one service, with separate tenants for each organization or product.

  • Issuance
  • Verification
  • Trust lists
  • Status lists
  • Keys
  • Sessions
  • Tenants

Wallets

Any wallet that follows the EUDI specifications, on the same device or by QR code from another screen.

Runs on your infrastructure

Keys

HSM over PKCS#11, AWS KMS, HashiCorp Vault or the database

Database

PostgreSQL, or SQLite for a single node

Storage

S3-compatible object storage or local files

Deployment

Docker Compose or Kubernetes, with OpenTelemetry

Connects to the trust ecosystem

Trust lists

Publishes and consumes lists of trusted issuers and verifiers

Registrar

Access and registration certificates for your services

Your login

Keycloak or any OpenID Connect provider before issuance

Configuration as code

Every credential and verification is a file you can review.

Each configuration is a JSON file with a published schema. Your editor autocompletes it, your CI validates it, and the CLI shows a plan before anything changes on a running instance.

  • eudiplo config validateCheck every file against its schema
  • eudiplo config planSee what an import would change
  • eudiplo config importApply it to a running instance
presentation/age-over-18.json
{
  "$schema": "https://eudiplo.dev/schemas/v3/PresentationConfigFile.schema.json",
  "spec": {
    "id": "age-over-18",
    "description": "Proof of age for checkout",
    "statusCheckMode": "strict",
    "webhookEndpointId": "shop-backend",
    "dcql_query": {
      "credentials": [
        {
          "id": "pid",
          "format": "dc+sd-jwt",
          "meta": { "vct_values": ["urn:eudi:pid:1"] },
          "claims": [{ "path": ["age_equal_or_over", "18"] }]
        },
        {
          "id": "pid-mdoc",
          "format": "mso_mdoc",
          "meta": { "doctype_value": "eu.europa.ec.eudi.pid.1" },
          "claims": [{ "path": ["eu.europa.ec.eudi.pid.1", "age_over_18"] }]
        }
      ],
      "credential_sets": [{ "options": [["pid"], ["pid-mdoc"]] }]
    }
  }
}

Get started

Pick your way in.

Start building

From zero to a credential in your phone's wallet, on your own machine.

  1. Install the CLI

    curl -fsSL https://eudiplo.dev/install.sh | bash
    The installer checks the release checksum. Prefer npm? Use npm install -g @eudiplo/cli with Node.js 22.12 or later.
  2. Start the demo

    eudiplo demo
    Starts EUDIPLO and its admin interface. Needs Docker or Podman.
  3. Follow a cookbook

    Issue a credential to a real wallet and verify it, with a checkpoint after every step. Open the cookbooks →

Plan a rollout

What you need to know before EUDIPLO handles real credentials.

  • Self-hosted. It runs on your servers, in the country you choose. Signing keys stay in your HSM, AWS KMS or Vault.
  • Free to use. Apache-2.0, with no license or per-transaction fees.
  • Multi-tenant. One installation serves several issuers and verifiers, or many customers if you offer it as a service, each with its own keys, roles and configuration.
  • Ready for audits. Session logs, OpenTelemetry, and configuration changes that are planned before they are applied.