Skip to content
Start with Identity
Decentralized Identity · Advanced

Verifiable Credentials Implementation Guide

By SWI Community Team · Updated 2026-11-05 · 15 min

Implementing verifiable credentials means standing up one or more of three roles, issuer, holder (wallet) or verifier, on a fixed stack of standards: a credential format (SD-JWT VC, ISO mdoc or W3C VC 2.0), the OpenID4VC 1.0 protocols for issuance and presentation, a status list for revocation, and a trust list that says which issuers count. In 2026 the pragmatic default is to start as a verifier, build to the HAIP 1.0 profile, and support SD-JWT VC and mdoc first.

This guide is for engineering teams that have decided to build. For the concept first, read decentralized identity explained and the Verifiable Credentials standard.

Where the standards stand (November 2026)

Layer Specification Status
Data model W3C VC Data Model 2.0 W3C Recommendation, 15 May 2025
Selective disclosure SD-JWT, RFC 9901 Proposed Standard, November 2025
Credential format SD-JWT VC draft-24 (5 November 2026), IESG evaluation
Issuance and presentation OpenID4VCI 1.0, OpenID4VP 1.0 Final
Interop profile HAIP 1.0 Final, 24 December 2025
Status (W3C) Bitstring Status List v1.0 W3C Recommendation, 15 May 2025
Status (IETF) Token Status List draft-21, RFC Editor queue
Unlinkable proofs BBS cryptosuite Candidate Recommendation Draft, 10 September 2026

Pin versions per integration. HAIP references SD-JWT VC draft-13, so the latest draft is not automatically what production wallets expect.

Pick your role first

You are implementing one or more of the issuer, holder, verifier roles, and each has different work:

  • Verifier (relying party): request and check presentations. This is the most common starting point and the lowest lift.
  • Issuer: sign credentials and deliver them to wallets. You need signing keys, a credential type, an issuance endpoint and a status list.
  • Holder/wallet: usually you integrate an existing wallet rather than build one, unless the wallet is your product.

Most enterprises start as a verifier, because you can accept credentials others issue without standing up issuance infrastructure.

Choose a format

Format Choose it when Trade-off
SD-JWT VC EU wallet interop, JWT tooling, general selective disclosure Same issuer signature on every showing unless you batch-issue
ISO mdoc Driver's licenses, age checks, in-person and EU PID CBOR tooling; separate stack from JWT
W3C VC 2.0 with Data Integrity JSON-LD ecosystems, education and workforce credentials Optional in the EU wallet framework
W3C VC with BBS You need unlinkable selective disclosure Cryptosuite not yet a Recommendation
AnonCreds Existing Hyperledger Indy networks Outside the OpenID4VC and HAIP mainstream

Transport: OpenID4VC and HAIP

OpenID4VCI handles issuance and OpenID4VP handles presentation. Both layer on OAuth 2.0, so you extend infrastructure you already run. HAIP narrows the options to one interoperable set: the authorization code flow with PKCE, PAR, DPoP-bound tokens, wallet and key attestation, DCQL queries, signed requests using the x509_hash client identifier, encrypted responses and ES256 signatures. If you align to HAIP from day one, EU-style wallets can talk to you without custom work.

Identifiers and keys

Verifiers need to find the issuer's signing key. Two models exist:

If you need EU interoperability, plan for X.509 alongside any DID. Either way, treat issuer keys like any high-value signing key: HSM-backed, rotated, with a tested compromise procedure. Storm-0558 showed what one acquired signing key enables when validation is loose.

Revocation and status

A credential outlives its issuance, so verifiers must know whether it is still valid. Publish status through a status list rather than a per-credential lookup: the verifier fetches the whole list, so the issuer does not learn what is being checked. Bitstring Status List requires lists of at least 16KB uncompressed for that crowd effect, and recommends random index assignment. Design this before issuing your first credential; retrofitting revocation is painful.

Trust: which issuers count

A signature proves a credential was not tampered with, not that you should trust who issued it. That is the job of a trust list or trust registry and a governance framework such as Trust over IP. Decide how verifiers learn which issuers are authoritative for which credential types before you go past a pilot.

