Skip to main content

Chapter 6: The New Way — OID4VC

What you'll learn:

  • The design philosophy that guided the new stack
  • What OID4VCI, OID4VP, SD-JWT, and did:web each replace
  • How the new stack maps onto tools developers already know
  • Why this stack succeeded where the previous one struggled
  • The trade-offs: what was simplified, what was sacrificed

The design question

The people who designed the new SSI stack — many of whom had spent years working on Aries and DIDComm — asked a deliberately simple question: what is the minimum change to existing web infrastructure that produces a working SSI system?

Not: what is the most cryptographically elegant solution? Not: what is the most decentralised architecture? Not: what maximises privacy at every layer?

But: what could a team of backend developers implement in a week, using tools they already have, without a blockchain, without a mediator, and without learning a new transport protocol?

The result is OID4VC — a suite of three specifications built as extensions of existing OAuth 2.0 and JWT standards, combined with a trust anchor mechanism that is literally a JSON file served over HTTPS.


The four pieces

OID4VCI — OpenID for Verifiable Credential Issuance

OID4VCI is how credentials get into a wallet. It extends the OAuth 2.0 authorisation code flow that most backend developers already know.

The issuer exposes two standard endpoints:

  • A credential offer endpoint — returns a QR code or deep link that the wallet scans to begin the flow
  • A credential endpoint — issues the signed credential in exchange for a valid access token

The flow is a standard OAuth pattern:

Every step of this flow is HTTPS. The token endpoint is the same OAuth token endpoint that any OAuth 2.0 server already provides. The credential endpoint is a new endpoint — but it accepts a Bearer token, the most standard form of HTTP authorisation. Any developer who has integrated with an OAuth provider (Google, GitHub, Auth0) already understands this pattern.

What it replaces: The Aries credential issuance protocol, which required a DIDComm connection to be established first, then a series of DIDComm message exchanges, then a write to the Indy ledger. OID4VCI replaces all of this with HTTPS calls.

OID4VP — OpenID for Verifiable Presentations

OID4VP is how a wallet presents credentials to a verifier. It extends OpenID Connect — specifically, the request object mechanism that OIDC already defines for passing authentication parameters.

The verifier publishes a presentation request that specifies which credentials and attributes it needs. The wallet responds with a verifiable presentation — a signed response containing only the requested claims.

The critical step is the final verification. The verifier does not call the issuer. It fetches the issuer's DID document — a static JSON file at a well-known URL — gets the public key, and verifies the signature on the credential. No live API, no mediator, no blockchain query.

What it replaces: The Aries present-proof protocol, which required an active DIDComm connection between the holder's agent and the verifier's agent. OID4VP replaces this with a redirect-based flow (familiar from OAuth) or a QR code scan, both over standard HTTPS.

SD-JWT — Selective Disclosure JSON Web Token

SD-JWT is the credential format. It is a standard JWT — signed by the issuer using a regular ECDSA or RSA key — with one extension: individual claims can be made selectively disclosable.

When an issuer creates an SD-JWT, each sensitive claim is replaced by a hash in the main JWT, and the actual claim values are provided as separate "disclosures" alongside the token. The holder stores the complete set of disclosures. When presenting, the holder includes only the disclosures for the claims they wish to reveal.

