Home Supported Standards Terms & Conditions Privacy Policy Documentation Contact About
  1. 0. Choose a use caseHow the issuance starts
  2. 1. Discover the issuerIssuer + authorization server metadata
  3. 2. Authorize & approveAuthenticate, review tokens, request it
  4. 3. The credentialThe issued SD-JWT VC and its disclosures
  5. 4. Refresh itRefresh Token, then the issuer again

VC Issuance — Step 1 of 4: Discover the Issuer← Return to home

What step 1 does

Issue a Selective Disclosure JWT Verifiable Credential (SD-JWT, RFC 9901) using OpenID for Verifiable Credential Issuance (OID4VCI). This page plays the wallet's part of the discovery phase: retrieve the Credential Issuer Metadata to learn what the issuer offers and where its endpoints are, retrieve the Authorization Server Metadata (RFC 8414) of the server that authorizes issuance, and settle the parameters both documents define. Step 2 authenticates the user through the existing OIDC Authorization Code flow on the debugger pages and asks the user to approve issuance; step 3 shows the credential the issuer returns.

Tip: click a pane's title to collapse/expand it.

Credential Issuer Metadata
What this document is, and why

An OID4VCI Credential Issuer publishes its metadata at a path that ends in /.well-known/openid-credential-issuer. See the OID4VCI spec.

The Credential Issuer Metadata endpoint. Retrieving it tells the wallet which credentials this issuer offers, which authorization server protects them, and where the nonce and credential endpoints are, and fills the OID4VCI half of the Configuration Parameters pane below. Populate Meta Data re-applies the document afterwards.
Fetch the Credential Issuer Metadata document from the URL above.
Load the Credential Issuer Metadata from a file on disk instead of fetching it. Use this when the issuer sends no CORS headers, which stops a browser reading its metadata however correct the URL is: fetch the document with curl, save it, and load it here. Everything afterwards is identical to a retrieval.
Forget the retrieved Credential Issuer Metadata document, its table, and the OID4VCI values it populated (on screen and in local storage).
Verify the signed_metadata JWT on the Credential Issuer Metadata document. The issuer's keys are resolved from the SD-JWT VC issuer metadata (/.well-known/jwt-vc-issuer) or from a jwks_uri in the document itself; the signature is verified in the browser, the iss claim is checked against credential_issuer, and any signed claim that disagrees with the plain JSON is reported.
 
Issuer DID Document
What this document is, and why

A credential may name its issuer by DID instead of by URL. did:jwk and did:key are their key — they resolve here with no network call. Only did:web has a document to retrieve. Note that SD-JWT VC defines no DID-based issuer signature mechanism — using one with dc+sd-jwt is a profile extension. ldp_vc is DID-native under VC Data Model 2.0.

The DID to resolve. Filled in automatically from a retrieved credential (its iss or issuer) when that is a DID; type one here to resolve it by hand.
Resolve the DID above. did:jwk and did:key are decoded locally; did:web is fetched over HTTP(S) from the document URL the method defines.
Load a DID Document from a file instead of resolving it. Use this when a did:web host sends no CORS headers, which stops a browser reading its document however correct the URL is: fetch it with curl, save it, and load it here.
Forget the resolved DID Document, its table, and the DID values it populated (on screen and in local storage).
Where a did:web document is fetched from. Resolve fills this in from the DID: the host with its port percent-decoded, then /.well-known/did.json, or /<path>/did.json when the DID carries path segments. It stays empty for did:jwk and did:key, which have nothing to fetch. You can also type a URL here and press Retrieve, for a document that is not where the method's rules say it should be.
Fetch the DID Document from the URL above and use it here exactly as a resolved one. This is a retrieval, not a resolution: it is for a document that is not at the location the DID method derives — on a staging host, behind a tunnel, or at a path the issuer has not published yet. Because you chose the URL, a document whose id is a different DID is reported rather than refused.
Check that a key in this DID Document actually verifies the credential in hand. Resolving a document proves nothing on its own — what matters is whether the key it publishes is the one the issuer signed with.
Fetch /.well-known/did-configuration.json from the issuer's origin and verify its Domain Linkage Credential (DIF Well Known DID Configuration). This is what proves the DID and the https issuer are the same entity. For did:web it is the only non-circular proof: resolving did:web:host means fetching host, so the DID document alone cannot establish that the origin's controller and the DID's controller are one party.
 
 
Authorization Server Metadata
What this document is, and why

An OAuth 2.0 Authorization Server Metadata endpoint uses a path that ends in /.well-known/oauth-authorization-server. See the RFC 8414 spec. This document is stored under the same names oauth2_oidc_1.html uses, so retrieving it here also configures the OAuth2 / OIDC workflow.

The RFC 8414 metadata endpoint of the authorization server that protects this credential issuer. Defaulted from the credential issuer metadata's authorization_servers member once that document has been retrieved. Retrieving it fills the authorization server half of the Configuration Parameters pane below; Populate Meta Data re-applies the document afterwards.
Load the Authorization Server Metadata from a file on disk instead of fetching it. Use this when the authorization server sends no CORS headers, which stops a browser reading its metadata however correct the URL is: fetch the document with curl, save it, and load it here. Everything afterwards is identical to a retrieval — including what oauth2_oidc_1.html then shows.
Fetch the authorization server metadata document from the URL above.
Forget the retrieved authorization server metadata document and every value it populated — here AND on the debugger pages, since both share the same local storage.
Verify the signed_metadata JWT on the RFC 8414 document against the keys at its own jwks_uri, exactly as the Metadata Retrieval pane on oauth2_oidc_1.html does.
 
