Explore how SD-JWTs, mDoc (ISO 18013-5), OIDC4VCI, and OIDC4VP enable user-consented, selective disclosure of Verifiable Credentials using open standards in a demo setup. The wallet implements wallet attestation (WIA/WUA), DPoP-bound tokens, and HAIP-compliant verifiable presentations, following the HAIP (High Assurance Interoperability Profile) specification and EUDI Architecture Reference Framework.
Related articles:
- Verifiable Credentials with Spring Boot & Android
- Securing Verifiable Credentials with DPoP
- HAIP 1.0: Securing Verifiable Presentations
- More articles covering WIA, WUA, and Token Status List coming soon.
| Feature | Description |
|---|---|
| WIA | Obtains Wallet Instance Attestation from the wallet-provider and presents it at PAR/Token endpoints via attest_jwt_client_auth |
| WUA | Obtains Wallet Unit Attestation backed by Android Key Attestation (TEE/StrongBox) for hardware key security |
| PAR | Uses Pushed Authorization Requests before initiating the Authorization Code Flow |
| DPoP | Generates DPoP proofs to sender-constrain access tokens (RFC 9449) |
| HAIP VP | Verifies JAR signatures (x5c), validates x509_hash client_id, encrypts VP responses (ECDH-ES + A256GCM) |
| DCQL | Parses Digital Credentials Query Language requests for selective disclosure |
| dc+sd-jwt | Issues and presents credentials in HAIP-compliant format with x5c header |
| mso_mdoc | Issues and presents mDoc credentials (ISO 18013-5) with COSE_Sign1 IssuerAuth and DeviceAuth |
| 🆕 Transaction Log | On-device audit log of issuance, presentation, and deletion events per ARF 2.8.0 Topic 19 (DASH) — attribute identifiers logged, never values (DASH_03a) |
| 🆕 Export / Import | AES-256-GCM encrypted wallet backup (.kwallet) via Android SAF per ARF 2.8.0 Topic 34 (Migration Objects) — no raw credentials or private keys exported |
| 🆕 App Check | Firebase App Check (Play Integrity API) verifies wallet genuineness on every Wallet Provider call per ARF 2.8.0 WIAM_04 |
| 🆕 Security Posture | 4-level device posture framework per ARF 2.8.0 §6.5.4.2 — freeRASP (root, hook/Frida, tamper, malware) + OS patch age, biometric enrollment, developer options |
| ⭐ Remote WSCD | Toggle between local (Android Keystore) and remote (QTSP) signing via CSC API v2 — wallet-provider issues WUA with wscd_type: "remote_qscd" for QTSP-managed keys |
K-Wallet and the backend services have successfully completed the OpenID Foundation Conformance Suite self-assessment for OID4VCI 1.0 Final:
| Role | Test | Result |
|---|---|---|
| Wallet | oid4vci-1_0-wallet-happy-path |
PASSED |
| Wallet | oid4vci-1_0-wallet-happy-path-with-scopes |
PASSED |
| Wallet | oid4vci-1_0-wallet-happy-path-with-scopes-without-authorization-details-in-token-response |
PASSED |
| Issuer | oid4vci-1_0-issuer-metadata-test |
PASSED |
| Issuer | oid4vci-1_0-issuer-happy-flow |
PASSED |
| Issuer | oid4vci-1_0-issuer-ensure-request-object-with-multiple-aud-succeeds |
PASSED |
Wallet profile (Mar 2026): dpop, client_attestation, wallet_initiated, simple, haip, unsigned, authorization_code, by_value
Issuer profile (Feb 2026): client_attestation, dpop, wallet_initiated, simple, haip, unsigned, authorization_code
Note: This is a self-assessment via the OpenID conformance suite — it validates protocol-level compliance (OID4VCI spec flows, token shapes, HAIP rules). It does not certify the app's production security posture (LoA High key authentication, per-use biometric gating at Keystore level, per-credential key isolation, WIA/WUA TTL compliance, etc.).
Start the backend services from spring-boot-vci-vp: wallet-provider (port 9001), auth-server (port 9000), issuer (port 8080), verifier (port 9002), and optionally qtsp-mock (port 9003) for remote WSCD and trust-validator (port 8090) for X.509 chain validation.
-
Build and run the app.
-
Authenticate using biometrics (or PIN, pattern, passcode).
-
Select "Request VC", choose the credential format (
dc+sd-jwtormso_mdoc), and follow the Issuer's Authorization Code Flow to obtain a sample credential. There are 3 available test users:testuser1 / pass1testuser2 / pass2testuser3 / pass3
The credential is securely stored in Encrypted Shared Preferences.
- Make sure you have a VC already stored.
- Open your browser and go to:
https://<REPLACE_WITH_YOUR_MACHINE_IP>/verifier/invoke-wallet - Press "HAIP WALLET" or "OpenID4VP WALLET"
- Re-authenticate with biometrics if needed and follow the steps.
- If everything is OK, you will see: VP Token is valid!
You can also test with the EU Reference Verifier:
- Select credential type: "Portable Document A1 (PDA1)"
- Select format:
dc+sd-jwtormso_mdoc - Choose attributes:
credential_holder&competent_institution - Add your issuer's certificate as trusted issuer (copy from issuer_cert.pem)
Both formats are supported end-to-end with the EU Reference Verifier.
You can test mDoc offline presentation using the multipaz-identity-reader fork, which adds PDA1 doctype support.
- Clone and run the reader app on a second Android device:
git clone https://github.com/kmandalas/multipaz-identity-reader
- On the reader device, open the app and tap "Scan QR" to start a proximity session
- On K-Wallet, open the PDA1 (MSO Mdoc) credential detail screen and tap "Present in Person"
- Scan the QR code displayed by the reader with K-Wallet
- 🔵 BLE data transfer initiates automatically — no internet connection required
- Select the claims to disclose and confirm — the reader displays the verified credential attributes
Note: Both devices must have Bluetooth enabled. This flow works fully offline (📴 no network needed).
⚠️ Disclaimer
This repo contains an experimental project created for learning and demonstration purposes. The implementation is not intended for production use.
This project is a teaser — a working proof-of-concept demonstrating a fully functional EUDI-compliant ecosystem. If you need a production-ready solution, I can deliver a complete, end-to-end EUDI stack tailored to your needs:
- HSM integration — Hardware Security Module support for issuer and wallet-provider signing keys (LoA High compliance)
- Remote WSCA — Production-grade Remote Wallet Secure Cryptographic Application with certified QTSP HSM integration (the included qtsp-mock demonstrates the CSC API v2 flow end-to-end)
- Production-grade storage — Replace H2 with a production database of your choice (PostgreSQL, MySQL, CosmosDB, etc.); credential status, WUA, and session data on a robust, scalable store
- Key Vault integration — AWS KMS, Azure Key Vault, or HashiCorp Vault for secret/key lifecycle management
- Full microservices setup — Containerised (Docker/Kubernetes), horizontally scalable, with distributed caching (e.g. Redis) for JTI replay protection, session management etc.
- Wallet apps (Android & iOS) — Custom-branded and themed to your organisation's identity; delivered as your own product
- Complete EUDI solution — Issuer + Verifier + Wallet App (Android & iOS) + Wallet Provider as a coherent, deployable product
- Admin consoles — Management UIs for wallet provider, issuer, and verifier operations (credential revocation, status list monitoring, WUA management, audit logs)
- Multiple credential types — Extend beyond the demo PDA1 to PID, mDL, EAA, and custom attestation types per your rulebooks
- LoTL / Trust Validator — ETSI TS 119 612 Lists of Trusted Lists integration for federated, EU-compliant trust infrastructure across issuers, verifiers, and wallet providers
- LoA High compliance — Architecture and attestation chain designed to satisfy Level of Assurance High requirements under eIDAS 2.0 / ARF
- Standalone Verifier for Relying Parties — If your use case is accepting EUDI wallet presentations — without issuing credentials or operating a wallet — I can consult on and implement a standalone, HAIP-compliant OID4VP verifier tailored to your credential types, trust model, and integration requirements; from architecture advice through to production implementation
- Standalone Issuer — If you need to issue verifiable credentials (e.g. as a government agency, university, or bank) without operating a full EUDI stack, I can design and implement an OID4VCI-compliant issuer for your specific credential types and rulebooks, including integration with your Authentic Sources (civil registries, population registers, HR systems, or any internal database)
Interested? Reach out via GitHub to discuss your requirements.
Business Source License 1.1 — free for non-production use.

