Credential Types Configuration
The credentialConfigurations object declares which credential types your Issuer2 Service can issue. It is part of the service create/update body and is published as the OpenID4VCI credential_configurations_supported metadata at the issuer's .well-known/openid-credential-issuer endpoint.
credentialConfigurations is a map keyed by credential configuration ID (e.g. "OpenBadgeCredential_jwt_vc_json"). That ID is the contract point with the rest of the system:
- Credential profiles reference it via
credentialConfigurationId. - Wallets request this credential by it — directly via
authorization_details(credential_configuration_id), or via the OAuthscopeparameter (matched against the configuration'sscopefield, or against this ID when noscopeis set).
Supported Formats
| Format | format value | Description |
|---|---|---|
| SD-JWT VC | dc+sd-jwt | IETF SD-JWT Verifiable Credentials |
| W3C JWT | jwt_vc_json | W3C Verifiable Credentials, JWT-signed |
| mDoc | mso_mdoc | ISO 18013-5 Mobile Documents |
Fields
Each entry in credentialConfigurations accepts the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
format | String (enum) | Yes | Credential format: dc+sd-jwt, jwt_vc_json, or mso_mdoc. |
scope | String | No | OAuth scope used to request this credential. Conventionally equal to the configuration ID. Must be non-blank if present. |
credential_definition | Object | No | For W3C VC (jwt_vc_json): { "@context": [...], "type": [...] }. type must include VerifiableCredential. |
doctype | String | No | Document type for mso_mdoc, e.g. org.iso.18013.5.1.mDL. |
vct | String | No | Verifiable Credential Type for dc+sd-jwt (required for SD-JWT VC). See VCT Handling. |
credential_signing_alg_values_supported | Array | No | Format-specific — JOSE strings or COSE integers. See Signing Algorithms. Non-empty if present. |
cryptographic_binding_methods_supported | Array | No | Key binding methods. Co-dependent with proof_types_supported — see Binding Methods & Proof Types. |
proof_types_supported | Object | No | Wallet key-proof types. Co-dependent with cryptographic_binding_methods_supported. |
credential_metadata | Object | No | Per-credential display and claim descriptions. See Credential Metadata. |
| (any other key) | — | No | Passed through verbatim into the published metadata as a custom parameter. Must not reuse a standard field name above. |
Only format is strictly required by the schema. A wallet can request the credential by its configuration ID even with nothing else set, but a production-ready type normally also declares cryptographic_binding_methods_supported, proof_types_supported, and credential_signing_alg_values_supported (for holder key binding), and often a scope for OAuth-scope-based requests.
Binding Methods and Proof Types
cryptographic_binding_methods_supported and proof_types_supported are co-dependent: if you set one, you must set the other. Providing only one is rejected at service create/update.
cryptographic_binding_methods_supported accepts:
| Method | Use case |
|---|---|
jwk | SD-JWT VC key binding |
did:{method} — e.g. did:key, did:jwk, did:web, did:ebsi | W3C credentials with DID subjects |
cose_key | mDoc credentials |
proof_types_supported is a map keyed by proof type (typically jwt); each entry's proof_signing_alg_values_supported must be non-empty:
{
"cryptographic_binding_methods_supported": ["jwk", "did:key", "did:web", "did:jwk"],
"proof_types_supported": {
"jwt": {
"proof_signing_alg_values_supported": ["ES256"]
}
}
}
Signing Algorithms
The value of credential_signing_alg_values_supported is validated against the format:
| Format | Expected values | Example |
|---|---|---|
dc+sd-jwt, jwt_vc_json | JOSE algorithm names (strings) | ["ES256"] |
mso_mdoc | COSE algorithm identifiers (integers) | [-7, -9] |
A string value is always interpreted as a JOSE identifier, so passing "ES256" for mso_mdoc is rejected — use the integer COSE form.
| Algorithm | Key Type | JOSE (JWT formats) | COSE (mDoc) | Description |
|---|---|---|---|---|
| ES256 | P-256 (secp256r1) | "ES256" | -7 | ECDSA with SHA-256 |
| ES384 | P-384 | "ES384" | — | ECDSA with SHA-384 |
| ES512 | P-521 | "ES512" | — | ECDSA with SHA-512 |
| EdDSA | Ed25519 | "EdDSA" | — | Edwards-curve Digital Signature Algorithm |
| RS256 | RSA | "RS256" | — | RSASSA-PKCS1-v1_5 with SHA-256 |
| PS256 | RSA | "PS256" | — | RSASSA-PSS with SHA-256 |
-7 is the COSE identifier for ECDSA with SHA-256, the algorithm used for ISO 18013-5 mDL signing. A configuration can advertise several COSE identifiers (e.g. [-7, -9]); values are integers from the IANA COSE Algorithms registry.
VCT Handling
Every SD-JWT VC configuration must declare a vct (Verifiable Credential Type) — a URL that uniquely identifies the credential type and points to its Type Metadata document. The Issuer2 Service supports two ways to provide it:
- External VCT — a plain
https://URL whose Type Metadata document is hosted somewhere else. - Self-hosted VCT — a
{vctBaseURL}placeholder that makes the issuer service resolve the URL and serve the Type Metadata document itself.
External VCT
Point vct at a Type Metadata document you host (or that a registry hosts). The issuer uses the value verbatim and serves nothing of its own:
{
"identity_credential": {
"format": "dc+sd-jwt",
"vct": "https://example.com/credentials/identity_credential"
}
}
Self-hosted VCT
Use the literal placeholder {vctBaseURL} to have the issuer host the Type Metadata document. The value must be of the form {vctBaseURL}/{type} — the placeholder followed by exactly one path segment:
{
"identity_credential": {
"format": "dc+sd-jwt",
"vct": "{vctBaseURL}/identity_credential"
}
}
Note the exact token: {vctBaseURL} — curly braces, capital URL. Self-hosting is triggered only when the vct contains this exact string. A different spelling. e.g. a lowercase-url variant ({vctBaseUrl}), or any typo — is not rejected: it is silently stored as a literal external vct, so the issuer self-hosts nothing and wallets receive an unresolvable URL.
Once the value does use the {vctBaseURL} token, it must start with the placeholder and be followed by exactly one path segment ({vctBaseURL}/identity_credential). A prefix before the placeholder, a trailing slash, or extra path segments fails validation with a 400 at service create/update time.
Resolution. At runtime the placeholder expands to:
{baseUrl}/.well-known/vct/v2/{target}/issuer-service-api/openid4vci
where {baseUrl} is the issuer service's baseUrl (or the host-derived base URL) and {target} is {organizationID}.{tenantID}.{issuerServiceID}. So {vctBaseURL}/identity_credential becomes, in the credential issuer metadata:
{baseUrl}/.well-known/vct/v2/{org}.{tenant}.{issuer}/issuer-service-api/openid4vci/identity_credential
That resolved URL is what wallets see as the vct in the issuer's credential_configurations_supported, and it is also the public, unauthenticated endpoint the issuer serves the Type Metadata document from (GET — no token required).
Providing the Type Metadata document
For self-hosted VCTs, supply the document to be served via the top-level sdJwtVcTypeMetadataConfiguration map on the issuer service, keyed by the same credential configuration ID as in credentialConfigurations:
{
"credentialConfigurations": {
"identity_credential": {
"format": "dc+sd-jwt",
"vct": "{vctBaseURL}/identity_credential",
"scope": "identity_credential",
"cryptographic_binding_methods_supported": ["jwk"],
"credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256"] }
}
}
},
"sdJwtVcTypeMetadataConfiguration": {
"identity_credential": {
"name": "Identity Credential",
"description": "A verifiable identity credential",
"schema_uri": "https://example.com/schemas/identity_credential.json",
"schema_uri#integrity": "sha256-..."
}
}
}
The served Type Metadata document supports these fields (per the SD-JWT VC Type Metadata draft):
| Property | Required | Description |
|---|---|---|
vct | No | The credential type identifier. If provided, it must resolve to the same value as the vct on the matching credential configuration (you may use the {vctBaseURL}/{type} placeholder here too). If omitted, the resolved VCT is filled in automatically. |
name | No | Human-readable name of the type. |
description | No | Human-readable description of the type. |
extends | No | VCT of a type this type extends. |
extends#integrity | No | Integrity metadata (SRI) for the extends document. |
schema | No | An inline JSON Schema for the credential. Mutually exclusive with schema_uri. |
schema_uri | No | URL of a JSON Schema for the credential. Mutually exclusive with schema. |
schema_uri#integrity | No | Integrity metadata (SRI) for the schema_uri document. Requires schema_uri. |
Any other member you include is served verbatim as well, so you can add further SD-JWT VC Type Metadata properties (or custom ones) beyond those above.
Each key in sdJwtVcTypeMetadataConfiguration must match a credentialConfigurations entry whose format is dc+sd-jwt; a key with no matching SD-JWT VC configuration fails validation with a 400.
sdJwtVcTypeMetadataConfiguration is optional even for self-hosted VCTs. If you use {vctBaseURL} but provide no document, the issuer serves a minimal default (the resolved vct, a name equal to the type, and a generated description). Provide the document when you need schema references, extends, or richer metadata.
Credential Metadata
Per-credential display and claim metadata lives under credential_metadata — as credential_metadata.display and credential_metadata.claims.
A display or claims key placed directly on the credential configuration is not interpreted as OpenID4VCI metadata — it is treated as a custom parameter and republished without validation. Always nest them under credential_metadata.
Display (credential_metadata.display)
An optional list of display entries, one per locale (locales must be unique):
| Property | Required | Description |
|---|---|---|
name | Yes | Credential display name (non-blank). |
locale | No | BCP-47 locale, e.g. en-US. |
logo | No | { uri, alt_text } — uri required and must include a scheme. |
description | No | Description of the credential. |
background_color | No | Hex color, e.g. #12107c. |
background_image | No | { uri } — must include a scheme. |
text_color | No | Hex color, e.g. #FFFFFF. |
Multi-language example:
{
"credential_metadata": {
"display": [
{ "name": "Identity Credential", "locale": "en-US", "description": "Your verified identity" },
{ "name": "Identitätsnachweis", "locale": "de-DE", "description": "Ihr verifizierter Identitätsnachweis" }
]
}
}
Claims (credential_metadata.claims)
An optional list of claim descriptions. This metadata is used by wallets to display information about the credential; it does not affect the actual credential content.
| Property | Required | Description |
|---|---|---|
path | Yes | Array of strings representing the path to the claim (non-empty, no blank segments). |
mandatory | No | Whether the claim is required (true) or optional (false). |
display | No | Array of { name, locale } entries; locales must be unique. |
The path format depends on the format:
| Format | Path example | Notes |
|---|---|---|
| SD-JWT VC | ["given_name"], ["address", "city"] | Claim name; nested claims add segments. |
| W3C JWT | ["credentialSubject", "name"] | Path from the credential root. |
| mDoc | ["org.iso.18013.5.1", "family_name"] | Namespace as the first segment, then the claim name. |
Credential Configuration Examples
SD-JWT VC (dc+sd-jwt)
{
"identity_credential": {
"format": "dc+sd-jwt",
"scope": "identity_credential",
"vct": "{vctBaseURL}/identity_credential",
"cryptographic_binding_methods_supported": ["jwk", "did:key", "did:web"],
"credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256"] }
},
"credential_metadata": {
"display": [
{
"name": "Identity Credential",
"locale": "en-US",
"description": "Your verified identity",
"background_color": "#12107c",
"text_color": "#FFFFFF"
}
],
"claims": [
{
"path": ["given_name"],
"mandatory": true,
"display": [{ "name": "First Name", "locale": "en-US" }]
},
{
"path": ["family_name"],
"mandatory": true,
"display": [{ "name": "Last Name", "locale": "en-US" }]
},
{
"path": ["birthdate"],
"mandatory": false,
"display": [{ "name": "Date of Birth", "locale": "en-US" }]
},
{
"path": ["address", "locality"],
"mandatory": false,
"display": [{ "name": "City", "locale": "en-US" }]
}
]
}
}
}
W3C JWT VC (jwt_vc_json)
{
"OpenBadgeCredential_jwt_vc_json": {
"format": "jwt_vc_json",
"scope": "OpenBadgeCredential_jwt_vc_json",
"cryptographic_binding_methods_supported": ["jwk", "did:key", "did:web", "did:jwk"],
"credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256"] }
},
"credential_definition": {
"type": ["VerifiableCredential", "OpenBadgeCredential"]
},
"credential_metadata": {
"display": [
{
"name": "Open Badge Credential",
"locale": "en-US",
"description": "Open Badges v3 achievement credential",
"background_color": "#1a365d",
"text_color": "#FFFFFF",
"logo": {
"uri": "https://w3c-ccg.github.io/vc-ed/plugfest-1-2022/images/JFF_LogoLockup.png",
"alt_text": "JFF Logo"
}
}
],
"claims": [
{
"path": ["credentialSubject", "achievement", "name"],
"mandatory": true,
"display": [{ "name": "Achievement Name", "locale": "en-US" }]
},
{
"path": ["credentialSubject", "givenName"],
"mandatory": true,
"display": [{ "name": "First Name", "locale": "en-US" }]
},
{
"path": ["credentialSubject", "familyName"],
"mandatory": true,
"display": [{ "name": "Last Name", "locale": "en-US" }]
}
]
}
}
}
mDoc (mso_mdoc)
mso_mdoc uses integer COSE signing identifiers (-7 = ES256) and cose_key binding. Claim paths are namespaced.
{
"org.iso.18013.5.1.mDL": {
"format": "mso_mdoc",
"scope": "org.iso.18013.5.1.mDL",
"doctype": "org.iso.18013.5.1.mDL",
"cryptographic_binding_methods_supported": ["cose_key"],
"credential_signing_alg_values_supported": [-7, -9],
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256"] }
},
"credential_metadata": {
"display": [
{
"name": "Mobile Driving License",
"locale": "en-US",
"description": "Your digital driving license",
"background_color": "#003366",
"text_color": "#FFFFFF",
"logo": {
"uri": "https://dmv.example.com/logo.png",
"alt_text": "DMV Logo"
}
}
],
"claims": [
{
"path": ["org.iso.18013.5.1", "family_name"],
"mandatory": true,
"display": [{ "name": "Family Name", "locale": "en-US" }]
},
{
"path": ["org.iso.18013.5.1", "given_name"],
"mandatory": true,
"display": [{ "name": "Given Name", "locale": "en-US" }]
},
{
"path": ["org.iso.18013.5.1", "birth_date"],
"mandatory": true,
"display": [{ "name": "Date of Birth", "locale": "en-US" }]
},
{
"path": ["org.iso.18013.5.1", "document_number"],
"mandatory": true,
"display": [{ "name": "Document Number", "locale": "en-US" }]
},
{
"path": ["org.iso.18013.5.1", "age_over_18"],
"mandatory": false,
"display": [{ "name": "Age Over 18", "locale": "en-US" }]
}
]
}
}
}
Complete Example
A full issuer service create body with all three formats:
{
"type": "issuer2",
"baseUrl": "https://myorg.enterprise-sandbox.waltid.dev",
"kms": "waltid.tenant1.kms1",
"tokenKeyId": "waltid.tenant1.kms1.tokenKey",
"credentialConfigurations": {
"identity_credential": {
"format": "dc+sd-jwt",
"scope": "identity_credential",
"vct": "{vctBaseURL}/identity_credential",
"cryptographic_binding_methods_supported": ["jwk", "did:key", "did:web"],
"credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256"] }
},
"credential_metadata": {
"display": [
{ "name": "Identity Credential", "locale": "en-US", "background_color": "#12107c", "text_color": "#FFFFFF" }
]
}
},
"OpenBadgeCredential_jwt_vc_json": {
"format": "jwt_vc_json",
"scope": "OpenBadgeCredential_jwt_vc_json",
"cryptographic_binding_methods_supported": ["jwk", "did:key", "did:web", "did:jwk"],
"credential_signing_alg_values_supported": ["ES256", "EdDSA"],
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256", "EdDSA"] }
},
"credential_definition": {
"type": ["VerifiableCredential", "OpenBadgeCredential"]
},
"credential_metadata": {
"display": [
{ "name": "Open Badge Credential", "locale": "en-US", "background_color": "#1a365d", "text_color": "#FFFFFF" }
]
}
},
"org.iso.18013.5.1.mDL": {
"format": "mso_mdoc",
"scope": "org.iso.18013.5.1.mDL",
"doctype": "org.iso.18013.5.1.mDL",
"cryptographic_binding_methods_supported": ["cose_key"],
"credential_signing_alg_values_supported": [-7, -9],
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256"] }
},
"credential_metadata": {
"display": [
{ "name": "Mobile Driving License", "locale": "en-US", "background_color": "#003366", "text_color": "#FFFFFF" }
]
}
}
},
"sdJwtVcTypeMetadataConfiguration": {
"identity_credential": {
"name": "Identity Credential",
"description": "A verifiable identity credential"
}
},
"issuerDisplayConfiguration": [
{
"name": "My Organization",
"locale": "en-US"
}
]
}
Credential Configuration ID
The map key for each credential type in credentialConfigurations becomes the credentialConfigurationId. This ID is used when:
- Creating credential profiles (
credentialConfigurationId). - Referencing credentials in the OpenID4VCI metadata.
- Requesting specific credential types — via
authorization_details(credential_configuration_id) or the OAuthscopeparameter.
A common convention is {credentialType}_{format}, e.g.:
OpenBadgeCredential_jwt_vc_jsonidentity_credential(SD-JWT VC)org.iso.18013.5.1.mDL(mDoc)
Next Steps
- Setup – Create the issuer service that carries these configurations.
- Create a Profile – Bind a credential configuration to a key and data template.
- Display Configuration – Configure issuer-level branding.
