Skip to main content

Configure credential types

This guide shows you how to configure Type Metadata for the Truvity EUDIW Connector. Type Metadata defines the credential types your connector can issue—including claim definitions, selective disclosure settings, display metadata, and the Verifiable Credential Type (VCT) URI that wallets use to identify the credential type.

Prerequisites

Overview

Type Metadata is a JSON document that describes a credential type. It tells the connector which claims to include in a credential and what display information to present to wallets. The connector loads Type Metadata from its configuration at startup and serves it at a public endpoint (/oidc4vci/types/{credential_configuration_id}) so wallets can discover supported credential types.

Type Metadata feeds into the connector's Credential Issuer Metadata—the credential_configurations_supported map that wallets read from GET /.well-known/openid-credential-issuer. Each entry in that map corresponds to a configured credential configuration. When you create a credential offer, the credential_configuration_id must match a key in this map.

Time to implement: 30 minutes.

Step 1: Define Type Metadata

Create a Type Metadata JSON document for your credential type. The document follows the SD-JWT VC draft-13 §6.3 array-form schema. The example below defines an Account Ownership Credential (AOC) with bank account claims and selective disclosure settings.

{
"vct": "https://issuer.example.com/oidc4vci/types/AccountOwnershipCredential",
"display": [
{ "lang": "en-US", "name": "Account Ownership Credential" }
],
"claims": [
{ "path": ["bankName"], "sd": "allowed", "display": [{ "lang": "en-US", "label": "Bank name" }] },
{ "path": ["accountHolder"], "sd": "allowed", "display": [{ "lang": "en-US", "label": "Account holder" }] },
{ "path": ["accountNumber"], "sd": "allowed", "display": [{ "lang": "en-US", "label": "Account number" }] },
{ "path": ["iban"], "sd": "allowed", "display": [{ "lang": "en-US", "label": "IBAN" }] },
{ "path": ["bic"], "sd": "allowed", "display": [{ "lang": "en-US", "label": "BIC" }] },
{ "path": ["currency"], "sd": "allowed", "display": [{ "lang": "en-US", "label": "Currency" }] },
{ "path": ["accountType"], "sd": "allowed", "display": [{ "lang": "en-US", "label": "Account type" }] }
]
}

Key fields:

  • vct—a VCT URI placeholder. When vct.source is local, the connector rewrites this field to {base_url}/oidc4vci/types/{credential_configuration_id} at startup, making the Type Metadata available at a publicly resolvable URL. You can set any value here—the connector overrides it.
  • display—an array of localized display entries for the credential type. Each entry requires lang (a BCP47 language tag) and name (the display name wallets show for this credential). The connector uses this array in the Credential Issuer Metadata.
  • claims—an array of claim definitions. Each entry contains:
    • path—a JSON pointer array identifying the claim (for example, ["iban"] for a top-level claim, or ["address", "street"] for a nested claim).
    • sd—the selective disclosure policy: "allowed" (wallet holder can choose to disclose), "always" (always disclosed), or "never" (never selectively disclosable).
    • display—an array of localized display entries with lang and label that wallets show as the human-readable claim name.
note

When vct.source is local, the connector automatically generates the public VCT URL from its base_url and the credential configuration ID. You don't need to configure a separate VCT hosting endpoint. When vct.source is external, you provide the URL directly and are responsible for hosting the Type Metadata at that URL. For external sources, the connector injects a default display entry with lang: "en-US" and name set to the credential configuration ID if the display array is missing.

Step 2: Load Type Metadata into the connector

The connector loads Type Metadata from its configuration at startup. Each credential configuration references a Type Metadata JSON file via the credential_configurations configuration section.

# Configure a credential type with a local Type Metadata file
export CONNECTOR_CREDENTIAL_CONFIGURATIONS_ACCOUNTOWNERSHIPCREDENTIAL_VCT_SOURCE=local
export CONNECTOR_CREDENTIAL_CONFIGURATIONS_ACCOUNTOWNERSHIPCREDENTIAL_VCT_FILEPATH=/config/type-metadata/aoc.json
export CONNECTOR_CREDENTIAL_CONFIGURATIONS_ACCOUNTOWNERSHIPCREDENTIAL_SCOPE=aoc_credential

Each credential configuration requires:

  • vct.source—how the Type Metadata is loaded. Use local for a file on disk (the connector serves it at {base_url}/oidc4vci/types/{config_id}), or external for a URL that wallets resolve directly.
  • vct.filepath—path to the Type Metadata JSON file (required when source is local).
  • vct.url—the external VCT URL (required when source is external). You are responsible for hosting the Type Metadata at this URL.
  • scope—the OAuth 2.0 scope associated with this credential type.

The credential configuration key (for example, AccountOwnershipCredential in CONNECTOR_CREDENTIAL_CONFIGURATIONS_ACCOUNTOWNERSHIPCREDENTIAL_*) becomes the credential_configuration_id you pass when creating offers. The environment variable uses an uppercase representation of the key, but the actual credential_configuration_id preserves the original casing.

For Kubernetes deployments, store Type Metadata as a ConfigMap and mount it into the connector pod:

spec:
containers:
- name: connector
env:
- name: CONNECTOR_CREDENTIAL_CONFIGURATIONS_ACCOUNTOWNERSHIPCREDENTIAL_VCT_SOURCE
value: local
- name: CONNECTOR_CREDENTIAL_CONFIGURATIONS_ACCOUNTOWNERSHIPCREDENTIAL_VCT_FILEPATH
value: /config/type-metadata/aoc.json
- name: CONNECTOR_CREDENTIAL_CONFIGURATIONS_ACCOUNTOWNERSHIPCREDENTIAL_SCOPE
value: aoc_credential
volumeMounts:
- name: type-metadata
mountPath: /config/type-metadata/
readOnly: true
volumes:
- name: type-metadata
configMap:
name: connector-type-metadata

The connector serves the loaded Type Metadata at a public endpoint. Wallets discover available credential types through the Credential Issuer Metadata endpoint.

Step 3: Verify the configuration

After starting the connector with your Type Metadata, verify that the credential type appears in the Credential Issuer Metadata.

curl -s https://connector.example.com/.well-known/openid-credential-issuer | jq .

The response should include your credential type in the credential_configurations_supported map:

{
"credential_issuer": "https://connector.example.com",
"authorization_servers": ["https://auth.example.com"],
"credential_endpoint": "https://connector.example.com/oidc4vci/credential",
"nonce_endpoint": "https://connector.example.com/oidc4vci/nonce",
"credential_configurations_supported": {
"AccountOwnershipCredential": {
"format": "dc+sd-jwt",
"scope": "aoc_credential",
"vct": "https://connector.example.com/oidc4vci/types/AccountOwnershipCredential",
"cryptographic_binding_methods_supported": ["jwk"],
"credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
"proof_signing_alg_values_supported": ["ES256"]
}
},
"credential_metadata": {
"display": [
{
"name": "Account Ownership Credential",
"locale": "en-US"
}
],
"claims": [
{ "path": ["bankName"], "display": [{ "name": "Bank name", "locale": "en-US" }] },
{ "path": ["accountHolder"], "display": [{ "name": "Account holder", "locale": "en-US" }] },
{ "path": ["accountNumber"], "display": [{ "name": "Account number", "locale": "en-US" }] },
{ "path": ["iban"], "display": [{ "name": "IBAN", "locale": "en-US" }] },
{ "path": ["bic"], "display": [{ "name": "BIC", "locale": "en-US" }] },
{ "path": ["currency"], "display": [{ "name": "Currency", "locale": "en-US" }] },
{ "path": ["accountType"], "display": [{ "name": "Account type", "locale": "en-US" }] }
]
}
}
},
"signed_metadata": "<JWS signed with access certificate private key>"
}

Confirm that:

  1. Your credential configuration key (for example, AccountOwnershipCredential) appears as a key in credential_configurations_supported.
  2. The vct value matches {base_url}/oidc4vci/types/{credential_configuration_id} (for local source) or your external URL.
  3. The credential_metadata.display array reflects the display entries from your Type Metadata document.
  4. The credential_metadata.claims array includes your configured claims with path arrays.
  5. The scope field matches the scope you configured.

Testing

Test checklist

  • Credential Issuer Metadata endpoint (GET /.well-known/openid-credential-issuer) returns a response
  • credential_configurations_supported contains your credential configuration key
  • The vct field is {base_url}/oidc4vci/types/{credential_configuration_id} (for local source)
  • The format field is dc+sd-jwt
  • The scope field matches your configured scope
  • credential_metadata.display includes your credential type display entries with name and locale
  • credential_metadata.claims includes your claims with path arrays
  • proof_types_supported includes jwt with ES256
  • cryptographic_binding_methods_supported includes jwk
  • The Type Metadata endpoint (GET /oidc4vci/types/{credential_configuration_id}) returns your JSON document with array-form display and claims
  • Creating a credential offer with the configured credential_configuration_id succeeds

Troubleshooting

unknown_credential_configuration error when creating an offer

The credential_configuration_id in your offer request doesn't match any configured credential type. Verify that:

  1. The credential configuration key in your environment variables matches the credential_configuration_id you use in the offer request (for example, CONNECTOR_CREDENTIAL_CONFIGURATIONS_ACCOUNTOWNERSHIPCREDENTIAL_* maps to credential_configuration_id: "AccountOwnershipCredential").
  2. The Type Metadata path in CONNECTOR_CREDENTIAL_CONFIGURATIONS_<ID>_VCT_FILEPATH points to a valid JSON file.
  3. The connector restarted after you added or modified credential configuration environment variables.

VCT URI not publicly resolvable

Wallets fetch the vct URI to retrieve credential type metadata. When using vct.source=local, the connector serves the Type Metadata at {base_url}/oidc4vci/types/{credential_configuration_id}—ensure your base_url is publicly reachable. When using vct.source=external:

  1. Verify the URI is accessible from the public internet (not just your internal network).
  2. Check that the domain has valid DNS records and TLS certificates.
  3. Ensure no firewall rules block external access to the URI.

Missing required fields in Type Metadata

The connector validates Type Metadata at startup. If the connector fails to start after adding a Type Metadata file, check the logs for validation errors. Common issues:

  • Missing or unreadable file—the path in CONNECTOR_CREDENTIAL_CONFIGURATIONS_<ID>_VCT_FILEPATH must point to a valid JSON file.
  • Invalid JSON—the file must be valid JSON that can be parsed.
  • Missing vct.source—each credential configuration must specify either local or external as the source type.
  • Missing vct.filepath—required when vct.source is local.
  • Missing or empty display array—Type Metadata requires at least one display entry with lang and name.
  • Invalid claims format—claims must be an array of objects with path (non-empty array), sd, and optional display. The legacy object-keyed format is no longer accepted.

Next steps

Further reading