Implementer guide — implementing EAA issuance with OpenID4VCI¶
Audience: EAA Providers implementing issuance flows with OpenID4VCI in the German EUDI Wallet Ecosystem.
Contents¶
- Introduction
- EAA issuance architecture and infrastructure
- OpenID4VCI option space and rulebook choices
- Implementing OpenID4VCI for your EAA configuration
- Credential lifecycle management
- Protocol templates (parameterized)
- Implementation checklists
1. Introduction¶
This guide targets EAA Providers who want to issue EAAs into German EUDI Wallets using OpenID4VCI. It complements the rulebook guidance: while the rulebook (the human-readable technical and governance specification) defines what your credential is and which level of end-to-end assurance you target, this document explains how to turn those decisions into a concrete OpenID4VCI-based issuance flow.
This guide applies to EAA Providers issuing EAAs to natural person wallets in the German ecosystem. It is intended to be compatible with different EAA rulebooks and assurance targets; always treat the rulebook as the normative source for assurance and governance requirements.
Understanding Key Terminology
- Catalog of attestations: A registry where you can look up what attestations are issued in the ecosystem
- Schema metadata: A machine-consumable entry in the catalog that references the rulebook, schema, and trust list for authorized issuers
- Rulebook: The human-readable specification covering technical requirements and governance for a credential type
- Trust list: A list of authorized issuers and their certificates for a given credential type
Sandbox: Do I need to start with a rulebook?
No, if you are a prospective EAA Provider who wants to start testing a solution in the Sandbox, you don't need to have a rulebook defined out of the gate. You can start with the implementation of your issuance infrastructure and write/publish your rulebook, trust list and schema metadata when you are ready.
Known Limitations¶
Before starting implementation, be aware of these current ecosystem limitations:
Authorization Code Flow with PID for identification: Using the Authorization Code Flow with the PID for identification depends on extensions to the Authorization Code Flow that still require standardization and is only expected to become available in Q2 2026. There are alternative, though less elegant, ways of combining a PID Presentation with an OpenID4VCI issuance flow. Which solution fits best for you likely depends on your context. See Section 3.2.1 for details.
Deferred issuance: Deferred issuance is not yet supported by the EUDI Wallet reference implementation. If your use case requires deferred issuance (for example, credentials requiring manual approval or slow source system queries), you will need to use alternative approaches such as out-of-band notification when credentials are ready. See Section 5.6 for more information.
Document Structure¶
Chapter 2 gives a high-level overview of the components and infrastructure needed to run an issuance service. Chapter 3 explains the OpenID4VCI option space (grant types, proof mechanisms, formats) and how these relate to choices made in your rulebook, in particular around identification. Chapter 4 provides a practical implementation path once you have selected your EAA configuration (format, assurance target, and flow).
Where relevant, we call out aspects that are particularly important for the German EUDI Sandbox. This is a living document and guidance may change as technical details are further standardized and clarified.
2. EAA issuance architecture and infrastructure¶
This chapter describes the main technical building blocks required for EAA issuance and how they relate to your rulebook.
2.1 Core components¶
At a minimum, an EAA Provider needs the following components:
-
Issuance backend
Application logic that knows which users are eligible for which credentials and when. It connects to source systems, implements business rules from your rulebook, and orchestrates issuance flows. -
OpenID4VCI credential issuer
An HTTP API exposing the OpenID4VCI endpoints: - Issuer metadata (credential issuer metadata / well-known)
- Credential offer generation mechanism (for example, an out-of-band credential offer via QR code or deep link)
- Authorization server endpoints (if co-located)
- Token endpoint
-
Credential endpoint
This component implements the OpenID4VCI protocol and translates between wallet-facing messages and your internal data. -
Trust and signing subsystem
Infrastructure to manage: - Signing keys and certificates used for EAAs
- Connection to the trust framework (for your own EAA Provider registration and trust anchors)
- Integration with the relevant trust lists / certificate and registration scheme used in the German ecosystem
-
Key rotation, backup, and revocation
This subsystem must meet the end-to-end assurance target described in your rulebook. -
Authentic source integration
-
Systems that hold the authoritative data for the attributes in your credential (registries, core databases, line-of-business systems). Your issuance backend must retrieve and validate data from these systems at issuance time according to the attribute verification rules in your rulebook.
-
Logging, monitoring, and audit logging of issuance events, errors, and security-relevant actions, with retention and access control aligned to your governance requirements.
2.2 Optional components¶
Depending on your use case and rulebook decisions, you may additionally run:
-
User self-service portal
Allows holders to request credentials, view status, or revoke/renew credentials (where supported). -
Back-office operations console
For manual review, exception handling, and audit. -
Separate authorization server
In some deployments, the OpenID4VCI credential issuer uses an existing authorization server rather than embedding one. In others, the credential issuer and authorization server are combined.
2.3 Security Considerations¶
For each of these components, you should follow best practice for Oauth 2.0 Security. All endpoints involved in the issuance process should be TLS protected. The details are stipulated in the FAPI2 Security Profile.
2.4 Relation to the rulebook¶
Your rulebook and your issuance infrastructure are tightly coupled:
The rulebook defines:
- Credential semantics (attributes, formats, identifiers)
- End-to-end assurance target
- Identification and attribute verification methods
- Revocation and update strategies
The infrastructure must enforce:
- Identification flows compatible with the stated assurance target
- Attribute retrieval and checks from the source systems named in the rulebook
- Secure operation of the signing and status mechanisms
The OpenID4VCI profile you choose (Chapter 3) is one of the key implementation levers to achieve the rulebook’s assurance target.
3. OpenID4VCI option space and rulebook choices¶
This chapter explains the main OpenID4VCI choices an EAA Provider must make and how they relate to the rulebook.
3.1 OpenID4VCI in brief¶
OpenID4VCI specifies how wallets obtain verifiable credentials from an issuer. At a high level, the flow is:
- The EAA Provider creates a credential offer and delivers it to the wallet (for example via QR code or deep link).
- The wallet and issuer perform an authorization and token exchange (using either authorization code or pre-authorized code).
- The wallet calls the credential endpoint with proof-of-possession and receives the credential.
Your rulebook does not describe protocol details but does define the assurance and governance requirements that your OpenID4VCI deployment must satisfy.
3.2 Grant types: authorization code vs pre-authorized code¶
OpenID4VCI supports two main issuance patterns:
-
Authorization code
The holder is redirected to the issuer’s authorization server, performs an interactive authentication and consent step, and the wallet exchanges the authorization code for an access token. -
Pre-authorized code
The issuer creates a credential offer containing a pre-authorized code that is already bound to a specific user or account. The wallet uses this code directly at the token endpoint (optionally with a one-time user code or PIN) to obtain an access token, without an interactive redirect.
3.2.1 Identification and grant type¶
Identification is defined by your rulebook and by the surrounding trust framework, not by the grant type itself. However, there are typical pairings:
Authorization code with strong online identification:
- Suitable when you identify the user at issuance time via PID or another high-assurance process defined by your rulebook.
- The authorization server handles user authentication; the result is linked to issuance.
- The rulebook should state that identification happens at issuance and specify the method (for example PID-based online identification or a sector-specific process).
Pre-authorized code with prior identification
- Suitable when identification is not needed, or has already taken place in a different channel (for example, in-person onboarding at a branch or a fully compliant remote onboarding process).
- The issuance flow itself relies on that prior identification and on secure code delivery to the same person.
- The rulebook should state that identification is performed before issuance, how it is verified, and how the pre-authorized code is securely delivered and bound to that identified person.
In both cases, your end-to-end assurance target from the rulebook must consider:
- Strength of user identification (PID, sector process, account history)
- Security of the issuance infrastructure (including authorization server, credential issuer, and source systems)
- Security of the pre-authorized code lifecycle (generation, delivery, replay prevention)
The choice between authorization code and pre-authorized code does not change the assurance target, but it changes where and how you must provide evidence that the target is met.
Retrieving additional information during identification
Implementers should keep in mind that the presentation of a PID does not automatically give you a unique identifier to match against your own records. Consequently, the identification process may require you to retrieve additional data to allow you to make a unique match against internal source information.
3.3 Credential formats and rulebook decisions¶
From the rulebook you choose:
- Supported credential formats (dc+sd-jwt, mso_mdoc, or both)
- Required attributes and their semantics
- Requirements on selective disclosure and data minimization
From an OpenID4VCI perspective, this leads to:
- Definition of credential configuration identifiers (vct values or document types)
- Supported proof types and algorithms for holder binding and signing
- Mapping between internal attribute names and the technical schemas (JSON Schema, CDDL) defined for this credential type
These choices should be consistent with the EUDI and German ecosystem profiles you are targeting.
3.4 Other relevant options¶
Other OpenID4VCI elements that must align with your rulebook include:
- Proof-of-possession mechanism (for example, a JWT-based proof-of-possession, a DPoP-like pattern, or an ecosystem-specific proof object)
- Use of encrypting responses from the credential endpoint
- Handling of multiple credentials in one issuance flow (for example, EAA plus auxiliary credentials)
- Error handling and retry policies, particularly for high-assurance flows.
4. Implementing OpenID4VCI for your EAA configuration¶
This chapter outlines a practical path to implement OpenID4VCI issuance once your rulebook and EAA profile are defined.
4.1 Step 1 — Derive your issuance configuration from the rulebook¶
From your rulebook and the associated schema metadata entry in the catalog of attestations, extract the following decisions into a concrete OpenID4VCI configuration:
- Credential types and formats you will issue (credential identifiers, technical schema references, versions)
- End-to-end assurance target and associated controls
- Identification method (at issuance time or prior) and how it maps to:
- Authorization code flows, or
- Pre-authorized code flows
- Requirements for attribute verification (which source systems must be queried at issuance time)
- Revocation and update behavior (whether the credential supports updates, and how revocation status is exposed)
Document this configuration as a separate technical specification for your development team and integrators.
4.2 Step 2 — Publish issuer metadata¶
Implement and publish the OpenID4VCI metadata for your credential issuer. At a minimum this includes:
- Credential issuer identifier (URL)
- Supported credential configurations (types, formats, display information)
- Supported grant types and flows (authorization code, pre-authorized code)
- Supported proof types and algorithms
- Endpoints for token and credential issuance
The metadata must reflect the rulebook decisions about formats, assurance, and supported flows so that wallets can interact with your issuer correctly.
4.3 Step 3 — Implement authorization and token handling¶
For authorization code flows:
- Integrate with your authorization server (or embedded authorization component) that supports:
- Strong user authentication according to your rulebook
- User consent for issuance
- Binding of the authenticated user to the resulting authorization code
- Implement the token endpoint logic:
- Validate the authorization code
- Issue an access token with claims that identify the user and the intended credential configuration
- Enforce audience and scope restrictions suitable for issuance
For pre-authorized code flows:
- Implement secure generation and storage of pre-authorized codes bound to identified users or accounts.
- Decide how codes are delivered to users (out-of-band channel, secure portal, etc.), in a way that maintains the rulebook’s assurance requirements.
- Implement the token endpoint logic:
- Validate pre-authorized codes and optional user codes
- Enforce one-time use and expiry
- Issue access tokens that carry enough information to drive issuance while respecting data minimization.
In both cases, treat the token endpoint as part of your high-assurance infrastructure, with proper rate limiting, logging, and monitoring.
4.4 Step 4 — Implement the credential endpoint¶
The credential endpoint is where the wallet exchanges proof-of-possession and an access token for an actual credential. A typical implementation performs the following steps:
- Validate the access token:
- Signature and issuer
- Audience and intended use (issuance)
- Expiry and freshness
- Determine the credential configuration:
- From the request or from the access token
- Check that the requested configuration is allowed for this token and user
- Validate the proof-of-possession from the wallet:
- Check signature validity
- Check that the proof is bound to the credential issuer and to the current credential request
- Fetch and verify attributes from source systems:
- Retrieve required data
- Apply the attribute verification rules from the rulebook
- Construct the credential:
- Populate all required attributes
- Apply the correct technical schema (JSON Schema or CDDL) and credential identifiers (vct or doctype)
- Enforce data minimization and selective disclosure requirements
- Sign and return the credential:
- Use the signing keys from your trust and signing subsystem
- Apply algorithms and formats that match your credential configuration
- Return the credential in the format expected by the wallet.
5. Credential lifecycle management¶
This chapter addresses the post-issuance lifecycle of credentials and the operational implementation aspects to consider as an EAA Provider. The high-level policy decisions about lifecycle should be defined in your rulebook; this chapter focuses on implementation approaches and considerations for those decisions.
5.1 Credential validity periods¶
Every credential has a validity period. Your rulebook defines the default validity period for your credential type; this section covers the operational aspects of implementing that policy.
Implementation considerations:
Encode validity dates correctly in the credential format. SD-JWT VC uses iat and exp claims; mDoc uses validFrom and validUntil fields. Ensure your issuance logic calculates expiry dates according to your rulebook's policy. Store issuance and expiry dates in your backend systems for tracking and renewal purposes. Use UTC timestamps to avoid ambiguity across time zones.
User experience considerations:
If your rulebook specifies relatively short validity periods, consider implementing proactive user notifications. Alert holders at meaningful intervals before expiry (for example, 7 days before expiration, adjusted based on your validity period). Use available notification channels such as wallet notifications, email, or SMS. Direct users to renewal or refresh flows with clear instructions and minimal friction.
If your rulebook permits, consider implementing a grace period where slightly expired credentials can still be refreshed without requiring full re-identification.
5.2 Credential refresh¶
Credential refresh allows holders to obtain an updated version of a credential without repeating the full identification and verification process. Your rulebook defines whether refresh is supported and under what conditions.
5.2.1 Using refresh tokens (recommended)¶
Refresh tokens are the protocol-native mechanism for credential refresh in OpenID4VCI and are particularly emphasized in the HAIP (High Assurance Interoperability Profile).
How refresh tokens work:
- At initial issuance, when the wallet exchanges an authorization code or pre-authorized code at the token endpoint, the issuer returns both an
access_token(for immediate credential issuance) and arefresh_token(for future credential refresh). - When refresh is needed, the wallet presents the
refresh_tokento the token endpoint using therefresh_tokengrant type. - The issuer validates the refresh token and returns a new
access_token(and optionally a newrefresh_token). - The wallet uses the new access token at the credential endpoint to obtain a refreshed credential.
- The holder does not need to repeat the authorization flow or provide identification again.
This approach is protocol-standard, aligned with OAuth 2.0 and OpenID4VCI specifications. It provides minimal user friction since no re-authentication or manual action is required. The wallet can manage refresh automatically as credential expiry approaches, and the issuer retains control through refresh token lifetime and rotation policies.
Implementing refresh tokens:
Set refresh token expiry based on your rulebook's refresh policy. For example, if credentials are valid for 24 months and can be refreshed without re-identification, the refresh token should remain valid for at least 24 months.
Consider implementing refresh token rotation where each refresh operation returns a new refresh token and invalidates the old one. This limits exposure if a refresh token is compromised. If implementing rotation, ensure old refresh tokens cannot be reused after rotation.
Provide a mechanism to revoke refresh tokens when a holder's eligibility ends, when the holder requests it, or in case of security incidents.
Refresh tokens are long-lived bearer credentials. Ensure wallets store them securely using encrypted storage or hardware-backed keystores where available.
Token endpoint implementation for refresh:
When the token endpoint receives a refresh token grant:
POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&
refresh_token=<refresh_token_value>
Your token endpoint should:
- Validate the refresh token (signature, expiry, revocation status, issuer)
- Verify the holder's eligibility remains valid (query your internal records or source systems)
- Check whether attributes have changed since the last issuance
- Generate a new access token bound to the same credential configuration as the original issuance, the current holder eligibility state, and the credential endpoint audience
- Optionally return a new refresh token (if implementing rotation)
- Log the refresh event for audit purposes
Handling attribute changes during refresh:
When processing a refresh token request, check whether the underlying data has changed (for example, a professional license was suspended, a specialization was added). If attributes have changed, the new credential should reflect current values, not stale data from the original issuance. If attributes changed in a way that invalidates the old credential (for example, license suspended), revoke the old credential in addition to declining refresh.
Example refresh token response:
{
"access_token": "<new_access_token>",
"token_type": "Bearer",
"expires_in": 86400,
"refresh_token": "<new_refresh_token>",
"c_nonce": "<nonce_for_proof>",
"c_nonce_expires_in": 86400
}
The wallet then uses the new access_token at the credential endpoint to obtain the refreshed credential, just as in the original issuance flow.
5.2.2 Alternative refresh approaches¶
If refresh tokens are not suitable for your use case (for example, if your rulebook requires re-authentication or manual approval for renewal), consider these alternative approaches:
Self-service portal with on-demand generation: Provide an authenticated portal where holders can request refresh. Verify eligibility and generate a fresh credential offer. This is suitable when refresh requires holder-initiated action or manual approval workflows.
Authorization code flow with reduced authentication: If your rulebook permits re-using recent identification evidence (within a defined time window), implement an authorization flow that requires only account authentication (not full re-identification). This is useful for credentials where identification was strong at initial issuance but can be relied upon for a limited time.
5.2.3 Refresh implementation checklist¶
Regardless of which approach you use, you should consider the following topics:
- Eligibility verification: Confirm the holder's underlying eligibility remains valid by querying internal records or source systems.
- Attribute freshness: Query source systems at refresh time to ensure attribute values are current. Never blindly re-issue stale data.
- Attribute change handling: If attributes have changed, issue an updated credential with new values and log the change for audit purposes.
- Key binding policy: Determine whether refreshed credentials maintain holder binding to the same key or allow key rotation. Your rulebook should specify this.
- Audit logging: Log refresh events with sufficient detail to support audits.
- User notifications: If implementing proactive refresh, notify holders when a refresh is available or has occurred.
- Error handling: Handle cases where refresh fails (eligibility ended, attributes cannot be verified, etc.) with clear user-facing messages.
5.3 Credential revocation¶
Revocation invalidates a credential before its natural expiry. Your rulebook defines the revocation policy including when revocation is required, which mechanism to use, and who can request it. This section covers the technical implementation.
Implementing status lists (recommended):
If your rulebook specifies status lists (for example, StatusList2021), implement the following components:
Status list infrastructure: Maintain a bit array representing credential status (0 = valid, 1 = revoked). Publish the status list at a stable, publicly accessible HTTPS URL. Update the list according to your rulebook's latency requirement (for example, within 4 hours).
Credential referencing: Include a status list reference in each credential at issuance time. Specify the status list URL and the credential's index position. For SD-JWT VC, include this in the status claim. For mDoc, include it in the appropriate namespace or element.
Revocation workflow: Provide an API or back-office interface for authorized parties to submit revocation requests. Validate the requestor's authority based on your rulebook policy. Update the status list by flipping the appropriate bit. Publish the updated list within the latency window defined in your rulebook. Log the revocation event with timestamp, requestor identity, and reason.
Privacy considerations: Status lists are fetched by relying parties, not by the issuer on each verification. Holders are not tracked when their credentials are verified. Use sufficiently large status lists to prevent correlation attacks.
Operational implementation:
Regardless of which revocation mechanism you use, implement the following operational capabilities:
Revocation request interface: Provide a web portal, API, or back-office system for authorized parties to request revocation.
Authorization checks: Verify that the requestor is authorized according to your rulebook policy (holder via authenticated portal, regulatory authority via trusted channel, etc.).
Notification system: Send notifications to affected holders when their credentials are revoked using email, wallet notification, or SMS.
Audit logging: Log all revocation requests and actions with sufficient detail to support compliance audits.
Monitoring: Monitor revocation infrastructure availability and latency to ensure compliance with your rulebook's SLA.
5.4 Issuer key and certificate rotation¶
EAA Providers sign credentials using cryptographic keys associated with a certificate issued under the German EUDI trust framework. Over time, you will need to rotate these keys and certificates. Your rulebook defines signature requirements; this section covers the operational process of key and certificate rotation.
Routine rotation:
Key rotation is a normal part of secure operations. Certificates have a defined validity period and must be renewed before expiry. Periodic key rotation reduces risk exposure and is often required by security policies. During rotation, you should support a transition period where both old and new keys are trusted.
Implementation approach:
Obtain a new certificate from the trust framework before the current certificate expires. Publish the new certificate in the trust registry and update your issuer metadata. Begin signing new credentials with the new key. Continue to maintain the old certificate in the trust registry for the duration of its validity (or longer if credentials signed with it are still in circulation). Wallets and verifiers can validate credentials signed with either key during the transition period.
Impact on existing credentials:
Credentials issued and signed with the old key remain valid and verifiable as long as the old certificate is still within its validity period, or the trust registry maintains historical certificate information and verifiers are configured to accept credentials signed by expired-but-once-valid issuer certificates (depending on ecosystem policy).
Your rulebook and operational documentation should clarify the expected lifetime of credentials relative to issuer certificate lifetimes.
5.5 Security incident response¶
As an EAA Provider, you should prepare for security incidents that may affect the integrity of your issuance infrastructure or the credentials you've issued. While incidents vary in nature and severity, having a response plan helps minimize impact on holders and verifiers.
Types of security incidents to consider:
Key compromise: Your signing key is exposed or stolen, potentially allowing unauthorized credential issuance.
Infrastructure breach: Unauthorized access to your issuance systems, source systems, or holder data.
Process failure: Credentials issued with incorrect attributes or to wrong holders.
Trust framework changes: Changes in trust framework policy that affect your credentials' validity.
Certificate issues: Discovery that your issuer certificate was issued improperly or should be revoked.
Example response to key compromise:
If your signing key is compromised, you would typically follow these steps. First, contain the incident by securing your infrastructure and preventing further unauthorized issuance. Second, revoke the compromised certificate by submitting a revocation request to the trust framework authority. Third, assess the impact by determining which credentials may be affected and what the timeline of compromise was. Fourth, obtain a new certificate by completing the trust framework registration process with a new key pair. Fifth, notify affected parties by communicating with holders, verifiers, and the ecosystem operator about the incident, timeline, and next steps. Sixth, re-issue credentials by providing a clear process for holders to obtain new credentials signed with the new key. Finally, review and improve security by conducting a post-incident review and implementing measures to prevent recurrence.
Impact of certificate revocation:
Revoking your issuer certificate has significant consequences. All credentials signed with that key may be considered invalid by verifiers, depending on trust framework policy. Holders will need to obtain new credentials signed with a new, trusted key. You will need to communicate the incident and remediation steps clearly and quickly.
Operational planning:
Consider including the following in your operational documentation: an incident response plan covering various security scenarios, contact information and escalation paths for trust framework authorities, communication templates for notifying holders and relying parties, processes for mass re-issuance if necessary, roles and responsibilities during an incident, and procedures for testing and exercising your incident response capabilities.
5.6 Deferred issuance¶
Deferred issuance is an OpenID4VCI feature that allows an issuer to accept a credential request but defer the actual issuance until a later time (for example, pending manual review, background checks, or asynchronous data retrieval).
Current status in the EUDI ecosystem:
Deferred issuance is not yet supported by the EUDI Wallet reference implementation. If your use case requires deferred issuance, you should monitor ecosystem updates for support timelines and consider alternative approaches in the interim (for example, notify the holder out-of-band when the credential is ready and issue a new credential offer).
Use cases for deferred issuance:
Manual approval workflows where a credential requires human review. Credentials that depend on slow or batch-processed source systems. Credentials with complex eligibility rules that cannot be evaluated in real-time.
Planning considerations:
If you anticipate needing deferred issuance, document this requirement in your rulebook and integration plans. Design your issuance workflows to be adaptable when deferred issuance becomes available.
6. Protocol templates (parameterized)¶
The templates in this chapter are structurally realistic but parameterized and non-normative. Replace placeholders with the values required by the German ecosystem profile you are targeting.
6.1 Credential issuer metadata (template)¶
{
"credential_issuer": "https://issuer.example",
"credential_endpoint": "https://issuer.example/credential",
"token_endpoint": "https://issuer.example/token",
"credential_configurations_supported": {
"eaa_example_sd_jwt": {
"format": "dc+sd-jwt",
"vct": "urn:example:eaa:1",
"credential_signing_alg_values_supported": ["ES256"]
},
"eaa_example_mdoc": {
"format": "mso_mdoc",
"doctype": "org.example.eaa.1",
"credential_signing_alg_values_supported": ["ES256"]
}
},
"grant_types_supported": [
"authorization_code",
"urn:ietf:params:oauth:grant-type:pre-authorized_code"
],
"authorization_server": "https://as.example"
}
6.2 Credential offers (templates)¶
Authorization code grant:
{
"credential_issuer": "https://issuer.example",
"credential_configuration_ids": ["eaa_example_sd_jwt"],
"grants": {
"authorization_code": {
"issuer_state": "<opaque_state>"
}
}
}
Pre-authorized code grant:
{
"credential_issuer": "https://issuer.example",
"credential_configuration_ids": ["eaa_example_sd_jwt"],
"grants": {
"urn:ietf:params:oauth:grant-type:pre-authorized_code": {
"pre-authorized_code": "<one_time_code>",
"user_pin_required": true
}
}
}
Security note: - Treat the pre-authorized code as a bearer secret. Anyone who obtains it may be able to redeem it. - Prefer delivering pre-authorized codes via an authenticated or out-of-band channel (for example, a logged-in portal, in-person handover, or a second channel you already trust for the identified holder). - Use the pre-authorized code in combination with a PIN if needed. - Use compensating controls: short expiry, one-time use, rate limiting, and require a user PIN where appropriate.
6.3 Token requests (templates)¶
Authorization code token request:
POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=<authorization_code>&
redirect_uri=<redirect_uri>&
client_id=<wallet_client_id>
Pre-authorized code token request:
POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:pre-authorized_code&
pre-authorized_code=<one_time_code>&
user_pin=<pin_if_required>
6.4 Credential request (template)¶
POST /credential HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json
{
"credential_configuration_id": "eaa_example_sd_jwt",
"proof": {
"proof_type": "jwt",
"jwt": "<proof_jwt>"
}
}
In the German ecosystem, proof-of-possession at the OpenID4VCI layer uses a JWT proof (proof_type: "jwt"). This proof mechanism is independent of the credential format you issue (dc+sd-jwt or mso_mdoc) and is used to bind issuance to a wallet-held key. In the future, the 'attestation' proof_type will also be supported.
7. Implementation checklists¶
7.1 Decision checklist (rulebook-to-protocol mapping)¶
Before building, ensure your rulebook answers:
- When is the holder identified: during issuance (online) or prior to issuance (re-used)?
- Which grant type do you support: authorization code, pre-authorized code, or both?
- Which credential formats do you issue: dc+sd-jwt, mso_mdoc, or both?
- Which source systems must be queried at issuance time?
- What is your end-to-end assurance target and which operational controls are mandatory?
7.2 Metadata checklist¶
- Metadata is reachable over HTTPS and returns correct content type.
- Metadata declares the same capabilities you actually implement:
- supported formats and configuration identifiers
- supported grant types
- token and credential endpoints
- supported algorithms and proof types required by the ecosystem profile
7.3 Token endpoint checklist¶
- Validate grant type and required parameters.
- Enforce expiry and one-time use semantics for codes.
- Ensure tokens intended for issuance are not accepted at other APIs and vice versa (audience scoping).
- Bind tokens to:
- intended credential configuration(s)
- intended subject / eligibility record
- intended audience (issuance)
- Rate limit and log suspicious activity.
- Log token grants using pseudonymous identifiers where possible to support audits without violating data minimization.
7.4 Credential endpoint checklist¶
- Validate access token (signature, expiry, audience, scope/claims).
- Validate wallet proof-of-possession according to the ecosystem profile.
- Perform source system lookups and apply the rulebook's attribute verification rules.
- Construct credential using the correct technical schemas and credential identifiers (vct for SD-JWT, doctype for mDoc), and enforce data minimization.
- Ensure status / revocation information required by the rulebook is correctly attached or referenced.
- Sign using protected keys and return the correct format (dc+sd-jwt or mso_mdoc).
- Ensure error responses do not leak sensitive information but are specific enough for wallet implementers to debug.