Important! Before you proceed, please read the EUDI Wallet Reference Implementation project description
- Overview
- Disclaimer
- Features
- Technical Details
- Endpoints
- Deployment
- Protected Resource Metadata
- How to contribute
- License
An implementation of a Wallet Provider service according to OpenId4VCI 1.0, and EUDI Wallet Standards and Technical Specifications, aiming for compliance with:
- Specification of Wallet Unit Attestations (WUA) used in issuance of PID and Attestations
- ETSI TS 119 472-3 V1.1.1
Important
Wallet Provider is created strictly for testing and development purposes.
By default, Wallet Provider acts as a MOCK Wallet Provider service, performing NO validations of platform Key Attestations
provided by Wallets, issuing Attestations with NO further checks.
Wallet Provider can be OPTIONALLY configured to perform validations of platform Key Attestations provided by Wallets, using the
Warden Supreme Attestation Library.
Caution
Wallet Provider is created strictly for testing and development purposes. It is NOT production-grade.
Wallet Provider is provided on an as-is basis, without warranties or conditions of any kind, either express or implied.
The released software is an initial development release version:
- The initial development release is an early endeavor reflecting the efforts of a short timeboxed period, and by no means can it be considered as the final product.
- The initial development release may be changed substantially over time, might introduce new features but also may change or remove existing ones, potentially breaking compatibility with your existing code.
- The initial development release is limited in functional scope.
- The initial development release may contain errors or design flaws and other problems that could cause system or other failures and data loss.
- The initial development release has reduced security, privacy, availability, and reliability standards relative to future releases. This could make the software slower, less reliable, or more vulnerable to attacks than mature software.
- The initial development release is not yet comprehensively documented.
- Users of the software must perform sufficient engineering and additional testing to properly evaluate their application and determine whether any of the open-sourced components is suitable for use in that application.
- We strongly recommend against putting this version of the software into production use.
- Only the latest version of the software will be supported
The service supports issuance of:
- Wallet Instance Attestations
- Key Attestations
per Specification of Wallet Unit Attestations (WUA) used in issuance of PID and Attestations.
Important
The service attests only EC Keys.
To issue a Wallet Instance Attestation:
- The Wallet requests a single-use Challenge from the Wallet Provider
- The Wallet generates a new Key-Pair and platform Key Attestation which contains the single-use Challenge provided by the Wallet Provider
- The Wallet requests a Wallet Instance Attestation from the Wallet Provider
- The Wallet Provider:
- Validates the single-use Challenge
- Validates the platform Key Attestation
- Verifies the platform Key Attestation contains the single-use Challenge
- Issues a Wallet Instance Attestation
sequenceDiagram
participant W as Wallet
participant WP as Wallet Provider
W->>+WP: Request single-use Challenge
WP->>+WP: Generate single-use Challenge
WP->>+W: Provide single-use Challenge
W->>+W: Generate new Key-Pair and platform Key Attestation (with single-use Challenge)
W->>+WP: Request Wallet Instance Attestation Issuance
WP->>+WP: Validate Challenge
WP->>+WP: Validate platform Key Attestation
WP->>+WP: Issue Wallet Instance Attestation
WP->>+W: Provide issued Wallet Instance Attestation
Caution
When using a Json Web Key, Wallet Provider performs NO validations and simply issues a Wallet Instance Attestation using the provided Json Web Key.
To issue a Wallet Instance Attestation:
- The Wallet generates a new Key-Pair
- The Wallet requests a Wallet Instance Attestation from the Wallet Provider
- The Wallet Provider issues a Wallet Instance Attestation
sequenceDiagram
participant W as Wallet
participant WP as Wallet Provider
W->>+W: Generate new Key-Pair
W->>+WP: Request Wallet Instance Attestation Issuance
WP->>+WP: Issue Wallet Instance Attestation
WP->>+W: Provide issued Wallet Instance Attestation
To issue a Key Attestation:
- The Wallet requests a single-use Challenge from the Wallet Provider
- The Wallet generates new Key-Pairs and platform Key Attestations which contain the single-use Challenge provided by the Wallet Provider
- The Wallet requests a Key Attestation from the Wallet Provider
- The Wallet Provider:
- Validates the single-use Challenge
- Validates the platform Key Attestations
- Verifies the platform Key Attestations contain the single-use Challenge
- Issues Key Attestation
sequenceDiagram
participant W as Wallet
participant WP as Wallet Provider
W->>+WP: Request single-use Challenge
WP->>+WP: Generate single-use Challenge
WP->>+W: Provide single-use Challenge
W->>+W: Generate new Key-Pairs and platform Key Attestations (with single-use Challenge)
W->>+WP: Request Key Attestation Issuance
WP->>+WP: Validate Challenge
WP->>+WP: Validate platform Key Attestations
WP->>+WP: Issue Key Attestation
WP->>+W: Provide issued Key Attestation
Caution
When using a Json Web Key Set, Wallet Provider performs NO validations and simply issues a Key Attestation using the provided Json Web Key Set.
To issue a Key Attestation:
- The Wallet generates new Key-Pairs
- The Wallet requests a Key Attestation from the Wallet Provider
- The Wallet Provider issues a Key Attestation
sequenceDiagram
participant W as Wallet
participant WP as Wallet Provider
W->>+W: Generate new Key-Pairs
W->>+WP: Request Key Attestation Issuance
WP->>+WP: Issue Key Attestation
WP->>+W: Provide issued Key Attestation
Wallet Provider uses the Warden Supreme Attestation Library for validating platform Key Attestations. Android Wallets must use the Certification Chain provided by the Android Keystore. iOS Wallets must use the Supreme Attestation Format which is based on Apple's App Attest Service.
An OpenAPI specification of the endpoints provided by Wallet Provider is available here.
Wallet Provider can be deployed using Docker or any other OCI compliant container runtime. You can find the available container images here.
Wallet Provider can be configured using the following environment variables:
Variable: SERVER_PORT
Description: Port the HTTP listener of Wallet Provider will bind to.
Default value: 8080
Variable: SERVER_PREWAIT
Description: Period after which the shutdown process begins.
Default value: 30 seconds
Variable: SERVER_GRACE
Description: Period during which already in-flight requests are allowed to continue before the shutdown process begins.
Default value: 5 seconds
Variable: SERVER_TIMEOUT
Description: Period after which the server forcibly shuts down.
Default value: 5 seconds
Wallet Provider is compatible with a wide range of relational database systems.
It uses Exposed with R2DBC.
R2DBC drivers are included for all major relational database systems.
Migrations are provided for PostgreSQL and MySQL here.
During startup, Wallet Provider checks the configured database and prints any migrations required to update the database schema.
To configure the database, use the following environment variables:
Variable: DATABASE_URL
Description: R2DBC URL used to connect to the database.
Allowed protocols: r2dbc
Available drivers:
h2postgresqlmysqlmariadboraclemssqlpool
Connection pooling can be configured using the r2dbc-pool driver.
Default value: N/A
Example value: r2dbc:pool:postgresql://localhost:5432/wallet-provider
Variable: DATABASE_USERNAME
Description: Username of the database user.
Default value: N/A
Variable: DATABASE_PASSWORD
Description: Password of the database user.
Default value: N/A
To load a signing key and certificate from a Keystore, use the following environment variables:
Variable: SIGNINGKEY_KEYSTOREFILE
Description: Location of the Keystore.
Default value: N/A
Variable: SIGNINGKEY_KEYSTOREPASSWORD
Description: Password of the Keystore.
Default value: N/A
Variable: SIGNINGKEY_KEYSTORETYPE
Description: Type of the Keystore.
Default value: JKS
Variable: SIGNINGKEY_KEYALIAS
Description: Alias of the Key and Certificate Chain to load.
Default value: N/A
Variable: SIGNINGKEY_KEYPASSWORD
Description: Password of the Key to load.
Default value: N/A
Variable: SIGNINGKEY_ALGORITHM
Description: JWS Algorithm used to sign the generated Attestations.
Default value: N/A
Allowed values:
ES256ES384ES512
By default, Wallet Provider performs no validation of platform Key Attestations.
To enable platform Key Attestation validation, use the following environment variables:
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_APPLICATIONS_XX_PACKAGENAME
Description: Android Package of the Wallet.
Default value: N/A
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_APPLICATIONS_XX_SIGNINGCERTIFICATEDIGESTS_XX
Description: Base64 Url-Safe encoded DER encoding of the X509 Certificate used to sign the Wallet application.
Default value: N/A
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_STRONGBOXREQUIRED
Description: Whether StrongBox security leve is required.
Default value: false
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_UNLOCKEDBOOTLOADERALLOWED
Description: Whether devices with unlocked bootloaders are allowed.
Default value: false
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_ROLLBACKRESISTANCEREQUIRED
Description: Whether rollback resistance is required.
Default value: false
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_LEAFCERTIFICATEVALIDITYIGNORED
Description: Whether the validity of the leaf certificate is ignored.
Default value: false
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_VERIFICATIONSKEW
Description: Tolerance added to the verification date.
Default value: 0 seconds
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_HARDWAREATTESTATIONENABLED
Description: Whether hardware platform Key Attestations are accepted.
Default value: true
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_SOFTWAREATTESTATIONENABLED
Description: Whether software platform Key Attestations are accepted.
Default value: false
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_SUPREMEPARSERENABLED
Description: Whether to enable the Android platform Key Attestation parser provided by Warden Supreme.
Default value: false
Validity of platform Key Attestation
By default, Wallet Provider validates the creation time of the platform Key Attestation using a default skew of 5 minutes.
You can modify the skew using:
Variable: PLATFORMKEYATTESTATIONVALIDATION_ANDROID_ATTESTATIONSTATEMENTVALIDITYSKEW
Description: How far in the past, the creation date of a platform Key Attestation can be.
Default value: 5 minutes
Variable: PLATFORMKEYATTESTATIONVALIDATION_IOS_APPLICATIONS_XX_TEAMIDENTIFIER
Description: The Team Identifier of the Wallet.
Default value: N/A
Variable: PLATFORMKEYATTESTATIONVALIDATION_IOS_APPLICATIONS_XX_BUNDLEIDENTIFIER
Description: The Bundle Identifier of the Wallet.
Default value: N/A
Variable: PLATFORMKEYATTESTATIONVALIDATION_IOS_APPLICATIONS_XX_ENVIRONMENT
Description: Environment in which the Wallet is running.
Default value: Production
Allowed values:
ProductionSandbox
By default, Wallet Provider validates the creation time of the platform Key Attestation using a default skew of 5 minutes.
You can modify the skew using:
Variable: PLATFORMKEYATTESTATIONVALIDATION_IOS_ATTESTATIONSTATEMENTVALIDITYSKEW
Description: How far in the past, the creation date of a platform Key Attestation can be.
Default value: 5 minutes
Variable: CHALLENGE_LENGTH
Description: The number of bytes a Challenge is composed of.
Default value: 128
Variable: CHALLENGE_VALIDITY
Description: Duration a Challenge is valid for.
Default value: 5 minutes
Variable: ISSUER_PUBLICURL
Description: Issuer of the Attestations, i.e., the public URL of this Wallet Provider. Must not contain a fragment.
Default value: http://localhost:8080
Variable: ISSUER_NAME
Description: A human-readable name for this Wallet Provider.
Default value: Wallet Provider
Variable: CLIENTID
Description: The Id of the OAuth2.0 Client the Wallet is using.
Default value: wallet-dev
Variable: WALLETINSTANCEATTESTATION_VALIDITY
Description: Duration a Wallet Instance Attestations is valid for.
Default value: 5 minutes
Variable: WALLETINSTANCEATTESTATION_WALLETNAME
Description: Wallet Name that will be included in the Wallet Instance Attestations.
Default value: N/A
Variable: WALLETINSTANCEATTESTATION_WALLETLINK
Description: Optional Wallet Link that can be included in the Wallet Instance Attestations.
Default value: N/A
Variable: WALLETINSTANCEATTESTATION_WALLETVERSION
Description: Wallet Version that will be included in the Wallet Instance Attestations.
Default value: N/A
Variable: WALLETINSTANCEATTESTATION_WALLETSOLUTIONCERTIFICATIONINFORMATION
Description: Wallet Solution Certification Information that will be included in the Wallet Instance Attestations.
Default value: N/A
Variable: WALLETINSTANCEATTESTATION_CLIENTSTATUSVALIDITY
Description: Duration a Client Status of a Wallet Instance Attestation is valid for.
Default value: 90 days
Variable: KEYATTESTATION_VALIDITY
Description: Duration a Key Attestations is valid for.
Default value: 31 days
Minimum value: 31 days
Variable: KEYATTESTATION_CERTIFICATION
Description: URL that links to the certification of the key storage component.
Default value: N/A
Variable: KEYATTESTATION_KEYSTORAGESTATUSVALIDITY
Description: Duration a Key Storage Status is valid for.
Default value: 90 days
Wallet Provider integrates with eudi-srv-statuslist-py, to include Status List Tokens based on Token Status List draft12 in issued Wallet Instance Attestations.
To configure this integration, use the following environment variables:
Variable: TOKENSTATUSLISTSERVICE_SERVICEURL
Description: URL of the take operation of eudi-srv-statuslist-py.
Variable: TOKENSTATUSLISTSERVICE_APIKEY
Description: API Key used to access eudi-srv-statuslist-py.
Variable: TOKENSTATUSLISTSERVICE_COUNTRY
Description: Country in which Status List Tokens will be allocated in.
Default value: FC
Variable: TOKENSTATUSLISTSERVICE_WALLETINSTANCEATTESTATIONSTATUSLIST
Description: Name of the Status List used for allocating Status List Tokens for issued Wallet Instance Attestations.
Default value: oauth-client-attestation+jwt
Variable: TOKENSTATUSLISTSERVICE_KEYATTESTATIONSTATUSLIST
Description: Name of the Status List used for allocating Status List Tokens for issued Key Attestations.
Default value: key-attestation+jwt
Wallet Provider exposes an OpenAPI specification of its endpoints using Swagger UI. You can configure the Swagger UI using the following environment variables:
Variable: SWAGGERUI_PATH
Description: The path at which Swagger UI is exposed.
Default value: /swagger
Duration types support unit strings in the following format (lower case only), with an optional space between the unit value and the unit type.
ns,nano,nanos,nanosecond,nanosecondsus,micro,micros,microsecond,microsecondsms,milli,millis,millisecond,millisecondss,second,secondsm,minute,minutesh,hour,hoursd,day,days
For example, 10s, 3 days, or 12 hours.
Wallet Provider supports RFC9728: Protected Resource Metadata, and provides the following metadata:
resource: The public URL of the Wallet Providerjwks_uri: URL where the signing keys used by Wallet Provider can be retrieved fromresource_signing_alg_values_supported: JWS Algorithms used by Wallet Provider to sign issued Attestations
Wallet Provider includes the following additional metadata:
client_attestation_signing_alg_values_supported: JWS Algorithms supported by Wallet Provider to sign Wallet Instance Attestationsproof_signing_alg_values_supported: JWS Algorithms supported by Wallet Provider to sign Key Attestations
Wallet Provider exposes Protected Resource Metadata at /.well-known/oauth-protected-resource. Per Section 3 of RFC9728: Protected Resource Metadata:
Protected resources supporting metadata MUST make a JSON document containing metadata as specified in Section 2 available at a URL formed by inserting a well-known URI string into the protected resource's resource identifier between the host component and the path and/or query components, if any. By default, the well-known URI string used is /.well-known/oauth-protected-resource. The syntax and semantics of .well-known are defined in RFC8615.
When Wallet Provider is not deployed under the root path, a reverse proxy must be configured appropriately to rewrite the Protected Resource Metadata well-known URL to what Wallet Provider exposes.
For instance:
Public URL of Wallet Provider is: https://example.com/wallet-provider
Protected Resource Metadata URL is https://example.com/.well-known/oauth-protected-resource/wallet-provider
Reverse Proxy rewritten Protected Resource Metadata URL is: https://example.com/wallet-provider/.well-known/oauth-protected-resource
We welcome contributions to this project. To ensure that the process is smooth for everyone involved, follow the guidelines found in CONTRIBUTING.md.
Copyright (c) 2025-2026 European Commission
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.