---
title: "Signed Credential Issuer Metadata"
description: "Request and verify signed OpenID4VCI Credential Issuer metadata from the walt.id Enterprise Issuer2 Service."
stack: "Enterprise Stack (commercial) — version 1.1.1"
stack_version: "1.1.1"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/services/issuer2-service/configurations/signed-metadata
generated: 2026-10-01
---
# 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

1. The client requests the Issuer2 Credential Issuer metadata endpoint.
2. The client sends `Accept: application/jwt`.
3. Issuer2 builds the current metadata and signs it with the private key referenced by the service's `tokenKeyId`.
4. 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:

```text
https://{host}/v2/{target}/issuer-service-api/openid4vci
```

the Credential Issuer metadata URL is:

```text
https://{host}/.well-known/openid-credential-issuer/v2/{target}/issuer-service-api/openid4vci
```

**Option: CURL**

**Endpoint:** `GET /.well-known/openid-credential-issuer/v2/{target}/issuer-service-api/openid4vci`

##### Example Request

```bash
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

```text
<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:

1. Confirm that the HTTP `Content-Type` is the signed media type it requested.
2. Parse the body.
3. Reject `alg: none` and symmetric algorithms.
4. Verify the signature with a trusted issuer key.
5. Confirm that `typ` is `openidvci-issuer-metadata+jwt`.
6. Confirm that `iss`, `sub`, and `credential_issuer` all equal the expected Issuer2 identifier.
7. Evaluate `iat` against the client's freshness policy.
8. Process the remaining payload fields as Credential Issuer metadata.

**Error:**

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:

```bash
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.
