Signed Credential Issuer Metadata
Issuer2 can return its OpenID4VCI Credential Issuer metadata as a signed JWT.
Signed metadata is available automatically for every Issuer2 service, using the same discovery endpoint as JSON metadata. Wallets can select the representation with the HTTP Accept header.
How It Works
- The client requests the Issuer2 Credential Issuer metadata endpoint.
- The client sends
Accept: application/jwt. - Issuer2 builds the current metadata and signs it with the private key referenced by the service's
tokenKeyId. - Issuer2 returns a compact JWS using the requested media type.
Rotating tokenKeyId changes the key used for subsequent metadata responses.
Prerequisites
Signed metadata reuses the Issuer2 service's existing tokenKeyId — the same key that signs OID4VCI access tokens — so no additional setup is required.
Request Signed Metadata
For an issuer whose identifier is:
https://{host}/v2/{target}/issuer-service-api/openid4vci
the Credential Issuer metadata URL is:
https://{host}/.well-known/openid-credential-issuer/v2/{target}/issuer-service-api/openid4vci
Endpoint: GET /.well-known/openid-credential-issuer/v2/{target}/issuer-service-api/openid4vci
Example Request
curl --request GET \
'https://{orgID}.enterprise-sandbox.waltid.dev/.well-known/openid-credential-issuer/v2/{target}/issuer-service-api/openid4vci' \
--header 'Accept: application/jwt'
Path Parameters
- orgID: String (required) - Your organization ID, e.g.
test.enterprise-sandbox.waltid.dev. - target: String (required) - The resource identifier of the issuer service,
{organizationID}.{tenantID}.{issuerServiceID}.
Example Response
<protected-header>.<payload>.<signature>
The response has status 200, the requested Content-Type, and the singed Issuer Metadata.
JWT Structure
The protected header contains:
| Header | Description |
|---|---|
alg | JWS algorithm of the signing key. |
typ | Always openidvci-issuer-metadata+jwt. |
kid | Key ID of the signing key. |
jwk | Public signing JWK. |
The payload contains the complete JSON Credential Issuer metadata plus these JWT claims:
| Claim | Description |
|---|---|
iss | The credential_issuer identifier. |
sub | The credential_issuer identifier. |
iat | Time at which Issuer2 generated the signed response, as a Unix timestamp. |
Issuer2 does not add an exp claim. A client that caches signed metadata should therefore apply its own refresh policy and respect HTTP caching controls.
Verify Signed Metadata
A consuming client should:
- Confirm that the HTTP
Content-Typeis the signed media type it requested. - Parse the body.
- Reject
alg: noneand symmetric algorithms. - Verify the signature with a trusted issuer key.
- Confirm that
typisopenidvci-issuer-metadata+jwt. - Confirm that
iss,sub, andcredential_issuerall equal the expected Issuer2 identifier. - Evaluate
iatagainst the client's freshness policy. - Process the remaining payload fields as Credential Issuer metadata.
Verifying with only the JWK embedded in the same JWT proves internal integrity, but does not by itself establish that the key belongs to the expected issuer. Bind the key to trusted issuer configuration, a trusted key distribution mechanism, or another deployment-specific trust policy.
Unsigned JSON Metadata
Request JSON explicitly when a client does not support signed metadata:
curl --request GET \
'https://{orgID}.enterprise-sandbox.waltid.dev/.well-known/openid-credential-issuer/v2/{target}/issuer-service-api/openid4vci' \
--header 'Accept: application/json'
The signed JWT payload and JSON response are generated from the same current Credential Issuer metadata.