Verifier checklist

  1. Validate the issuer signature with a vetted library; reject none and unexpected algorithms. Forged tokens accepted by weak validation, as in SimpleHelp (CVE-2026-48558), are the failure to avoid.
  2. Check the issuer against your trust list for that credential type.
  3. Verify the key binding: RFC 9901's key binding JWT carries your nonce, your aud and an sd_hash over the presented SD-JWT. Without it you accept copied credentials, the same flaw as token replay against unbound endpoints.
  4. Enforce a fresh nonce per request and reject reuse.
  5. Check validity dates and the status list entry, with a defined cache window.
  6. Recompute disclosure digests; reject unknown or duplicated disclosures.
  7. Request only the claims you need, with DCQL.
  8. Sign your requests (x509_hash) so wallets can show who is asking.
  9. Bind the response to the originating session; relayed QR codes are a phishing path similar to an AitM proxy.
  10. Log the verification result and evidence reference, not the full credential.

Issuers have one extra rule from RFC 9901: salts need at least 128 bits of randomness, so use a maintained library rather than hand-rolled code.

A staged rollout

These phases are planning estimates, not measured durations.

  1. Verifier pilot (about one quarter): accept one credential type from one issuer for one flow, such as a reusable KYC check at onboarding, with a non-credential fallback.
  2. Add issuance if you own credentials worth making portable, with status lists and key custody in place first.
  3. Formalize trust with a trust list and documented governance.
  4. Scale formats and wallets as the ecosystem matures. Test against the European Commission's open-source reference issuer, verifier and wallet libraries and at least one third-party wallet.

Common mistakes

  • Building issuance before you have a verifier that will accept the output.
  • Picking a format or draft your target wallets do not support.
  • Checking the signature but skipping holder binding.
  • Treating revocation and trust governance as afterthoughts.
  • Assuming a ledger is required. It usually is not.

Where to go next

Vendor selection: choosing a decentralized identity platform. KYC angle: reusable identity and KYC. Vendors: decentralized identity directory, including open-source stacks such as walt.id and SpruceID, and best platforms. Use cases: verifiable credentials use cases.

Frequently asked questions

What do I need to issue a verifiable credential?
An issuer identity with HSM-backed signing keys (an X.509 certificate chain for EU wallet interoperability, or a did:web), a credential type and schema, a signing library for your chosen format such as SD-JWT VC, a status list for revocation, and an issuance protocol, typically OpenID4VCI 1.0, to deliver the credential to a wallet bound to a holder key.
Which verifiable credential format should I use?
Choose by verifier. SD-JWT VC and ISO mdoc are the formats the EU wallet framework and HAIP require; mdoc is also the format for mobile driver's licenses. Use W3C VC 2.0 with Data Integrity when you are in a JSON-LD ecosystem, adding BBS once it stabilizes for unlinkable selective disclosure, and AnonCreds only inside ecosystems that already standardize on it.
Is W3C Verifiable Credentials 2.0 a final standard?
Yes. Verifiable Credentials Data Model v2.0 became a W3C Recommendation on 15 May 2025, together with Bitstring Status List v1.0 and the Data Integrity specifications. The BBS cryptosuite is still a Candidate Recommendation Draft (10 September 2026). On the IETF side, SD-JWT is RFC 9901 while SD-JWT VC remains an Internet-Draft in IESG evaluation.
How does credential revocation work?
The issuer publishes a status list and each credential points to an index in it. W3C credentials use Bitstring Status List v1.0; SD-JWT VC and mdoc use the IETF Token Status List, which is in the RFC Editor queue. The verifier fetches the whole list, so the issuer does not learn which credential is being checked.
How do verifiers know which issuers to trust?
Through a trust list or trust framework that names which issuers may issue which credentials. The EU wallet ecosystem uses X.509 certificates and trusted lists; DID-based ecosystems use trust registries and governance frameworks. Without one, verifiers fall back to manually configured issuer allowlists, which do not scale past a pilot.
Do I need to build my own wallet?
Rarely. Unless the wallet is your product, integrate existing wallets: national EUDI wallets, platform wallets that support the Digital Credentials API, or vendor wallets. The European Commission publishes open-source reference components, including a PID issuer, a verifier endpoint and wallet libraries, on its official EU Digital Identity Wallet GitHub organization.
Last reviewed By SWI Community TeamSuggest a correctionHow we research