The verifier receives the JWT (which it can verify with the issuer's public key) and the selected disclosures (which it can verify by hashing them and checking they match the _sd array in the JWT). The holder cannot forge a claim — the JWT body is signed. But the holder can choose which signed claims to reveal.

What it replaces: AnonCreds, which used zero-knowledge proofs to achieve similar properties but required Indy-specific cryptographic libraries. SD-JWT is an IETF standard (RFC 9278 extended) and works with any library that handles JWTs — which is every language and every platform.

The trade-off: AnonCreds supported predicate proofs — proving "age > 18" without revealing your date of birth at all. SD-JWT does not directly support predicates; you reveal the date of birth and the verifier checks the maths. For most use cases this is acceptable. For the most privacy-sensitive cases — where even the date of birth should not leave the wallet — this is a real regression. The IETF SD-JWT specification includes work on integrating with external ZKP extensions to close this gap, but as of 2024 this is not widely deployed.

did:web — the trust anchor

Every signed credential needs a way to tell a verifier where to find the issuer's public key. In the Hyperledger stack, this was stored on the Indy blockchain. In the new stack, it is a JSON file hosted at a well-known HTTPS URL.

A DID like did:web:government.example.com resolves to:

GET https://government.example.com/.well-known/did.json

The response is a DID document — a JSON object that contains the issuer's public key (or keys) and nothing else:

{
"id": "did:web:government.example.com",
"verificationMethod": [{
"id": "did:web:government.example.com#key-1",
"type": "JsonWebKey2020",
"controller": "did:web:government.example.com",
"publicKeyJwk": {
"kty": "EC",
"crv": "P-256",
"x": "...",
"y": "..."
}
}]
}

Any verifier, anywhere in the world, can fetch this URL and get the public key. No blockchain query. No DID resolver infrastructure. No special library. It is an HTTP GET request.

What it replaces: did:sov, did:indy, and other blockchain-based DID methods that required ledger access to resolve a DID. did:web replaces the ledger with DNS and HTTPS — infrastructure that every organisation already operates.

The trust trade-off: A blockchain DID is tamper-resistant by design — once written, it cannot be changed without a consensus process. A did:web DID can be changed by anyone who controls the DNS and web server for that domain. This is a genuine trade-off: did:web is simpler and more practical, but relies on the security of the issuer's DNS and web hosting, which is the same trust model as HTTPS certificates. For most government and enterprise issuers, this is an acceptable model.


Side by side: old stack vs new stack

DimensionHyperledger StackOID4VC Stack
Trust anchorBlockchain (Indy)HTTPS JSON file (did:web)
TransportDIDComm (bespoke)HTTPS (standard)
Credential formatAnonCreds (ZKP)SD-JWT (JWT extension)
Mobile messagingDIDComm + MediatorOAuth redirect / QR
Developer prerequisiteBlockchain + Aries + DIDCommOAuth 2.0 + JWT
Infrastructure neededLedger nodes + MediatorWeb server
ZKP predicates✅ Native❌ Not natively supported
Existing library supportLimitedUniversal

Why adoption succeeded

The OID4VC stack spread rapidly. By 2024, it had been implemented by the major cloud providers (Microsoft Entra, Google, AWS), by specialist digital identity vendors, and by governments building EUDI-compliant systems. The reasons track directly to the design philosophy.

Every developer already knows the protocol shape. OAuth 2.0's authorisation code flow is the most commonly implemented authentication pattern in the world. OID4VCI is that pattern with one new endpoint. A developer who has integrated a social login can understand OID4VCI in an hour.

You can test it with curl. Because the entire stack runs over HTTPS with JSON payloads, you can test every endpoint with standard HTTP tools. No DIDComm-capable agent. No mediator. Just HTTP calls.

No new infrastructure. An issuer building on the OID4VC stack needs: a web server (they already have one), a JWT signing library (available in every language), and a domain with HTTPS (they already have one). That is the complete list.

Wallets do not need mediators. The OID4VP flow is based on redirects and QR codes — the same mechanism used by every OAuth mobile flow. The wallet is redirected to a verifier's callback URL, or the verifier polls a response URI. No persistent agent. No mediator.

Business significance: The combination of standard infrastructure, familiar developer tooling, and no blockchain dependency meant that a team could go from zero to a working credential issuance demo in a day. This is the practical definition of a developer-friendly standard, and it is why enterprise adoption moved faster than anything in the previous generation.


The complete picture

When you put all four pieces together, the full lifecycle of a credential in the OID4VC stack looks like this:

The issuer's only ongoing infrastructure requirement is a web server hosting a JSON file. The transport is HTTPS throughout. The credential format is a JWT. The verifier does not call the issuer at verification time.


Summary

The OID4VC stack — OID4VCI, OID4VP, SD-JWT, and did:web — was designed around one insight: use what developers already know. OAuth 2.0 instead of DIDComm. JWTs instead of AnonCreds. A static HTTPS file instead of a blockchain. The result is a complete SSI system that requires no new infrastructure, no specialist library, and no knowledge beyond standard web development.

The trade-offs are real: ZKP predicates are not natively supported, and the trust model for did:web relies on DNS security rather than ledger consensus. But for the majority of use cases — and for eIDAS 2.0 compliance — these trade-offs are acceptable.

Part 3 goes deeper into each building block. Now that you understand why this stack was chosen, the next four chapters explain exactly how each piece works.


Next: Part 3 — Building Blocks