Credential Configuration¶
Credential configurations define the structure and properties of individual credentials. Each credential type has its own configuration file.
Basic Structure¶
Each credential configuration is a JSON object that defines how a specific credential type should be issued. The configuration includes metadata, display information, claims, and various optional features like key binding and status management.
For a complete configuration example, see the Complete Configuration Example section at the bottom of this page.
Info
The data object for the import can be found in the API Documentation
Configuration Fields¶
Required Fields¶
id: REQUIRED - Unique identifier for the credential configuration that will be used to reference this credential in the issuance metadata or in the credential offer.config: REQUIRED - Entry for credential_configuration_supported.format: REQUIRED - The format of the credential, onlydc+sd-jwtis currently supported.display: REQUIRED - Display configuration for the credential, including name, description, locale, colors, and images.
Optional Fields¶
description: OPTIONAL - Human-readable description of the credential. Will not be displayed to the end user.vct: OPTIONAL - VC Type Metadata provided via the/{tenantId}/credentials-metadata/vct/{id}endpoint. This link will automatically added into the credential.keyId: OPTIONAL - Unique identifier for the key used to sign the credential. If not provided, the first key in the key set will be used. See Signing Key for details.lifeTime: OPTIONAL - Credential expiration time in seconds. If specified, credentials will include anexpclaim calculated asiat + lifeTime. See Credential Expiration for details.statusManagement: OPTIONAL - Enable OAuth Token Status Lists for credential revocation. Whentrue, credentials include astatusclaim with revocation information. See Status Management and Revocation for details.keyBinding: OPTIONAL - Enable cryptographic key binding. Whentrue, credentials include acnfclaim with the holder's public key and require proof of possession. See Cryptographic Key Binding for details.claims: OPTIONAL - Static claims to include in the credential. Can be overridden by webhook responses or claims passed during credential offer.claimsWebhook: OPTIONAL - Webhook to receive claims for the issuance process. See Webhooks for details.notificationWebhook: OPTIONAL - Webhook to send notifications about the issuance process. See Webhooks for details.disclosureFrame: OPTIONAL - Defines which claims should be selectively disclosable in SD-JWT format.embeddedDisclosurePolicy: OPTIONAL - Defines the embedded disclosure policy for the credential. See Embedded Disclosure Policy for details.schema: OPTIONAL - JSON schema for validating the credential claims.
Fetching Claims¶
Claims define the data that will be included in the credential. This section covers how to configure claims at the credential configuration level.
Claims Priority System
EUDIPLO supports multiple ways to provide claims (configuration-level and offer-level), with a priority system that determines which claims are used. For a complete explanation of the claims priority order and when to use each method, see Passing Claims in the Issuance Overview.
Static Claims¶
You can specify static claims directly in the credential configuration. These claims will be used as defaults for every credential issued using this configuration:
{
"claims": {
"issuing_country": "DE",
"issuing_authority": "DE",
"given_name": "ERIKA",
"family_name": "MUSTERMANN",
"birth_family_name": "GABLER",
"birthdate": "1964-08-12",
"age_birth_year": 1964,
"age_in_years": 59,
"age_equal_or_over": {
"12": true,
"14": true,
"16": true,
"18": true,
"21": true,
"65": false
},
"place_of_birth": {
"locality": "BERLIN"
},
"address": {
"locality": "KÖLN",
"postal_code": "51147",
"street_address": "HEIDESTRAẞE 17"
},
"nationalities": ["DE"]
}
}
Static claims are useful for:
- Default values for all credentials of this type
- Fixed metadata (e.g., issuing country, issuing authority)
- Development and testing scenarios
Claims Webhook¶
For dynamic claim retrieval, you can configure a webhook that will be called during the issuance process to fetch claims:
{
"claimsWebhook": {
"url": "https://your-backend.com/api/claims",
"headers": {
"Authorization": "Bearer your-token"
}
}
}
The webhook will receive information about the issuance session and must return the claims to be included in the credential.
Claims webhooks are useful when:
- Claims need to be fetched from an external system or database
- Claims should be personalized based on the authentication context
- Claims depend on real-time data
For detailed information about webhook implementation, payload structure, and examples, see Claims Webhook.
Notification Webhook¶
You can configure a webhook to receive notifications about the issuance process. This allows you to track the status of credential issuance and take appropriate actions:
{
"notificationWebhook": {
"url": "https://your-backend.com/api/notifications",
"headers": {
"Authorization": "Bearer your-token"
}
}
}
The notification webhook will be called at various stages of the issuance process, such as:
- When a credential is successfully issued
- When an issuance request fails
- When a credential is accepted by the holder
For more details about the webhook implementation and payload structure, see Notification Webhook.
Info
When a webhook is configured on credential config level, it will will sent the notification to this endpoint and not also to the one provided in the issuance config. It can also be overwritten via the credential offer.
Selective Disclosure¶
Use the disclosureFrame to make specific claims selectively disclosable in
SD-JWT format:
{
"disclosureFrame": {
"_sd": [
"issuing_country",
"issuing_authority",
"given_name",
"family_name",
"birth_family_name",
"birthdate",
"age_birth_year",
"age_in_years",
"age_equal_or_over",
"place_of_birth",
"address",
"nationalities"
],
"address": {
"_sd": ["locality", "postal_code", "street_address"]
}
}
}
This configuration allows:
- Individual disclosure of personal information fields
- Selective disclosure of address components
- Holders can choose which claims to reveal during presentation
Display Configuration¶
The display configuration defines how the credential appears in wallets as defined in the OID4VCI spec for the credential metadata:
{
"display": [
{
"name": "Personal Identity Document",
"description": "Official identity credential",
"locale": "en-US",
"background_color": "#FFFFFF",
"text_color": "#000000",
"logo": {
"uri": "issuer.png"
},
"background_image": {
"uri": "credential-bg.png"
}
}
]
}
Display Fields¶
name: Display name for the credentialdescription: Brief description of the credentiallocale: Language/locale (e.g., "en-US", "de-DE")background_color: Background color (hex format)text_color: Text color (hex format)logo: Issuer logo configurationbackground_image: Background image for the credential
Info
When no uri is passed, EUDIPLO will resolve the image based the storage system, see the image configuration. If the image cannot be found, the URI will be ignored.
Signing Key¶
The signing key is used to create the digital signature for the credential. It is essential for ensuring the integrity and authenticity of the credential. If none is provided, the first key in the key set will be used. The matching certificate will be included in the x5c field of the issued credential.
Configuration¶
Note
Keys can be managed through the /keys API endpoint.
Cryptographic Key Binding¶
Cryptographic key binding ensures that a credential can only be used by the
holder who possesses the corresponding private key. This is enabled through the
keyBinding configuration option.
Configuration¶
How It Works¶
When keyBinding is enabled:
- The credential includes a
cnf(confirmation claim) containing the holder's public key - During credential request, the holder must provide a proof of possession of their private key
- The resulting credential can only be presented by the holder who has the private key
Use Cases¶
- High-value credentials (identity documents, diplomas, licenses)
- Credentials requiring strong authentication
- Preventing credential theft or unauthorized use
Status Management and Revocation¶
Status management allows credentials to be revoked or suspended using OAuth
Token Status List. This is controlled by the statusManagement configuration
option.
Configuration¶
How It Works¶
When statusManagement is enabled:
- Each issued credential includes a
statusclaim with a reference to a status list - The status list tracks the revocation state of individual credentials
- The status list is provided by the service and can be fetched by verifiers
- Credentials can be revoked using the
/session/revokeendpoint - The status list is updated immediately upon revocation
Info
When a session is deleted, the relationship between the sessionId and the issued credentials is still stored to be able to revoke the credentials. Only the sessionId and the index is stored, no other personal data.
Benefits¶
- Real-time revocation capability
- Standards-compliant status tracking
- Verifiers can check credential validity
- Granular control over credential lifecycle
Status Configuration¶
By default EUDIPLO will create a status list where each credential is managed with one bit. This means only Valid and Revoked status is possible. To support suspension or other states like defined specification, you need to update the configuration options by setting the STATUS_BITS options at least to 2.
TODO
Move status configuration to the issuance config: https://github.com/openwallet-foundation-labs/eudiplo/issues/276
| Key | Type | Notes |
|---|---|---|
STATUS_LENGTH |
number |
The length of the status list (default: 10000) |
STATUS_BITS |
number |
The number of bits used per status entry (default: 1) |
Info
More granular configuration is planned for the future. When a tenant is created, it will use the same status list for all credentials. Automatic creation of new lists or dedicated lists per credential configuration is planned for the future.
Credential Expiration¶
Credential expiration allows setting a specific lifetime for credentials using
the lifeTime configuration option (specified in seconds).
Configuration¶
{
"config": {
"format": "dc+sd-jwt",
"display": [
{
"name": "Temporary Credential",
"description": "Time-limited credential"
}
]
},
"lifeTime": 3600,
"claims": {
"given_name": "ERIKA",
"family_name": "MUSTERMANN"
}
}
How It Works¶
When lifeTime is specified:
- The credential includes an
exp(expiration) claim - The expiration time is calculated as:
iat(issued at) +lifeTime - Example:
"lifeTime": 3600creates credentials valid for 1 hour - Example:
"lifeTime": 86400creates credentials valid for 24 hours
Common Lifetime Values¶
| Duration | Seconds | Use Case |
|---|---|---|
| 1 hour | 3600 | Short-term access tokens |
| 1 day | 86400 | Daily passes, temporary IDs |
| 1 week | 604800 | Weekly permits |
| 1 month | 2592000 | Monthly subscriptions |
| 1 year | 31536000 | Annual licenses |
Embedded Disclosure Policy¶
The embedded disclosure policy defines rule to which the credential can be disclosed.
There are four supported policy mechanisms:
None¶
when policy is set to none, then there is no restriction on disclosure and claims can be revealed without any constraints.
Allow List¶
When policy is set to allow, only relying parties explicitly listed in the credential can access the claims.
Root of Trust¶
When policy is set to rootOfTrust, only relying parties that have a valid trustchain to the explicitly listed root of trust can access the claims.
Attestation Based¶
When policy is set to attestationBased, only relying parties that can present a valid attestation can access the claims.
{
"policy": "attestationBased",
"values": [
{
"claims": [
{
"id": "card",
"path": ["given_name"]
}
],
"credentials": [
{
"id": "card",
"format": "sd-jwt-dc",
"meta": {
"vct_values": "https://example.com/member-card"
},
"trusted_authorities": [
{
"type": "aki",
"values": ["s9tIpPmhxdiuNkHMEWNpYim8S8Y"]
}
]
}
],
"credential_sets": [
{
"options": [["card"]]
}
]
}
]
}
Complete Configuration Example¶
Here's a complete example of a credential configuration (PID - Personal Identity Document) that demonstrates many of the available features:
{
"id": "pid",
"description": "Personal ID",
"config": {
"format": "dc+sd-jwt",
"scope": "pid",
"display": [
{
"name": "PID",
"description": "PID Credential",
"locale": "en-US",
"background_color": "#FFFFFF",
"text_color": "#000000",
"background_image": {
"uri": "identity-card.jpg"
},
"logo": {
"uri": "logo.jpg"
}
}
]
},
"claims": {
"issuing_country": "DE",
"issuing_authority": "DE",
"given_name": "ERIKA",
"family_name": "MUSTERMANN",
"birth_family_name": "GABLER",
"birthdate": "1964-08-12",
"age_birth_year": 1964,
"age_in_years": 59,
"age_equal_or_over": {
"12": true,
"14": true,
"16": true,
"18": true,
"21": true,
"65": false
},
"place_of_birth": {
"locality": "BERLIN"
},
"address": {
"locality": "KÖLN",
"postal_code": "51147",
"street_address": "HEIDESTRAẞE 17"
},
"nationalities": [
"DE"
]
},
"disclosureFrame": {
"_sd": [
"issuing_country",
"issuing_authority",
"given_name",
"family_name",
"birth_family_name",
"birthdate",
"age_birth_year",
"age_in_years",
"age_equal_or_over",
"place_of_birth",
"address",
"nationalities"
],
"address": {
"_sd": [
"locality",
"postal_code",
"street_address"
]
}
},
"vct": {
"name": "PID",
"description": "PID credential"
},
"keyBinding": true,
"keyId": "039af178-3ca0-48f4-a2e4-7b1209f30376",
"statusManagement": true,
"lifeTime": 604800,
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"issuing_country": {
"type": "string",
"title": "Issuing Country"
},
"issuing_authority": {
"type": "string",
"title": "Issuing Authority"
},
"given_name": {
"type": "string",
"title": "Given Name"
},
"family_name": {
"type": "string",
"title": "Family Name"
},
"birth_family_name": {
"type": "string",
"title": "Birth Family Name"
},
"birthdate": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"title": "Birthdate"
},
"age_birth_year": {
"type": "integer",
"title": "Birth Year"
},
"age_in_years": {
"type": "integer",
"title": "Age in Years"
},
"age_equal_or_over": {
"type": "object",
"title": "Age Equal or Over",
"properties": {
"12": {
"type": "boolean",
"title": "12 or Over"
},
"14": {
"type": "boolean",
"title": "14 or Over"
},
"16": {
"type": "boolean",
"title": "16 or Over"
},
"18": {
"type": "boolean",
"title": "18 or Over"
},
"21": {
"type": "boolean",
"title": "21 or Over"
},
"65": {
"type": "boolean",
"title": "65 or Over"
}
},
"required": [
"12",
"14",
"16",
"18",
"21",
"65"
]
},
"place_of_birth": {
"type": "object",
"title": "Place of Birth",
"properties": {
"locality": {
"type": "string",
"title": "Locality"
}
},
"required": [
"locality"
]
},
"address": {
"type": "object",
"title": "Address",
"properties": {
"locality": {
"type": "string",
"title": "Locality"
},
"postal_code": {
"type": "string",
"title": "Postal Code"
},
"street_address": {
"type": "string",
"title": "Street Address"
}
},
"required": [
"locality",
"postal_code",
"street_address"
]
},
"nationalities": {
"type": "array",
"title": "Nationalities",
"items": {
"type": "string",
"title": "Nationality"
}
}
},
"required": [
"issuing_country",
"issuing_authority",
"given_name",
"family_name",
"birth_family_name",
"birthdate",
"age_birth_year",
"age_in_years",
"age_equal_or_over",
"place_of_birth",
"address",
"nationalities"
],
"title": "PID Claims",
"description": "Schema for PID credential claims, describing personal and identity information fields."
},
"embeddedDisclosurePolicy": {
"policy": "attestationBased",
"values": [
{
"claims": [
{
"id": "card",
"path": [
"given_name"
]
}
],
"credentials": [
{
"id": "card",
"format": "sd-jwt-dc",
"meta": {
"vct_values": "https://example.com/member-card"
},
"trusted_authorities": [
{
"type": "aki",
"values": [
"s9tIpPmhxdiuNkHMEWNpYim8S8Y"
]
}
]
}
],
"credential_sets": [
{
"options": [
[
"card"
]
]
}
]
}
]
}
}
This example includes:
- Required fields:
id,configwith format and display information - Optional fields:
description,vct,keyId,lifeTime,statusManagement,keyBinding - Claims: Static claims that will be included in every issued credential
- Selective disclosure:
disclosureFramedefining which claims can be selectively disclosed - Display configuration: How the credential appears in wallets, including colors, logos, and images
You can use it as a template or use the generated JSON Schema to create your own credential configurations by modifying the fields according to your requirements.