DID Configuration
What this document is, and why

An issuer named by did:web presents a problem this document exists to solve: resolving did:web:example.com means fetching example.com, so reading a DID document off that origin to decide whether the DID belongs to it is circular. A Domain Linkage Credential breaks the circle: the DID signs, with its own key, a credential naming the origin. The resource lives at the fixed path /.well-known/did-configuration.json at the origin root.

The resource's location is fixed by the specification: /.well-known/did-configuration.json at the origin root. Filled in from the credential issuer's origin once its metadata is retrieved; editable, because the copy you want to inspect may be somewhere else.
Fetch the resource from the URL above, check it against the specification, and populate the DID Configuration section of Configuration Parameters.
Load the resource from a file instead. Use this when the origin sends no CORS headers, which stops a browser reading it however right the URL is: fetch it with curl, save it, and load it here.
Forget the resource, its table, and the DID Configuration values it populated (on screen and in local storage).
Check the loaded resource cryptographically, not just structurally: resolve the DID it links, verify the credential's signature against the keys that DID authorises to assert, and check the origin it names is the origin it was fetched from. The schema check below says whether the document is well formed; this says whether it is true.
 
 
Receive a Credential Offer
When you need this

In a cross-device flow the issuer shows a QR code on its own screen and your wallet is somewhere else, so the offer does not arrive in this browser by itself. Paste what the QR code contains — an openid-credential-offer:// URI, an https:// link carrying credential_offer or credential_offer_uri, or the Credential Offer JSON itself.

Whatever the QR code encodes. OID4VCI defines the openid-credential-offer:// URI scheme for exactly this hand-over.
Read the offer, then discover the issuer it names and the authorization server that issuer names — the same thing that happens when an offer arrives in the URL.
 
Configuration Parameters
What this pane is

Every parameter the two metadata documents above can define, plus the client settings the authorization request needs. Retrieving either document fills its half of this pane; each value can then be overridden by hand, and Populate Meta Data in that pane re-applies the document. The OAuth 2.0 / OpenID Provider parameters are stored under the same names oauth2_oidc_1.html uses, so what is set here is what the OIDC workflow will run with. A member the retrieved document leaves out is marked -->not defined<--.

 

Claims to Request
What this pane is

Every claim the chosen credential configuration says it can carry, read from claims in the issuer's metadata above. Clear a row to ask the issuer to leave that claim out. The request travels in the OPTIONAL claims member of the authorization_details entry of type openid_credential (OID4VCI section 5.1.1) — not in the Credential Request, which section 8.2 gives no such member — so it is made when the issuance is authorized: in the authorization request, or, for a pre-authorized offer (H.2 / H.3) that has no authorization request at all, in the Token Request on step 2 (section 6.1.1). Each row is sent as a claims description object holding a claims path pointer, which is why a nested claim appears as address.locality here and travels as ["address","locality"]. Leaving every row checked sends no claims member: asking for all of them is what omitting it already means. An issuer decides what it issues either way — a claim it marks mandatory arrives whether or not it was asked for.

The credential configuration these claims belong to, chosen in the Configuration Parameters pane above.
RequestClaim pathNameNotes

 

 
Authorize Issuance (OIDC Authorization Code Flow)

OID4VCI authorizes issuance with an ordinary OAuth 2.0 / OpenID Connect Authorization Code flow, so this step hands over to the debugger pages that already implement it. The sdjwtvc=1 query parameter tells oauth2_oidc_1.html that it is running as part of this workflow: it starts the authorization request with the configuration above, the user authenticates at the identity provider, oauth2_oidc_2.html exchanges the code for tokens, and the browser then returns here — to step 2, where the tokens are shown and the user is asked to approve issuance.

Where the Start button goes. The query parameter is what puts oauth2_oidc_1.html into SD-JWT VC issuance mode.
/oauth2_oidc_1.html?sdjwtvc=1
The endpoint the authorization request will be sent to — the value from the Configuration Parameters pane above.
OID4VCI has two ways to say which credential is wanted (section 3.3.4). A scope is the simple one. authorization_details (RFC 9396) is the expressive one: the token response then grants credential_identifiers, and the Credential Request MUST name one of those instead of a credential_configuration_id.
 
The credential configuration the Credential Request will ask for in step 2.
Save the configuration and go to oauth2_oidc_1.html?sdjwtvc=1 to authenticate the user.
 
VC Tools

Tools that are useful at any point in these workflows, and belong to none of their steps.

Resolve a DID to its document, read the keys it publishes, check that one of them really signed the credential this browser is holding, and check that the DID and an origin are the same entity.
Resolve a Decentralized Identifier (did:jwk, did:key, did:web) to its document, verify that a key it publishes signed the credential in this browser, and verify a domain linkage (DIF Well Known DID Configuration). Opens in this tab; the workflow's state is untouched.
Build a Root, Intermediate and Issuing CA, issue certificates with any X.509v3 extension, and test a real TLS or mutual-TLS handshake with what you issued.
Build a certificate authority — Root, Intermediate and Issuing — and issue TLS server, TLS client, code-signing and S/MIME certificates with full X.509v3 extension control. Useful when the issuer or verifier is behind TLS you control. Opens in this tab; the workflow's state is untouched.