Skip to content

OpenID for Verifiable Credential Issuance (OID4VCI)

Asgardeo supports issuing verifiable credentials to digital wallets using the OID4VCI protocol. This page explains the key concepts, supported flows, credential formats, and endpoints.

Info

OID4VCI is defined by the OpenID for Verifiable Credential Issuance specification. Asgardeo's implementation follows this specification to ensure interoperability with any conformant digital wallet.

What are verifiable credentials?

A verifiable credential (VC) is a tamper-evident digital document that represents claims about a subject (for example, a user's name, job title, or degree). VCs are cryptographically signed by the issuer, held by the holder in a digital wallet, and presented to a verifier who can check authenticity without contacting the issuer.

This three-party trust model — issuer, holder, verifier — is the foundation of decentralized identity.

What is OID4VCI?

OpenID for Verifiable Credential Issuance (OID4VCI) is a protocol built on OAuth 2.0 and OpenID Connect. It standardizes how a credential issuer delivers verifiable credentials to a digital wallet.

Asgardeo acts as the credential issuer. It exposes the necessary endpoints to allow a conformant digital wallet to:

  1. Discover the issuer's capabilities via a well-known metadata endpoint.
  2. Get authorization (interactively or via a pre-authorized code).
  3. Request and receive a signed verifiable credential.

Credential issuance flow

Asgardeo supports the authorization code flow for credential issuance. In this flow, the user authenticates interactively before receiving a credential.

OID4VCI authorization code flow sequence diagram

  1. Credential offer — Asgardeo generates a credential offer delivered as a QR code or deep link. The wallet scans or follows it to begin the issuance flow.
  2. GET /.well-known/openid-credential-issuer — The wallet fetches credential issuer metadata (typically from /oid4vci/.well-known/openid-credential-issuer) to discover supported credentials and endpoint URLs.
  3. Credential issuer metadata — Asgardeo returns the issuer metadata, including supported credential configurations and endpoint locations.
  4. GET /.well-known/oauth-authorization-server — The wallet fetches authorization server metadata to discover OAuth 2.0 endpoints such as authorization and token endpoints.
  5. Authorization server metadata — Asgardeo returns the authorization server metadata.
  6. Authorization request — The wallet sends an authorization request to Asgardeo including scope specifying the verifiable credential being requested.

    Note

    Some wallets use the Pushed Authorization Request (PAR) endpoint (POST /oauth2/par) to send the authorization request directly to the server before redirecting the user. This improves security by keeping request parameters out of the browser URL. If the wallet supports PAR, it will use the request_uri returned by the PAR endpoint in the authorization redirect.

  7. User authentication and consent — Asgardeo prompts the user to sign in and grant consent to share the requested attributes with the wallet.

  8. Authorization code — Asgardeo issues an authorization code and redirects back to the wallet's callback URL.
  9. Access token — The wallet exchanges the authorization code at the token endpoint, and Asgardeo returns an access token bound to the authorized credential request.
  10. POST /nonce — The wallet sends POST /oid4vci/nonce to get a fresh server-generated nonce (c_nonce) used to prevent replay attacks.
  11. c_nonce — Asgardeo returns the c_nonce value.
  12. Credential request (AT + proof) — The wallet sends a credential request to the credential endpoint, including the Bearer access token and a JWT proof signed with c_nonce to prove possession of the private key.
  13. Verifiable Credential — Asgardeo validates the access token and proof, then returns the signed verifiable credential (for example, an SD-JWT VC) to the wallet.

Supported credential formats

Asgardeo supports the following credential formats:

Format Description
dc+sd-jwt SD-JWT VC — Selective Disclosure JWT-based verifiable credential. Allows the holder to selectively disclose individual claims to a verifier without revealing the full credential.
jwt_vc_json JWT VC JSON — Standard JWT-based verifiable credential encoded as a JSON object. All claims are included in the token and signed by the issuer.

Key endpoints

Asgardeo exposes the following OID4VCI endpoints:

Endpoint Path Purpose
Credential issuer metadata /oid4vci/.well-known/openid-credential-issuer Advertises the issuer's capabilities, supported credential configurations, and endpoint URLs.
Credential offer /oid4vci/credential-offer?credential_offer_uri=... Delivers a credential offer to the wallet via a URI reference.
Nonce /oid4vci/nonce Issues a fresh nonce used to bind the wallet's proof of possession.
Credential /oid4vci/credential Issues the signed verifiable credential after validating the access token and proof.

Sample credential issuer metadata response

The following is an example response from the /oid4vci/.well-known/openid-credential-issuer endpoint. Wallets use this to discover what credentials the issuer supports and how to request them.

{
  "credential_issuer": "https://localhost:9443/oid4vci",
  "credential_endpoint": "https://localhost:9443/oid4vci/credential",
  "nonce_endpoint": "https://localhost:9443/oid4vci/nonce",
  "authorization_servers": [
    "https://localhost:9443/oauth2/token"
  ],
  "credential_configurations_supported": {
    "work_id": {
      "id": "work_id",
      "format": "dc+sd-jwt",
      "scope": "work_id",
      "vct": "work_id",
      "credential_signing_alg_values_supported": [
        "RS256"
      ],
      "cryptographic_binding_methods_supported": [
        "jwk"
      ],
      "proof_types_supported": {
        "jwt": {
          "proof_signing_alg_values_supported": [
            "RS256", "RS384", "RS512",
            "PS256", "PS384", "PS512",
            "ES256", "ES384", "ES512"
          ]
        }
      },
      "credential_metadata": {
        "display": [
          {
            "name": "Work ID"
          }
        ],
        "claims": [
          {
            "path": ["email"]
          },
          {
            "path": ["username"]
          }
        ]
      }
    }
  }
}

Note

The credential_signing_alg_values_supported field (shown as RS256 above) specifies the algorithm Asgardeo uses to sign the issued credential. This is configured per credential template and can be customized. In contrast, proof_signing_alg_values_supported lists the algorithms the wallet can use to sign its proof of possession. These are two separate concerns — issuer-side credential signing and wallet-side proof signing.

Proof of possession (key binding)

To prevent credential theft, OID4VCI requires the wallet to prove it controls the private key bound to the credential. Asgardeo supports the JWT proof type for this purpose.

The flow works as follows:

  1. The wallet generates a key pair (public and private keys).
  2. Before requesting the credential, the wallet calls the nonce endpoint to get a fresh nonce.
  3. The wallet constructs a JWT proof — a signed JWT containing the nonce and the wallet's public key — signed with its private key.
  4. The wallet includes this proof in the credential request.
  5. Asgardeo verifies the proof signature and nonce before issuing the credential.

Cryptographic binding

Asgardeo uses JWK-based cryptographic binding to tie the issued credential to the wallet's key pair. The wallet's public key (in JWK format) is embedded in the credential's cnf (confirmation) claim. This ensures that only the holder of the corresponding private key can present the credential to a verifier.

See also