Home 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

← Back to step 1 (discovery & configuration)

SD-JWT VC Issuance — Step 2 of 4: Approve and Request the Credential

The user has authenticated through the OIDC Authorization Code flow and debugger2.html has exchanged the code for tokens. What follows is the OID4VCI credential request: the wallet proves possession of a key it just generated, the user approves the issuance, and the access token is presented to the issuer's Credential Endpoint.

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

Tokens from the OIDC Authorization Code Flow

The token set debugger2.html obtained from the authorization server. The access token is what authorizes the credential request below; the ID token says who was authenticated.

 
Presented to the Credential Endpoint as a Bearer credential. The issuer decides what to put in the credential based on who this token belongs to.

Inspect

The OIDC authentication result. Not sent to the credential endpoint — shown so you can see who the credential will be about.

Inspect

Not used by the issuance itself — but it is what lets step 4 refresh the credential later without troubling the End-User (OID4VCI section 14.5). An authorization server is not obliged to issue one, and the pre-authorized code grant normally does not.
The decoded ID token payload — the authenticated subject the issuer will describe.
 
OID4VCI Credential Request

Everything the request is built from. The holder key pair is generated in this browser; only its public half leaves, inside the proof of possession, and the issuer copies it into the credential's cnf claim so a verifier can later demand proof that the presenter holds the private half.

credential_endpoint from the credential issuer metadata retrieved in step 1.
credential_issuer — also the audience of the proof of possession.
credential_configuration_id, its format and its vct — the credential the issuer is being asked to mint.
The public half of the key pair generated in this browser, as a JWK. It goes in the proof JWT header and ends up in the credential's cnf claim.

 
Whether the PRIVATE half of the holder key pair may be written to this browser's localStorage. It has to be kept for the workflow to continue past this page: step 4 needs it to refresh the credential, and the presentation pages need it to sign the Key Binding JWT. Turn it off to keep it out of storage, and carry it yourself with Download Key Pair.
 
A fresh nonce from the issuer's Nonce Endpoint, carried by the proof so the issuer knows the proof was made for this request.
A JWT with typ openid4vci-proof+jwt, signed by the holder key, naming the credential issuer as its audience and carrying the c_nonce.
The header of the proof JWT carried in the request body's proofs.jwt, decoded. typ marks it as an OID4VCI proof of possession, alg is what it was signed with, and jwk is the holder public key the credential will be bound to.
The payload of the proof JWT carried in the request body's proofs.jwt, decoded: the wallet as iss, the credential issuer as aud, when it was signed (iat), and the c_nonce that ties it to this request.
The JSON that will be POSTed to the credential endpoint with the access token as a Bearer credential.
 
Credential Request Options

Three things the wallet gets to decide, each of which changes the request below.

OID4VCI section 8.2. If the token response granted credential_identifiers (because the authorization used authorization_details), the request MUST use credential_identifier and MUST NOT use credential_configuration_id. Otherwise it is the other way round. This is not a preference — it follows from what was granted.
One proof per key, one credential per proof (section 8.3). The issuer's batch_credential_issuance.batch_size is the most it will accept; asking for more than one is how a wallet gets several copies of the same credential bound to different keys.
 
Section 10. The wallet sends a public key and the issuer returns a JWE instead of JSON, which this page then decrypts. Only offered when the issuer advertises credential_response_encryption.
 
Approve Issuance

Issue this credential?

Approving will send the Credential Request shown below to the issuer, exactly as it appears. The issuer will mint an SD-JWT VC describing the authenticated user and bound to the holder key generated on this page.

  • Issuer:
  • Credential:
  • Subject:
  • Claims the issuer says this credential can carry:
The fully assembled HTTP request: the method and URL of the Credential Endpoint, the headers (including the access token presented as a Bearer credential), and the JSON body carrying the proof of possession. This is exactly what Approve sends.