# Blueprint for the EUDI Wallet Ecosystem in Germany > Architecture, governance, and operational models for the German EUDI Wallet Ecosystem. Version: latest This file contains the complete documentation content for the Blueprint for the EUDI Wallet Ecosystem in Germany. ## Wallet Function: PID Issuance and Presentation The PID is an attestation of person identity data and an electronic identity as defined in eIDAS. It can be used by a user to identify themselves at a Relying Party. This section discusses options to present a PID in a remote transaction (incl. authentication). ## Requirements The following additional requirements apply to the PID solutions: - the PID and its complete lifecycle, including its issuance and presentation processes, shall fulfill the requirements defined for Level of Assurance High - the PIDs in the German Wallet implementation and their use as an electronic identity shall be based on the German eID ## Reference Design Proposals This section lays out different design options for implementing the remote (i.e., online) issuance and presentation using the German eID system. Note: The current document aims at covering the potential solution space based on existing solutions in Germany and the EU as well as international developments in order to provide the basis for a comprehensive analysis and discussion. The objective is to find the best solution based on an assessment from different angles, such as security, privacy, complexity, potential user reach, and user experience. The number of options will be reduced in the course of that process. The PID Provider obtains the EUDIW user's identity data using the German eID system. It then creates a PID credential in either ISO mdoc or SD-JWT VC format. From a high level view, two options exist to transmit a PID credential: The PID Provider either provides the credential directly (Server Retrieval) or indirectly (Device Retrieval) to the Relying Party that requested for the PID as shown in Figure 2. A Relying Party trusts the PID data if it trusts the PID Provider and its issuance and presentation process. ![Depicting data flows and trust relationships.](../figures/figure2.svg) *Figure 2: Architecture overview.* The Server Retrieval options are not pursued for the German EUDI Wallet architecture as this would allow the PID provider to monitor where the user submits their PID and therefore contradict essential privacy requirements. The possible architecture designs for Device Retrieval are further distinguished by the following factors: - **Trust Anchor (Unforgeability)**: Two mechanisms may be used to cryptographically ensure the authenticity and integrity of the PID: - Authenticated Channel - The data is protected with an HMAC and may be encrypted using a symmetric secret specific to a certain transaction with a Relying Party. The secret is determined through key agreement (ECDH) based on an ephemeral key of the Relying Party. The secure channel serves as replay protection and binds the data to a specific transaction. The approach requires the authoritative source to create the secure channel or a party that has a similar security and trust level (e.g., a trusted applet residing in a certified Secure Element). This approach is used by the German eID system. - Signature - The data is protected by a signature created by the PID-Provider. The PID is bound to a certain key managed by the Wallet. This key is used to sign a presentation of the PID to the RP, which serves as cloning protection and binds the presentation to a certain transaction. Since the data is signed, it provides non-repudiation but eliminates proper plausible deniability for the user to an uninvolved party. This approach is used today, e.g., for QES. - **Trust Anchor (User Binding)**: Different mechanisms may be used to securely bind the PID to the user as identity holder: - eID-Card - Secure authentication is based on the German eID-Card - Cloud Support - Secure authentication is based on a trust anchor in the cloud. - SE Smartphone - Secure authentication is based on a SE within the smartphone Note 1: All architecture designs allow for the request and presentation of PID or one or more (Q)EAAs or both in one session by the Relying Party and the Wallet. All architecture designs allow for the following technical standards: - [OpenID for Verifiable Credentials](https://openid.net/sg/openid4vc/) protocol family - OpenID4VCI for Issuance of the PID - OpenID4VP for Presentation of the PID and optionally other (Q)EAAs - PID Credential Formats - IETF [SD-JWT VC](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-sd-jwt-vc) - ISO mdoc (as defined in ISO 18013-5) Additionally, an alternative implementation based on the RestAPI protocol according to ISO/IEC 23220-4 is shown for Option B below. All PID options allow the issuance of either SD-JWT VC or ISO mdoc or even a combination of both. For the sake of brevity, not all PID option flows include both credential format options. Based on these architecture choices, Figure 3 gives an overview of the solution space. ![Overview solution options](../figures/PID_Options_v5.png) *Figure 3: Overview of solution options.* The different solution options are explained in the following and contain a technical description including the cryptographic assets and sequence diagrams. Additionally, each option is linked to a user journey that shows the various flows from a user perspective as lo-fi wireframe screen sequences. All screens of the User Journey are labeled with a specific name. Within the associated sequence diagram, green hexagonal markers labeled "Screen: screen_name" are placed to indicate the corresponding screen in that sequence. The Lo-fi wireframes primarily serve to illustrate the architecture flow from the UX/UI perspective and to show how an implementation could look from the UX/UI perspective. However, it should be kept in mind that the actual realization and implementation of the UX/UI is the responsibility of the wallet providers and the relying parties. ### PID Provider Authenticated Channel **Authenticated Channel with eID-Card (B)** - The authentication of the identity holder for any presentation of the PID is based on the German eID. The PID is created by the PID Provider on demand and presented via the Wallet to the RP within a MAC-authenticated secure channel. - [User Journey: PID Presentation - Authenticated Channel - eID Card](../../../user_journeys/PID-AuthenticatedChannel-eIDcard-presentation.png) - [Technical Description and Sequence Diagrams](../flows/PID-AuthenticatedChannel-eIDcard.md) - Alternative implementation using the RestAPI protocol according to ISO/IEC 23220-4: [Technical Description and Sequence Diagrams](../flows/PID-AuthenticatedChannel-eIDcard-RESTAPI.md) **Authenticated Channel with Cloud Support (B')** - A "seed credential" is derived by the PID-Provider (e.g., using the German eID) and stored in the Wallet signed by the PID Provider for a limited time-period. The PID is created by the PID Provider out of the seed credential on demand and presented via the Wallet to the RP within a MAC-authenticated secure channel. Therefore, the holder authenticates to the PID-Provider based on the security functions of the smartphone and a secure evaluation of the PIN by the PID-Provider in the cloud. - [User Journey: Wallet Activation - Authenticated Channel - Cloud](../../../user_journeys/PID-AuthenticatedChannel-cloud-initialization.png) - [User Journey: PID Issuance - Authenticated Channel - Cloud](../../../user_journeys/PID-AuthenticatedChannel-cloud-issuance.png) - [User Journey: PID Presentation - Authenticated Channel - Cloud](../../../user_journeys/PID-AuthenticatedChannel-cloud-presentation.png) - [Technical Description and Sequence Diagrams](../flows/PID-AuthenticatedChannel-cloud.md) **Authenticated Channel with SE Smartphone (D)** - The PID data is issued by the PID Provider into a (Java Card) Applet of the Wallet Provider in the Secure Element on the user's device (e.g., using the "Online-Ausweisfunktion"). The PID authorizes a Wallet-controlled key to present the PID to RPs through a MAC-authenticated secure channel. Therefore, the holder authenticates to the Secure Element based on the secure evaluation of authentication by the Secure Element of the smartphone. - [User Journey: Wallet Activation - Authenticated Channel - Secure Element](../../../user_journeys/PID-AuthenticatedChannel-secureElement-initialization.png) - [User Journey: PID Issuance - Authenticated Channel - Secure Element](../../../user_journeys/PID-AuthenticatedChannel-secureElement-issuance.png) - [User Journey: PID Presentation - Authenticated Channel - Secure Element](../../../user_journeys/PID-AuthenticatedChannel-secureElement-presentation.png) - [Technical Description and Sequence Diagrams](../flows/PID-AuthenticatedChannel-secureElement.md) ### PID Provider Signed Credential Options for PID Provider signed credentials leverage the concept of a Wallet Secure Cryptographic Device (WSCD). This is an abstraction that can be implemented in many ways, including secure elements residing in a mobile device (SE), external tokens (such as eID cards or FIDO authenticators), an applet on a eUICC, remote services (based on a remote HSM), and combinations of those options. **Signed Credential with eID-Card (C'')** - The authentication of the identity holder for any presentation of the PID is based on the "Online-Ausweisfunktion". The PID is created by the PID Provider on demand as a PID Provider signed credential and presented via the Wallet to the RP. - User Journey: PID Presentation - TBD - [Technical Description and Sequence Diagrams](../flows/PID-IssuerSigned-eIDcard.md) **Signed Credential with Cloud Support (C')** - A credential is derived by the PID-Provider (e.g. using the "Online-Ausweisfunktion") and stored in the Wallet as a credential signed by the PID Provider. The cloud/remote HSM acts as a WSCD that controls the keys used for presentation of the PID. The Wallet presents the Issuer-Signed PID credential to the RP and the key binding is performed by the cloud HSM. Therefore, the user authenticates to the cloud-based key store based on the security functions of the smartphone and a secure evaluation of the PIN by the cloud based key store. - [User Journey: Wallet Activation - Issuer Signed - Cloud](../../../user_journeys/PID-IssuerSigned-cloud-initialization.png) - [User Journey: PID Issuance - Issuer Signed - Cloud](../../../user_journeys/PID-IssuerSigned-cloud-issuance.png) - [User Journey: PID Presentation - Issuer Signed - Cloud](../../../user_journeys/PID-IssuerSigned-cloud-presentation.png) - [Technical Description and Sequence Diagrams](../../features/PID/runtime-views.md) **Signed Credential with SE Smartphone (C)** - A credential is derived by the PID-Provider (e.g., using the "Online-Ausweisfunktion") and stored in the Wallet as a credential signed by the PID Provider. The Secure Element acts as a WSCD that controls the keys used for presentation of the PID. The Wallet presents the Issuer-Signed PID credential to the RP and the key binding is performed by the Secure Element. Therefore, the user authenticates to the secure key store of the smartphone based on the secure evaluation of authentication by security functions of the smartphone. - [User Journey: PID Issuance - Issuer Signed](../../../user_journeys/PID-IssuerSigned-issuance.png) - [User Journey: PID Presentation - Issuer Signed](../../../user_journeys/PID-IssuerSigned-presentation.png) - [General Technical Description of Signature-based Credentials](../flows/PID-IssuerSigned.md) (within the general description, the WSCD is realized with a SE in the smartphone and user authentication is realized with a PIN evaluated in the SE in the smartphone) ## Preliminary Assessment and Comparison of PID Design Options The architectural options presented do not claim to represent a perfect solution for all problems in the environment of an EUDI wallet. All options have their own advantages and disadvantages in security, privacy and usability and scalability. Some options are more suitable for simple (Q)EAAs than others, but in principle there are additional legal requirements for the use and consideration of the PID that make a different or more complex solution necessary for the identification/authentication on LoA high. In the current (early) phase of the project, the options are therefore to present a basis for discussion and further analysis, including the development of new alternatives. A complete assessment (based on BSI-TR 03107) of the solutions regarding the level of assurance, will be possible when the design/architecture is finalized. For now, several assumptions are made e.g. regarding a proper implementation and a certification of the used hardware etc. Authenticated Channel Signed Credential eID-Card Cloud Support SE Smartphone Cloud Support SE Smartphone B B' D C' C Privacy Considerations Unobservability The PID provider is involved in the presentation and can learn the time and frequency of the presentation as well as the attriputes presented. The Wallet provider is not involved in the presentation. The PID provider is involved in the presentation and can learn the timing and frequency of presentations. The Wallet provider is not involved in the presentation. PID provider and Wallet provider are not involved in the presentation. PID provider and Wallet provider are not involved in the presentation. The cloud key store provider cannot assert whether the usage of a key belongs to a PID presentation. PID provider and Wallet provider are not involved in the presentation. Unlinkability RP: An RP cannot assign two presentations to the same user (ephemeral keys). RP+RP: see RP. PP+RP: Could assign issuance and presentation transactions to the same user if PP logs PID presentation keys. RP: An RP cannot assign two presentations to the same user (ephemeral keys). RP+RP: see RP. PP+RP: Could assign issuance and presentation transactions to the same user if PP logs PID presentation keys. RP: An RP cannot assign two presentations to the same user (ephemeral keys). RP+RP: see RP. PP+RP: Could assign issuance and presentation transactions to the same user if PP logs PID presentation keys (could be prevented if group keys are set for multiple users). RP: An RP cannot assign two presentations to the same user (ephemeral keys). RP+RP: see RP. PP+RP: Could assign issuance and presentation transactions to the same user if PP logs PID presentation keys. RP: An RP cannot assign two presentations to the same user (ephemeral keys). RP+RP: see RP. PP+RP: Could assign issuance and presentation transactions to the same user if PP logs PID presentation keys. Selective Disclosure Achieved through logic in SE of eID-Card. Realized with salted hashes. Achieved through logic in SE of smartphone. Realized with salted hashes. Realized with salted hashes. Repudiation The authenticity of the PID cannot be proven to third parties. PID is not signed. Ephemeral keys are used for authenticated channel. The authenticity of the PID cannot be proven to third parties. PID is not signed. Ephemeral keys are used for authenticated channel. The authenticity of the PID cannot be proven to third parties. PID is not signed. Ephemeral keys are used for authenticated channel. The authenticity of the PID can be proven to third parties. PID is signed. The authenticity of the PID can be proven to third parties. PID is signed. Security Considerations LoA By leveraging the security functionality of the eID-Card and PID provider, PID retrieval could be sufficient for LoA high. TBD By having most security functionality within secure hardware, this option may be able to achieve LoA high, depending on the degree to which the secure hardware can be protected. TBD By having most security functionality within secure hardware, this option may be able to achieve LoA high, depending on the degree to which the secure hardware can be protected. Unforgeability PP authenticated channel (ECDH+HMAC) PP authenticated channel (ECDH+HMAC) PP authenticated channel (ECDH+HMAC) PP signed credential PP signed credential Freshness Dynamic authentication via challenge Response (OpenID4VC) Dynamic authentication via challenge Response (OpenID4VC) Dynamic authentication via challenge Response (OpenID4VC) Dynamic authentication via challenge Response (OpenID4VC) Dynamic authentication via challenge Response (OpenID4VC) User Binding 2FA of eID-Card via knowledge (PIN, validated in SE of eID-Card) and possession (key, SE of eID-Card) 2FA via knowledge (PIN, secure cloud validation) and possession (smartphone-bound key, TEE/TRH/SE) 2FA via knowledge (PIN, validated in SE of smartphone) and possession (smartphone-bound key, SE) 2FA via knowledge (PIN, secure cloud validation) and possession (smartphone-bound key, TEE/TRH/SE) 2FA via knowledge (PIN, validated in SE of smartphone) and possession (smartphone-bound key, SE) Usability Considerations External token required for presentation by the user eID-Card required no no no no Combined presentation of PID and (Q)EAA yes yes yes yes yes Scalability Considerations Minimum Device Requirements Any NFC equipped device. Platform mechanisms (e.g., Android Key Attestation, iOS App Attestation) for wallet attestations. Any NFC equipped device. Platform mechanisms (e.g., Android Key Attestation, iOS App Attestation) for wallet attestations. Any NFC equipped device with programmable secure element or eUICC resistant to attack potential high. Platform mechanisms (e.g., Android Key Attestation, iOS App Attestation) for wallet attestations. Any NFC equipped device. Platform mechanisms (e.g., Android Key Attestation, iOS App Attestation) for wallet attestations. Any NFC equipped device with programmable secure element or eUICC or OEM key store resistant to attack potential high. Platform mechanisms (e.g., Android Key Attestation, iOS App Attestation) for wallet attestations. Interoperability Wallet & RP The proposed design requires additional algorithms for key agreement and message protection in the ARF (Authenticated Channel). The proposed design requires additional algorithms for key agreement and message protection in the ARF (Authenticated Channel). The proposed design requires additional algorithms for key agreement and message protection in the ARF (Authenticated Channel). This option is lined up with the current ARF. This option is lined up with the current ARF. Offline support No (eID-Service required) No (cloud support required) Yes No (cloud support required) Yes Cloud service with high availability required for presentation eID-Service for eID-Card & PID-Provider for ad hoc issuance PID-Provider for ad hoc issuance No Cloud key store No ## Considerations on Performance, Availability, etc. of the individual components Depending on the chosen architecture, there are a wide variety of components that all have different requirements of availability or performance and for which scalability must be considered. The following list is intended to provide a brief overview of the relevant components but is not exhaustive. - PID Provider (including eID-Server, HSM) - Wallet instance - Wallet Secure Cryptographic Device (remote or on the device) - Wallet Backend (including HSM) Backend components might be required, which has a significant influence on the various aspects covered in this section. ### Availability It can be assumed that the wallet can be in different stages of use, which have different requirements for the components: - During issuance of Credentials, PID provider and the WSCD must be available. When the WSCD is not part of the Smartphone of the holder/user, the remote WSCD service must be available too. - During presentation of Credentials, the WSCD and, only in some cases, the PID provider are required. Therefore, the estimation of the scalability of the PID provider depends directly on the choice of the actual infrastructure and architecture of a wallet solution: required availability might be temporary or recurring. The wallet provider (and its key management hardware) must be available during the onboarding of a wallet. Depending on the choice of revocation mechanism, later retrievals can be possible or necessary, which would also have an impact on the availability requirements of this component. ### Scalability For the scalability of the PID provider's eID service, the existing eID systems can be used. Reading the data would not be a problem, assuming the eID service has sufficient resources available. Options that use Secure Element on the Smartphone (D+C) Option with on demand PID issuance (B+C'') Options with Could Support (B'+C') Performance Generally speaking, background communication is only needed for the provisioning and personalization of the PID, therefore short down times for maintenance and similar events will only affect relatively few users. The PID Provider is contacted during presentation and must therefore be available at all times and be able to withstand unforseeable load peaks. The wallet backend is accessed during every presentation and must therefore be available at all times and be able to withstand unforeseeable load peaks. Scalability A lot of unknowns when it comes to provisioning and personalization scalability. Backend communication through one or more PID providers would be scalable. Need to consider how to scale HSM communications. ## Hardware security considerations The options that use a PID provider authenticated channel use signature keys to authenticate the ephemeral keys for the authenticated channel. Option B and B' use a signature key for the authenticity of the ephemeral keys and thus also for the authenticity of the PIDs issued ad hoc. The signature key for B and B' is located, for example, in an HSM in the environment of the PID provider. If the signature key were compromised, an attacker could theoretically authenticate any PIDs. The signature key would have to be revoked. However, no PIDs would have to be revoked, as no permanently valid PIDs are issued. Option D presumably uses a group key such as the eID card that is stored in the applet in the SE of the smartphone in the user's environment. If the group key is compromised, an attacker could theoretically authenticate any PIDs. The group key would have to be revoked. All PIDs that use the same group key would no longer work. However, it is not known which issued PIDs are affected, resulting in a complex revocation scenario. The options that use signed credentials use a signature key for signing that is located for all options, e.g. in an HSM in the PID provider's environment. If the signature key is compromised, an attacker could theoretically authenticate any PIDs. The PIDs already issued would have to be revoked. The impact could be reduced if the diversity of the signature keys were increased, e.g., for short-lived and long-lived signed credentials. As there is currently no publicly available information on the breach of keys in Common Criteria certified SEs or HSMs, it can be assumed that the probability of these devices being compromised is very low. In any case, a proper certification of the secure hardware is mandatory to ensure it is tamper and duplication proof against a high attack potential. Adhering to using only certified Secure Elements from trustworthy (European) hardware manufacturers reduces the risk of compromise even further. Usage of remote/cloud HSMs would further require the security environment to be certified according to ISO 27001. The SE chip/HSM production can only be verified through third party certification, as such the security may be considered less reliable than for the smart card. Whether this "risk" can be accepted for LoA “high” has not been thoroughly evaluated yet. Furthermore, the data authenticity during transmission from the eID card to the PID Provider during issuance is done via the German eID for all options. We are confident that using the German eID (notified for LoA “high”) raises only acceptable risks for all use-cases. Consistent testing, certification and mandatory supervision of the chip production under the Federal Ministry of the Interior ensure a very high level of reliability and trust in the German eID. In fact, there has not been any meaningful security incident to the eID card since its introduction in 2010. ## Batch Credential Issuance When the same Issuer-signed credential (as in PID option C) is reused for the same Relying Party or across multiple Relying Parties, it becomes possible to link these transactions and track users across different use cases. This is due to the properties of mdoc and SD-JWT credential formats using: - unique hashes for the disclosures - unique public keys for key-binding - unique PID Provider signatures - unique reference for the status To achieve the unlinkability requirements (as described in [Unlinkability](../../ecosystem-concepts/crosscutting-concepts/privacy-requirements.md#unlinkability)), the Provider issues a batch of credential instances that all contain the same credential dataset but with different cryptographic material. This functionality is enabled by using the Credential Endpoint of the OpenID4VCI protocol. It requires the Wallet to send a number of different keys used for cryptographic binding in the Credential Request and requires the Provider to choose individual salts for the Disclosures (therefore resulting in individual signatures as well) in the Credential Response. If the Wallet utilizes the batch-issued credentials as one-time use, unlinkability for the same Relying Party and colluding Relying Parties can be achieved. If all issued credentials have been used, the Wallet should request new credential instances from the Provider, preferably using Refresh Tokens to avoid a repeated user authentication. The optimal batch size depends on several factors: - the frequency with which the user needs to present a unique credential over time, - the user experience during the issuance process when a bigger batch size is chosen, - the wallet's capacity to manage a larger number of credentials, which may be influenced by factors such as hardware-based key storage, - the available resources that the provider has for issuing credentials in larger quantities at a specific time. - the used revocation mechanism The Provider is able to define a limit for the maximum number of batch size to issue, but it is up to the wallet to choose the actual size of the batch. The Wallet could take into account information of the individual user's credential usage in the past. The Provider needs to pay attention to further data in the batch-issued credentials that could lead to linkability. It must be prevented that data exists, that is unique to batch issued credentials that belong together. Data that is shared across all or a large quantity of batches can in general be kept as is. The following recommendations are made: - *Issuance, validity and expiration dates* If using timestamps with high precision the timestamps can be unique to the batch or at least unique within a small group of batches. To prevent that, the issuer should choose a lower precision, for example the start or end of the day. The exact precision to use needs to be determined by the amount of credentials issued per time period. - *Status information* Depending on the mechanism used, the credential may contain an identifier or index, that links to the status information in a status list or identifier list. Each unique identifier or index must be unique, if it cannot be omitted. Indices and identifiers must be distributed randomly to prevent linkability by these. - *Cryptographic material* Each credential must contain unique values for all cryptographic material, this includes cryptographic keys (especially the holder binding), signatures, nonces, salts and random values. Nonces and salts must be distributed randomly. - *Unique identifiers* Depending on the format other fields may be used that could act as unique identifier for the batch if not chosen randomly. This can for example be the jti claim in an SD-JWT VC and the digest IDs in an ISO mdoc. Such values must only be equal for different credentials in a batch in negligible cases. - *Changes to the issuer system* When changes are done to the issuer system, care must be taken to prevent the creation of a small subset of credentials, that share a common property. An example is that an update is introduced, that changes the size of a nonce value from 8 to 12 bytes. Immediately after the release, it is discovered, that in fact 16 bytes are needed and a new update is rolled out within ten minutes. All credentials that fall in this ten minutes frame share the 12 bytes nonce length and thus form a small subgroup. Those credentials are less protected by herd privacy than the other credentials. To identify such subgroups all information in the credential must be considered: it is not enough to prevent subgroups for each information individually but the combination of things like nonce length and rounded timestamps needs consideration. Besides these efforts, users may be (intentionally) linked by the data that they disclose to the Relying Parties. Most German citizen are trackable by the combination of first name, last name and birth data and for certain use cases that require to identify the user, linkability is intentional. However, the underlying technology should aim to enable unlinkability, thus batch-issued credentials are recommended. ## Revocation Revocation of credentials is a process in which the issuer of PID or (Q)EAA declares that the credential is no longer valid. Various use cases and scenarios may require revocation: - the PID/(Q)EAA Provider wants to revoke its issued credential because the contained data is no longer valid - the Wallet Provider wants to revoke a Wallet Instance because Wallet Security Cryptographic Device (WSCD) or the Wallet Instance application is compromised or vulnerable - the user wants to revoke their Wallet Instance because they lost their smartphone - the user wants to revoke their PID - the PID Provider wants to revoke a PID because the person has died Regarding the various PID options, only the issuer-signed variations like C or C' require revocation as the Authenticated Channel variations generate fresh credentials for every transaction. To enable revocation within the EUDI Wallet ecosystem, the following mechanisms for revocation are considered: - Certificate Revocation Lists - Status Lists - Online Certificate Status Protocol (OCSP) - OCSP stapling ### Certificate Revocation Lists Certificate Revocation Lists (CRL) as defined in [RFC5280](https://datatracker.ietf.org/doc/rfc5280/) are an established revocation mechanism for X509 certificate that has been proven in productive environments for a long time. The Issuer maintains a publicly available list that contains the serial numbers of revoked certificates. Relying Parties may discover this list (e.g. as the URL is contained in the certificate) and validate whether the serial number exists in the list. As the issuer of a certificate always delivers the complete list, he will not learn which serial number the Relying Party is interested in, thus guaranteeing the unobservability. As CRLs are currently only used for X509 certificates, it remains open to define how this mechanism is used for the PID credential formats. Additionally, CRLs have seen some scalability limitations in the Browser TLS context, and it remains open to evaluate if CRL sizes remain manageable within the eIDAS ecosystem. Usage of CRL Delta updates may be considered to increase the scalability. ### Status List [IETF Token Status List](https://datatracker.ietf.org/doc/draft-ietf-oauth-status-list/) is a new mechanism with similar properties to CRLs, which defines a status mechanism for JOSE and COSE secured Referenced Tokens. This status links to a Status List in JSON and CBOR formats that describe the individual statuses of multiple Referenced Tokens. The statuses of all Referenced Tokens are conveyed via a bit array in the Status List. Each Referenced Token is allocated an index during issuance that represents its position within this bit array. The value of the bit(s) at this index correspond to the Referenced Token's status. The Status List is provided by the issuer through a public endpoint or as a signed Status List Token in JWT or CWT. As the issuer of a status list always delivers the complete list, he will not learn which index the Relying Party is interested in, thus guaranteeing the unobservability. Status List have shown to have better scalability properties than CRLs under most circumstances, but it remains open to evaluate if this is sufficient for the eIDAS ecosystem. Status Lists have not been widely adopted and proven in productive ecosystems yet. The Status List requires additional communication between the issuance and revocation service during the issuance. ### Online Certificate Status Protocol (OCSP) In the Online Certificate Status Protocol the issuer provides a service(called OSCP Responder), which the Relying Party may use to query the revocation status of a certificate in real time. As the Relying Party provides the specific certificate serial number to the issuer, unobservability can not be achieved. As OCSP is currently only used for X509 certificates, it remains open to define how this mechanism is used for the PID credential formats. Furthermore, the system has shown to have bad scalability properties. Therefore, usage of OSCP is *not* recommended. ### OCSP stapling In the OCSP stapling the TLS certificate owner regularly queries the issuer's OCSP endpoint and "staples" the result to the response of the TLS handshake, thus the other party does not need to fetch it themselves, reducing the traffic and cost for the OCSP Responder. OCSP stapling was introduced to tackle the scalability issues of OCSP but only with modest success. OCSP stapling is currently only defined for X509 certificates, but a [proposal applying the concepts to the PID credential formats is under development](https://datatracker.ietf.org/doc/draft-demarco-oauth-status-attestations/). The concept has the privacy potential as the Relying Party does not fetch the revocation information itself, but it remains open whether sufficient scalability can be achieved. ### Wallet revocation and WIA/WTE security assurances Beside the revocation of attestations, there are reasons that necessitate to revoke the wallet itself. For example, if the backend wants to revoke the wallet, due to a security breach or similar, it needs to differentiate between the wallet solution, the wallet instance and the wallet unit. For that, indications, or "attestations" are needed to guarantee towards another entitywhether a wallet instance/unit/solution is still valid or has been revoked, as the issuer or RP has no other means to detect this. Adopted implementing acts on Articles 5a and 5c define a "wallet unit attestation" (WUA), which refers to both the wallet instance and secure hardware (WSCD/WSCA). Corresponding to those definitions, the ARF version 1.4. specifies a "wallet instance attestation" (WIA) as well as a "wallet trust evidence" (WTE). After a first assessment, we see an advantage of keeping two separate attestations instead of just one, since it allows to also have different lifetimes and revocation mechanisms. We believe the WIA/WTE approach is compatible with the WUA. As such, we propose a wallet revocation using both WIA and WTE. We will revisit this proposal in the future, after discussions on the WUA have been finalized in the Implementing Acts. The following security assurance for issuers and RPs shall be attested by the corresponding attestations: WIA assures: - Trustworthiness of the wallet solution overall - Trustworthiness of the wallet instance - Trustworthiness of the device and OS - Wallet has not been revoked by the user WTE assures: - Trustworthiness of the WSCA/WSCD managing defined cryptographic keys and their security properties - Trustworthiness of the user authentication mechanism used to authenticate to the WSCA/WSCD Content and lifetime of the attestations may differ, depending on the chosen architecture. E.g., an architecture with a WSCD/WSCA based on a secure element in the device may not want to issue short-lived WIAs for each presentation, as it requires a callback to the backend each time. According to implementing act on 5a (23) PID and EAA of the revised regulation (EU) 910/2014, in Art. 5 (4b), the issuer revokes the issued PID, if the WUA (here WTE) to the corresponding wallet unit they have issued the PID to, gets revoked (revocation chaining). The RP can be assured of the WTE guarantees through verifying the validity of the PID, as otherwise, if the WTE has been revoked, the PID would have been revoked as well. To fulfill this requirement, different approaches for revocation are possible, differing e.g., in the attestations' lifetime and recipients. In the following, they are outlined for where the WUA is comprised of a WIA and WTE, attesting the components as described at the beginning of this section *(Note: the ARF discussions for the WUA are not yet finalized and are subject to change)*: - **1** Long-lived WIA and WTE: Both Wallet Attestations are long-lived, meaning that they need to be revoked actively by the Wallet Provider, upon compromise, request of the user or similar. Furthermore, both attestations are only send to the PID and Attestation Providers during issuance, but not to the RPs during presentation. In order for the RP to verify the validity of the Wallet Unit, the PID and Attestation Providers must perform "revocation chaining": meaning, they revoke their issued PID or attestations upon revocation of either the WIA or WTE by the Wallet Provider, for which the PID and Attestation Provider must frequently check their validity. During presentation, a RP "only" verifies the validity of the presented PID/attestation and can be assured of the Wallet Units' (Instance and WSCA/WSCD) validity through this. That is, as the presented attestation would be revoked if either the WIA or WTE was revoked as well. This shifts the "liability" of verifying the validity of the Wallet from the RP to the PID and Attestation Providers. - **2a** Short-lived WIA and long-lived WTE: The WIA is short-lived (lifetime < 24 hours) and requires no revocation. Revoking the WIA is equal to not issue them any further by the Wallet Provider. It can be issued either ad-hoc or in batch once a day. The WIA is communicated to both the PID and Attestation Providers and the RPs, upon their explicit request. A RP requesting a WIA must then verify both the presented PID/attestation(s) and the WIA. The WTE is long-lived and requires revocation by the Wallet Provider. Furthermore, the WTE is only communicated to the PID and Attestation Providers, but not the RPs. In order for the RP to verify the validity of the WSCA/WSCD managing the cryptographic keys belonging to a presented PID/attestation, as well as the authentication towards it, the PID/Attestation Providers perform revocation chaining for their issued attestations depending on the validity of the WTE only. That is, if the secure hardware is compromised, the WTE gets revoked by the Wallet Provider/RWSCD and subsequently the PID/attestations, that were issued into the WSCD attested by this WTE, get revoked by the PID/Attestation Provider. - **2b** Short-lived WIA and WTE: Both Wallet Attestations are short-lived (lifetime < 24 hours), meaning that they don't require revocation by the Wallet Provider. Revoking the WIA and WTE is equal to not issue them any further by the Wallet Provider. They can be issued either ad-hoc or in batch once a day. The WIA is communicated to both the Attestation Provider and the RPs, upon their explicit request. A RP requesting a WIA mut then verify both the presented PID/attestation(s) and the WIA. The WTE is only communicated to the PID/Attestation Provider during issuance. The PID/Attestation Providers verify the validity of the WSCA/WSCD, only at the moment of issuance, when verifying the validity of the WTE. Afterwards, they do not have no further obligation to link their issued PID's/attestations' validity to the validity of the WTE. During presentation, a RP verifies the presented PID/attestations validity as well as the WIA, if they requested it. However, due to the short lifetime of the WTE and no revocation chaining performed by the PID/Attestation Providers, the RP cannot verify the validity of the WTE through the presented PID's/attestations' validity. Instead, the RP "trusts" the Wallet Backend to that the WTE assurances are fulfilled through the WIA. This can be done by, e.g., only issuing a WIA (either ad-hoc or in batch) upon verifying if the WTE, attesting the WSCA/WSCD, is still valid. If not, no WIA (batch) will be issued. - **3** Short-lived WIA and WTE: Similar to option 2b, both Wallet Attestations are short-lived and managed by the Wallet Provider. However, both WIA and WTE are send to both the PID/Attestation Providers and the RPs, if they request it. A party receiving the two Wallet Attestations verify both their validity directly. PID/Attestation Providers thus also do not perform any revocation chaining. *Note: the WTE presented to the RP may not contain all the information as the WTE presented to the PID/Attestation Providers, as the latter may contain information about the secure hardware needed for issuance but not presentation* For options 2a, 2b and 3, Wallet Attestations that are short-lived may also be implemented as long-lived with revocation. In that case however, batch issuance is required for them as to not introduce linkability across Issuers or RPs. Furthermore, for option 2a, usage of short-lived WTEs for Attestation Providers other than the PID Provider may be used (*Issuer Trust Evidence - ITE*). For those options with revocation chaining (1, 2a), it must be noted that the general requirement, which introduces the aforementioned "liability shift" to the Issuers, can only be applied to the PID. That is, as the PID Provider and (state-managed) Wallet Provider both fall under MS liability, while, after a first assessment, the German law does not allow to push/force such a requirement onto QTSPs. However, if a QTSP decides to adopt such a revocation chaining policy for their issued attestations, e.g., due to internal service requirements, they may do so. As such, option 1 may not be possible in Germany. In order to decide which option for revocation and lifecycle to use, factors such as security, privacy, scalability, interoperability, costs, and ux should be considered. In the following, we have made a first analysis on these points (*issuer specific (service) requirements and policies, e.g., QTSPs deciding to perform revocation chaining, are out of scope of this analysis*): - **Option 1:** For this option, Issuers and RPs receive all assurances or can always verify them indirectly through the presented PID/attestation(s) (Security). Due to the long-livedness of the Wallet Attestations, the Wallet Provider has to manage and maintain the revocation and their entries (Scalability). PID and Attestation Providers need to monitor the validity of the WIA and WUA and revoke their issued PID/attestations accordingly (Scalability, Cost). Due to this, issuers may also learn when a Wallet has been revoked (Privacy). The more Providers are in the ecosystem, the higher the complexity and workload gets, and the more dependency on the active participation of the issuer, for the whole lifetime of their issued credentials, exist (Scalability). Furthermore, the eIDAS regulation has no mandate to require QTSPs to perform revocation chaining for their issued attestations, and at least in Germany this is most likely not possible (Interoperability). The revocation of the WIA or WTE would also trigger the revocation of the PID and all other attestations issued into the Users' wallets, which may not be necessary in every case (Usability). - **Option 2a:** While Issuers receive all assurances through the WIA and WTE, RPs must request the WIA if they need them as well (Security). Due to the short-livedness of the WIA, the Wallet Provider may get metadata about the WI through the WIA, and, if the WIA is issued ad-hoc, the Wallet Provider may infer when a Wallet is performing an issuance or presentation (Privacy), which also means regular WIA-issuance by the WP and fetching by the Wallet (Scalability, Cost). While not as bad as for option 1, the PID Provider must, and Attestation Providers may/should, monitor the WTE and revoke their issued PIDs or attestations accordingly (Scalability). The reliance on short-lived WIAs also impacts the offline-capability of the Wallet, as they need to fetch the WIA ad-hoc or in batch once a day at the Wallet Provider (Interoperability, UX). - **Option 2b:** Similarly to option 2a, the RP must request the WIA in order to be assured of the wallet's validity, while the issuers receive and verify this through the WIA and WTE during issuance (Security). Also similar to 2a, the Wallet Provider may get metadata about the WI or, in case of ad-hoc issued WIAs, infer when the wallet issues or presents something (Privacy). The workload is shifted from the Issuers to the Wallet Provider, as they former don't need to monitor the WIA and WTE, while the latter now has to regularly issue new WIAs and WTEs (Scalability, Cost). Furthermore, RPs now have to request and verify both the WIA and WTE, if they require it (Scalability). In the case of multiple WSCDs being used, this option does not allow to discern them effectively and may lead to revoking the whole WI, if "just" one WSCD has been revoked (Interoperability, UX). Due to regular fetching of both the WIA and WTE at the Wallet Provider, this option is also not offline-capable (UX). - **Option 3:** Assurances are verified through the WIA and WTE for the issuers, and for RPs if they request them (Security). As before, the Wallet Provider may get metadata about the wallet through the WIA or WTE, and, if they are issued ad-hoc, may also infer when a Wallet is issuing or presenting something (Privacy). The WTE may also not contain the same information when presented to a RP compared to when presented to an issuer, as to not provide any information about the WSCD that is not needed for the RP besides its validity information (Privacy). Similarly, regular issuance of WIAs and WTEs by the WP, and fetching by the wallet, is needed (Scalability, Cost). Furthermore, RPs have to request and verify both WIA and WTE if needed (Scalability). Please note that for interoperability, and due to the volatile nature of the ARF, the ARF conformance may not be given for every option listed here. A review of the options, and their applicability and compliance, after ARF finalization, or at least on the parts about WUA and wallet revocation, must be performed. *tbc* The above options, especially those with revocation chaining (1, 2a), consider only the PID and QEAAs. For example, issuers of non-key-bound attestation such as EAAs do not require the revocation chaining, even just for the WTE, as they have lower requirements and do not possess keys generated and stored in a WSCD attested by the WTE. Sector specific requirements may also apply, but are out of scope for this analysis here. Furthermore, a future review of the options may consider (multiple) local WSCDs more in-depth, as to not require regular, and non-offline compatible, fetching of the short-lived WIAs or WTEs. It must also be discussed how to attest WTEs issued by the wallet itself for the local (or native) WSCD. A first assessment for **option C'** proposes the usage of option 2a: short-lived ephemeral WIAs which are ad-hoc issued on-demand, and unique per RP (if they request the WIA, otherwise none is sent) to ensure unlinkability. Furthermore, the WTE is long-lived and only sent to the issuers. The revocation chaining may also be performed by issuers of key-bound attestations other than the PID, but are not required to by the regulation (only the PID is). The fact that option 2a may pose problems for the offline-availability is no issue for the architecture option C', as it requires regular communication to the Wallet Provider anyway. This proposal shall be revisited at a later time again. ### Revocation use cases As per Art. 5a (9) of the revised regulation (EU) 910/2014, the wallet shall be revoked in the following cases: - upon the explizit request of the user - where the security of the EUDIW has been compromised - upon the death of the user (or cease of activity of the legal person) Note that the regulation requirement for revocation chaining of the PID depending on the WUA is changed here to dependency on the WTE. The reason is, that, e.g., the wallet instance, attested by the WIA, may be compromised, but would not require the revocation of the PID. The corresponding batch keys for the PID lie within the WSCD, the secure hardware attested by the WTE, and remain unaffected by the compromise of the wallet instance. Furthermore, the WIA does not have a revocation in this proposal, as they are short-lived. As such, the revocation chaining for the PID would only make sense for dependency on the WTE. Revocation for (key-bound) attestation other than the PID may very well be regulated by issuer policies or sector-specific rulebooks, and are (mostly) outside of the scope of this approach. Upon the death of the user, it is currently not defined how either the PID Provider or the Wallet Provider is informed of this matter. As such, the revocation for this scenario remains to be defined. Other use cases, as well as necessary interfaces for revocation (such as, e.g., a "Wallet Provider Interface" towards the user) will be described at a later date. ### Batch issuance When using batch issuance to achieve verifier unlinkability, it is important for privacy reasons that the status management is using unique identifiers for each credential in the batch: - status list: each credential needs a unique index in the status list. The indices must be distributed randomly. - CRL: each credential needs a unique serial number. This serial number must be distributed randomly. When updating the status list and the CRL object that are publicly available,the issuer should group the revocation of multiple batches into one update to avoid linkability of the individual credentials. ### Credential Format mapping For the PID and (Q)EAA credentials, the following mapping to the revocation mechanisms is proposed: - SD-JWT VC: Token Status List - mdoc: CRL ### Online-Offline Scenarios When the Relying Party is online, it will fetch the CRL and the Status List from the issuer's endpoint (or from a status provider). When the Relying Party is offline, it will use a cached version of the CRL or the Status List with the risk of being outdated. A mechanism to pass the CRL or the Status List to the Relying Party via the OID4VP response with a trust chain and where the Relying Party only needs the root of trust is not defined yet to support fully offline scenarios. ## Cross-Device PID Presentation The PID Design Options presented in this document cover the transmission of the PID on the same device only, meaning the RP and the Wallet shall reside on the same device. PID scenarios across devices are not directly supported as they cannot be secured to a Level of Assurance High. Applications wishing to support cross-device presentations may implement a session-transfer based solution instead: The application needs to transfer the user's session to the device where the Wallet is installed (e.g., by displaying a QR code that is then scanned on the second device), conduct a same-device PID presentation, and transfer the result back via the application's session backend. Since there is usually no authenticated channel for cross-device session transfer, fundamental security issues may arise, for example, when QR codes are replayed in phishing attacks. The exact implementation of cross-device session transfer flows, the security considerations, and appropriate mitigations are out of scope of this document. ## Repudiation Data deniability in identification scenarios can be technically achieved through several conceivable approaches and cryptographic primitives. A prominent example is the German eID solution, where an ephemeral but authenticated end-to-end channel between eID card and Relying Party is established, which is then used to transmit the PID in an unauthenticated way. The Relying Party is able to gain certainty about the card user's PID through the authenticity of the channel, but is not able to prove that to a third party after the channel has been closed. Thus, the user is able to plausibly deny the authenticity of his PID to some third party. Note: Technically, a Relying Party trusts the PID issuer and thus any eID card with attested key material on its chip, which is used to compute a DH shared secret for the establishment of an E2E channel. Therefore, it can also consider the transmitted PID to be correct and authentic, but does not keep a proof for this. For establishing user deniability, PID may be protected by a MAC which was generated with a symmetric secret key. In this case, PID authenticity can only be verified by entities who share the secret key---usually just the two entities involved in an identification. A third party not in possession of this key cannot distinguish the MAC from randomness, giving the user deniability about their presentation of the PID credential. The use of digital signatures (for both, identification or PID) ensures PID integrity and authenticity, but generally obstructs any kind of deniability due to their “non-repudiation” property. A PID fragment of an identification transaction that has been equipped with a digital signature can be regarded as an officially certified copy, which allows to be cryptographically verifiable verified by everyone in possession of the respective issuer’s public key. This holds for an indefinite amount of time after the identification process. A quite unconventional approach would be to regularly publish the respective signature keys (including appropriate key management), but is at most conceivable for short-lived credentials. ## PID Provider Implementation Considerations PID Providers may be part of the Wallet solution or there can be a central PID Provider (then also called PID Issuer) used by all German EUDI Wallets to obtain PIDs. If the PID Provider is part of the Wallet solution, the way PID Provider and Wallet establish trust and communicate with each other is at the discretion of the Wallet Provider. If there is a PID Issuer, the communication protocol used for PID issuance and the way trust is established needs to be standardized. The PID Provider is a backend service that translates from German national eID scheme into eIDAS 2.0 scheme by either issuing a PID in mdoc format or an SD-JWT VC format in accordance to the selected transport protocol while keeping eIDAS LoA High. The Wallet receives the data from the PID Provider and responds to the Relying Party. One main component of the PID Provider is an eID-Server according to BSI TR-03130 that manages an authorization certificate with authorization bits set according to PID specification of eIDAS 2.0. The eID-Client reads the identity data from the German eID Card or Smart-eID, sends it to the eID-Server that validates the data. The second main component of the PID Provider (for Options B and C) is a service that creates the mdoc or SD-JWT format. This includes the creation of a digital signature or MAC over the identity data read by the eID-Server. The signature or MAC is recognized as the PID attestation under eIDAS by Relying Parties and must fulfill eIDAS level high. Hence, the respective key material and access to the key material must be stored and managed in a way to resist attackers with high attack potential. ## PID Provider Trust Management Relying Parties must be able to establish trust in a PID. Hence, the respective PKI must be made available to the Relying Parties, for example, through Trusted lists (specifically for PID Providers). ## PID Contents PIDs can be issued in two formats, mdoc and [SD-JWT VC](https://datatracker.ietf.org/doc/draft-ietf-oauth-sd-jwt-vc/). For SD-JWT VC, the [SD-JWT VC DM proposal](https://github.com/danielfett/sd-jwt-vc-dm) is to be used. A type hierarchy compliant with the SD-JWT VC DM proposal needs to be defined consisting of a base type for EU PIDs and derived types for national PIDs. The base type would define a minimal dataset (e.g., given name, family name, date of birth) plus define data fields that are common to a number of national PID types (e.g., address, nationalities, gender, middle name, birth family name, etc.). The derived types would define the specific data fields for each national PID type; in particular, national types would define which data fields out of those in the base type are generally available and add specific national data fields. For German national PIDs, the data can be obtained from an ID card, a residence permit, or an eID card for EU citizens. The data available is defined in BSI TR-03127. Under the assumption that data fields in the base type would be structured and defined similar to those in [OpenID Connect Core](https://openid.net/specs/openid-connect-core-1_0.html) and [OpenID eKYC Identity Assurance](https://openid.net/specs/openid-connect-4-identity-assurance-1_0.html), a German national PID could be designed as follows: ```yaml { ## Base data (SD-JWT VC DM) "vct": "https://example.bmi.bund.de/credential/pid/1.0", # metadata would define this as an extension of the base type, e.g., https://example.eudi.eu/credential/pid/1.0 "vct#integrity": "sha256-jo8433ot48....utul8ura33", ## Base dataset that always needs to be present "given_name": "Erika", # from base type, minimal dataset, may be empty "family_name": "Mustermann", # from base type, minimal dataset, may be empty "birthdate": "1963-08-12", # from base type, minimal dataset, may be partial date ## Additional data "source_document_type": "id_card", # not in base type, can also be "residence_permit" or "eu_citizen_eid_card" "birth_family_name": "Gabler", # from base type "place_of_birth": { # from base type "locality": "Berlin", "country": "DE" }, "also_known_as": "Schwester Agnes", # from base type ## data available in certain situations "address": { # from base type, available for ID card and eID card for EU citizens only "street_address": "Heidestraße 17", "locality": "Köln", "postal_code": "51147", "country": "DE" }, "nationalities": [ # from base type, not available for eID cards issued before Nov. 2019 "DE" ], "gender": "female", # available for residence permit only ## Derived claims "age_equal_or_over": { # from base type "12": true, "14": true, "16": true, "18": true, "21": true, "65": false }, # key binding (SD-JWT VC DM) "cnf": { "jwk": { "kty": "EC", "crv": "P-256", "x": "52aDI_ur05n1f_p3jiYGUU82oKZr3m4LsAErM536crQ", "y": "ckhZ-KQ5aXNL91R8Eufg1aOf8Z5pZJnIvuCzNGfdnzo" } }, ## Mandatory metadata as defined by PID Rule Book v1.0.0 section 2.4 "iat": 1712231700, "exp": 1806839700 } ``` All claims except `vct`, `vct#integrity`, `cnf` and the claims listed under metadata would be issued as selectively disclosable claims. The additional claims `iat` and `exp` would define the lifetime of the PID. In Options B, B' and D, this would be a short time frame, while in Options C and C', the PID could be valid for a longer time frame. Alternatively, multiple types could be used to distinguish between the different source document types. This would allow for a more fine-grained specification of available data fields. For example, a type hierarchy similar to the following could be created: - Base Type: `https://example.eudi.eu/credential/pid/1.0` - German Base Type: `https://example.bmi.bund.de/credential/pid/base/1.0` - PID based on ID Card: `https://example.bmi.bund.de/credential/pid/id-card/1.0` - PID based on Residence Permit: `https://example.bmi.bund.de/credential/pid/residence-permit/1.0` - PID based on EU Citizen eID card: `https://example.bmi.bund.de/credential/pid/eu-citizen-eid-card/1.0` - (... other national PID types) While this design option provides more granular credential types, it has a privacy drawback: The source of the PID information is always revealed in the credential type URI and would not be selectively disclosable. If the credential is used, for example, for age verification, the Verifier learns not only the age, but also that the person presenting the credential is not a German citizen. Therefore, a single type for all national PIDs is preferred. PIDs are issued as compact-serialized SD-JWTs. For the mdoc format, the PID contents as defined in the [ARF PID rule book](https://eu-digital-identity-wallet.github.io/eudi-doc-architecture-and-reference-framework/1.2.0/annexes/annex-06-pid-rulebook.pdf) are to be used. ## PID SD-JWT VC Type Metadata This section illustrates a first draft of the SD-JWT VC Type Metadata for the german PID. Note that the values of the fields `vct`, `extends` and `extends#integrity` are only placeholders and will be changed before this definition reaches a final stage. ```json { "vct": "https://example.bmi.bund.de/credential/pid/1.0", "name": "German Person Identification Data Credential - First Version", "description": "The definition of the core identification credential for all natural persons in Germany - first revision", "extends": "https://example.eudi.eu/credential/pid/1.0", "extends#integrity": "sha256-9cLlJNXN-TsMk-PmKjZ5t0WRL5ca_xGgX3c1VLmXfh-WRL5", "display": [ { "lang": "en-US", "name": "German Person Identification Data Credential", "description": "The core identification credential for all natural persons in Germany" }, { "lang": "de-DE", "name": "Deutscher Personenidentifikationsnachweis", "description": "Der zentrale Identifikationsnachweis für alle natürlichen Personen in Deutschland" } ], "claims": [ { "path": [ "vct" ], "sd": "never" }, { "path": [ "vct#integrity" ], "sd": "never" }, { "path": [ "given_name" ], "display": [ { "lang": "de-DE", "label": "Vorname" }, { "lang": "en-US", "label": "Given Name" } ], "sd": "always" }, { "path": [ "family_name" ], "display": [ { "lang": "de-DE", "label": "Nachname" }, { "lang": "en-US", "label": "Last Name" } ], "sd": "always" }, { "path": [ "birthdate" ], "display": [ { "lang": "de-DE", "label": "Geburtsdatum" }, { "lang": "en-US", "label": "Birthdate" } ], "sd": "always" }, { "path": [ "source_document_type" ], "display": [ { "lang": "de-DE", "label": "Quelldokumenttyp", "description": "Der Typ der Quelle des Dokumentes, beispielweise der Personalausweis oder der Aufenthaltstitel" }, { "lang": "en-US", "label": "Source Document Type", "description": "The type of the source of the document, for example the national identity card or the residence title" } ], "sd": "always" }, { "path": [ "address" ], "display": [ { "lang": "de-DE", "label": "Adresse" }, { "lang": "en-US", "label": "Address" } ], "sd": "always" }, { "path": [ "address", "street_address" ], "display": [ { "lang": "de-DE", "label": "Straße" }, { "lang": "en-US", "label": "Street Address" } ], "sd": "always" }, { "path": [ "address", "locality" ], "display": [ { "lang": "de-DE", "label": "Ort" }, { "lang": "en-US", "label": "Locality" } ], "sd": "always" }, { "path": [ "address", "postal_code" ], "display": [ { "lang": "de-DE", "label": "Postleitzahl" }, { "lang": "en-US", "label": "Postal Code" } ], "sd": "always" }, { "path": [ "address", "country" ], "display": [ { "lang": "de-DE", "label": "Land" }, { "lang": "en-US", "label": "Country" } ], "sd": "always" }, { "path": [ "nationalities" ], "display": [ { "lang": "de-DE", "label": "Staatsangehörigkeiten" }, { "lang": "en-US", "label": "Nationalities" } ], "sd": "always" }, { "path": [ "gender" ], "display": [ { "lang": "de-DE", "label": "Geschlecht" }, { "lang": "en-US", "label": "Gender" } ], "sd": "always" }, { "path": [ "birth_family_name" ], "display": [ { "lang": "de-DE", "label": "Geburtsname" }, { "lang": "en-US", "label": "Family Name at Birth" } ], "sd": "always" }, { "path": [ "place_of_birth" ], "display": [ { "lang": "de-DE", "label": "Geburtsort" }, { "lang": "en-US", "label": "Place of Birth" } ], "sd": "always" }, { "path": [ "place_of_birth", "locality" ], "display": [ { "lang": "de-DE", "label": "Geburtsort" }, { "lang": "en-US", "label": "Place of Birth" } ], "sd": "always" }, { "path": [ "place_of_birth", "locality" ], "display": [ { "lang": "de-DE", "label": "Ort" }, { "lang": "en-US", "label": "Locality" } ], "sd": "always" }, { "path": [ "place_of_birth", "country" ], "display": [ { "lang": "de-DE", "label": "Land" }, { "lang": "en-US", "label": "Country" } ], "sd": "always" }, { "path": [ "also_known_as" ], "display": [ { "lang": "de-DE", "label": "Ordens- oder Künstlername" }, { "lang": "en-US", "label": "Religious Name or Pseudonym" } ], "sd": "always" }, { "path": [ "age_equal_or_over" ], "display": [ { "lang": "de-DE", "label": "Altersbestätigung" }, { "lang": "en-US", "label": "Age Verification" } ], "sd": "always" }, { "path": [ "age_equal_or_over", "12" ], "display": [ { "lang": "de-DE", "label": "Mindestalter 12" }, { "lang": "en-US", "label": "Minimum Age 12" } ], "sd": "always" }, { "path": [ "age_equal_or_over", "14" ], "display": [ { "lang": "de-DE", "label": "Mindestalter 14" }, { "lang": "en-US", "label": "Minimum Age 14" } ], "sd": "always" }, { "path": [ "age_equal_or_over", "16" ], "display": [ { "lang": "de-DE", "label": "Mindestalter 16" }, { "lang": "en-US", "label": "Minimum Age 16" } ], "sd": "always" }, { "path": [ "age_equal_or_over", "18" ], "display": [ { "lang": "de-DE", "label": "Mindestalter 18" }, { "lang": "en-US", "label": "Minimum Age 18" } ], "sd": "always" }, { "path": [ "age_equal_or_over", "21" ], "display": [ { "lang": "de-DE", "label": "Mindestalter 21" }, { "lang": "en-US", "label": "Minimum Age 21" } ], "sd": "always" }, { "path": [ "age_equal_or_over", "65" ], "display": [ { "lang": "de-DE", "label": "Mindestalter 65" }, { "lang": "en-US", "label": "Minimum Age 65" } ], "sd": "always" }, { "path": [ "cnf" ], "sd": "never" }, { "path": [ "iat" ], "display": [ { "lang": "de-DE", "label": "Ausstellungsdatum" }, { "lang": "en-US", "label": "Issuing Date" } ], "sd": "never" }, { "path": [ "exp" ], "display": [ { "lang": "de-DE", "label": "Ablaufdatum" }, { "lang": "en-US", "label": "Expiry Date" } ], "sd": "never" }, { "path": [ "issuing_authority" ], "display": [ { "lang": "de-DE", "label": "Ausstellende Behörde" }, { "lang": "en-US", "label": "Issuing Authority" } ], "sd": "never" }, { "path": [ "issuing_country" ], "display": [ { "lang": "de-DE", "label": "Ausstellungsland" }, { "lang": "en-US", "label": "Issuing Country" } ], "sd": "never" } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "German Person Identification Data VCT Schema", "description": "The JSON schema that defines the German Person Identification Data VCT", "type": "object", "properties": { "vct": { "type": "string" }, "vct#integrity": { "type": "string" }, "given_name": { "type": "string" }, "family_name": { "type": "string" }, "birthdate": { "type": "string", "format": "date" }, "source_document_type": { "type": "string" }, "address": { "type": "object", "properties": { "street_address": { "type": "string" }, "locality": { "type": "string" }, "postal_code": { "type": "string" }, "country": { "type": "string" } }, "minProperties": 1 }, "nationalities": { "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true }, "gender": { "type": "string" }, "birth_family_name": { "type": "string" }, "place_of_birth": { "type": "object", "properties": { "locality": { "type": "string" }, "country": { "type": "string" } }, "minProperties": 1 }, "also_known_as": { "type": "string" }, "age_equal_or_over": { "type": "object", "properties": { "12": { "type": "boolean" }, "14": { "type": "boolean" }, "16": { "type": "boolean" }, "18": { "type": "boolean" }, "21": { "type": "boolean" }, "65": { "type": "boolean" } }, "minProperties": 1 }, "cnf": { "type": "object" }, "iat": { "type": "number" }, "exp": { "type": "number" }, "issuing_authority": { "type": "string" }, "issuing_country": { "type": "string" } }, "required": [ "vct", "source_document_type", "cnf", "iat", "exp", "issuing_authority", "issuing_country" ] } } ``` --- ## Wallet Function: (Q)EAA Issuance and Presentation !!! info "Related documentation" This section covers **protocol flows** (OID4VCI, OID4VP) for EAA issuance and presentation. For guidance on **credential design** (formats, signatures, revocation, best practices), see the [EAA Design Section](../../features/EAA/index.md). The updated eIDAS regulation and the Architecture Reference Framework (ARF) describe Electronic Attestation of Attributes (EAA) as generic, general-purpose electronic credentials that attest to any user data. QEAAs are provided by Qualified Trust Service Providers (QTSP) governed under eIDAS. EAAs are provided by any Trust Service Provider that, while supervised under eIDAS, may rely on other contractual frameworks and trust domains. EAAs may also be provided by or on behalf of a public sector body responsible for an authentic source (called Pub-EAA). In this case, Pub-EAAs must match specific requirements equally to QEAAs, and both shall have the same legal effect as lawfully issued attestations in paper form. Any Relying Party may request presentations for QEAAs and EAAs if they are authorized under the eIDAS trust management for RPs. The interaction between QTSPs for QEAA and authentic sources involves several steps to ensure data integrity and security. Data from authentic sources must be transmitted to the QTSP in a secure format. To issue a QEAA into the wallet, the following security measures are required: - **Data Confidentiality**: All data transmitted from the authentic source to the QTSP must be encrypted to prevent unauthorized access. - **Data Integrity**: The data must be digitally signed by the authentic source to verify its authenticity and integrity. - **Compliance with eIDAS Section 3 and Art. 24**: The QTSP must ensure that all processes comply with the requirements outlined in Section 3 of eIDAS and specifically Art. 24, which details the requirements for qualified trust service providers. - **Interoperability**: The QTSP must adhere to the ongoing ETSI standardization efforts to ensure interoperability and compliance with European standards. These measures ensure that the QEAA issued into the wallet is secure, authentic, and compliant with the relevant regulations and standards. ## Use Case Examples The following use cases are examples for (Q)EAAs: - mobile driving license - municipal ID - educational credentials, e.g. diploma - payment - ePrescription - public transport ticket ## Requirements - Technical Interoperability with standards referenced by implementing acts acc Art. 45 c, d and eIDAS - Remote issuance - Presentation for remote and proximity flows - Support level of assurance acc. Art. 24 eIDAS required by use cases (details TBD) ## Credential Formats & Protocols As the PID and a (Q)EAA have the same technical foundation, the credential formats and transport protocols of the PID should also apply to (Q)EAAs. To achieve the best interoperability, the EUDIW should be limited to as few technological options as possible. For the transport protocols the EUDIW shall support: - OpenID4VCI - in Pre-Authorized Code Flow - in Authorization Code Flow - OpenID4VP For credential formats the EUDIW shall support: - ISO mdoc according to 18013-5 - IETF [SD-JWT VC](https://datatracker.ietf.org/doc/draft-ietf-oauth-sd-jwt-vc/) Other credential formats can be used but the description will only focus on the two mentioned ones. ### Batch Credential Issuance The considerations for batch issuance are described in [Batch Credential Issuance for the PID](../00-pid-issuance-and-presentation/index.md#batch-credential-issuance). Those are valid for (Q)EAAs as well. For QEAAs additional timestamps can be included in the credential. This is for example the case for XAdES and JAdES signatures with B-B profile where a sigT timestamp is provided with the signature. This timestamp should be rounded in the same way the other timestamps in the credential are handled according to the link above. ## Remote Issuance Flow [Description](../../features/EAA/EAA-Issuance-OpenID4VC.md) ### User Experience for remote issuance [User Journey: (Q)EAA Issuance - Authorization Code](../../../user_journeys/QEAA-AuthorizationCode-issuance.png) [User Journey: (Q)EAA Issuance - Pre-Authorized Code](../../../user_journeys/QEAA-PreauthorizedCode-issuance.png) _Via the link, the user journey of the sequence diagram can be viewed in the form of lo-fi wireframe screen sequences. All screens of the User Journey are labeled with a specific name. Within the associated sequence diagram, green hexagonal markers labeled "Screen: screen_name" are placed to indicate the corresponding screen in that sequence. The Lo-fi wireframes primarily serve to illustrate the architecture flow from the UX/UI perspective and to show how an implementation could look from the UX/UI perspective. However, it should be kept in mind that the actual realization and implementation of the UX/UI is the responsibility of the wallet providers and the relying parties._ ## Remote Presentation Flow [Description](../../features/EAA/EAA-Presentation-OpenID4VC.md) ### User Experience for remote presentation [User Journey: (Q)EAA Presentation - Same Device](../../../user_journeys/QEAA-SameDevice-presentation.png) [User Journey: (Q)EAA Presentation - Cross Device](../../../user_journeys/QEAA-CrossDevice-presentation.png) _Via the link, the user journey of the sequence diagram can be viewed in the form of lo-fi wireframe screen sequences. All screens of the User Journey are labeled with a specific name. Within the associated sequence diagram, green hexagonal markers labeled "Screen: screen_name" are placed to indicate the corresponding screen in that sequence. The Lo-fi wireframes primarily serve to illustrate the architecture flow from the UX/UI perspective and to show how an implementation could look from the UX/UI perspective. However, it should be kept in mind that the actual realization and implementation of the UX/UI is the responsibility of the wallet providers and the relying parties._ ## Proximity Presentation Flow _NOTE: THIS SECTION WILL BE DEVELOPED IN A FUTURE RELEASE_ ## (Q)EAA Provider Trust Management _NOTE: THIS SECTION WILL BE DEVELOPED IN A FUTURE RELEASE_ --- ## Pseudonym TBD --- ## Wallet Function: Combined Presentation *NOTE: THIS SECTION WILL BE DEVELOPED IN A FUTURE RELEASE* - Multiple EAAs - EAA + PID --- ## EAA Disclosure Policies This document outlines a proposed solution for implementing the disclosure policy requirements from the Implementing Acts (IA) 5a to handle Relying Party authorization during presentation of credentials. ## Motivation In this model, the (Q)EAA provider directly defines rules for which RP data requests are acceptable, adhering to the dynamic authorization framework discussed later. Rather than using an allow list approach, the authorization is credential-based, giving more flexibility to the Issuer to manage the policy. The authorization requirements for accessing Personal Identity Data (PID) and Electronic Attribute Attestation (EAA) data prioritize flexibility and scalability while addressing the following shortcomings of traditional methods like allowlists and static trust anchors: - **Limitations of Allowlists**: Maintaining a comprehensive and updated list of entities (e.g., pharmacies) across Europe is impractical, given the large number of Relying Parties and their varying roles. - **Challenges with Root of Trust Models**: Static root of trust mechanisms introduce risks due to inconsistent registry coordination, and are unable to adapt to evolving authorization needs across multiple jurisdictions. To overcome these limitations, the solution advocates for an attribute-based authorization model that uses a query language like [Digital Credentials Query Language (DCQL)](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-digital-credentials-query-l): - **Attribute-based access control**: The usage of a query language to realize authorization policies avoids the pitfalls of static mechanisms by: - Ensuring RPs are validated through machine-readable, real-time policies. - Allowing issuers to define granular, adaptable rules for data access. - **Automation and Transparency**: The Wallet processes DCQL-based requests automatically, providing users with clear insights into how their data will be used, while ensuring compliance with issuer-defined policies. ## International interoperability The following can be specified individually by each member state without impacting interoperability: - Setting up management for Authorization Attestations ## Out of Scope The setup and administration of authorities responsible for the discovery of the disclosure policies and the setup of the authorities issuing the required credentials are out of scope of this document. ## Overview ```plantuml digraph G { rankdir=LR node [shape=box] // Nodes tl [label="Trusted List"] wrp [label="Wallet-Relying Party"] wrp_registrar [label="Wallet-Relying Party Registrar"] wallet [label="Wallet"] i [label="Issuer"] dc [label="Disclosure Policy"] auth [label="Authority for an ecosystem"] ac [label="Authorization Attestation", fillcolor=yellow, style=filled] vc [label="Verifiable Credential", fillcolor=yellow, style=filled] vp [label="Verifiable Presentation" fillcolor=yellow, style=filled] // Edges wrp -> wrp_registrar [label="onboarded"] wrp_registrar -> tl [label="published"] vp -> wrp [label="presented to"] wallet -> vp [label="creates"] i -> vc [label="issues"] vc -> wallet [label="issued for"] vc -> dc [label="references"] dc -> auth [label="references as authority"] auth -> ac [label="issues"] ac -> wrp [label="issued for"] ac -> dc [label="required for"] } ``` ## Policies Disclosure policies are defined using a single `policy` object that follows the **EmbeddedDisclosurePolicy** JSON Schema. Each policy specifies one trust model and its corresponding values. Only one policy can be defined per credential. ### Policy object | Field | Required | Type | Description | | --------- | ----------- | ------ | ----------------------------------------------------------------------- | | `policy` | Yes | string | Type of policy (`allowList`, `rootOfTrust`, `attestationBased`, `none`) | | `options` | Conditional | array | Objects that define `claims` and `values` (or credentials) | | `url` | Yes | string | Human-readable explanation URL of the disclosure policy | --- ### Allowlist Policy **Definition**: A list of Relying Party identifiers (subject alternative names) that are authorized to request specific claims of this credential. **Rules**: - `policy` must be `allowList`. - Each entry in `options` may include: - `claims`: OPTIONAL — array of claim paths to which the allowlist applies. If omitted, the allowlist applies to all claims in the credential. - `values`: REQUIRED — array of subject alternative names of the authorized Relying Parties. - Wallets must match the RP’s access certificate against the allowlist. If an intermediary is used, the registration certificate subject must also appear in the allowlist. **Example**: ```json { "policy": "allowList", "options": [ { "claims": [{ "path": ["country"] }], "values": ["EI:SE-5567971433", "NTRDE-HRB123456"] } ], "url": "https://example.com/disclosure-policy" } ``` --- ### Root of Trust Policy **Definition**: Instead of enumerating all Relying Parties, the Issuer trusts only specific Access Certificate Providers to authorize RPs. **Rules**: - `policy` must be `rootOfTrust`. - Each entry in `options` may include: - `claims`: OPTIONAL — array of claim paths to which the trust anchor applies. - `values`: REQUIRED — array of identifiers of Access Certificate Providers authorized to issue access certificates. - Wallets must verify that the RP’s certificate chains to one of these trusted providers, which are listed in the EU Trusted List. **Example**: ```json { "policy": "rootOfTrust", "options": [ { "claims": [{ "path": ["country"] }], "values": ["GermanAccessCertificateProvider"] } ], "url": "https://example.com/disclosure-policy" } ``` --- ### Attestation-Based Policy **Definition**: Relying Parties must present authorization attestations fulfilling specific claim and credential requirements. **Rules**: - `policy` must be `attestationBased`. - Each entry in `options` may include: - `claims`: OPTIONAL — array of claim paths requested. Defaults to all claims in the attestation if omitted. - `credentials`: REQUIRED — array of credential requirements, defined with [credential query syntax](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-credential-query). - `credential_sets`: OPTIONAL — credential set requirements, using [credential set query syntax](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-credential-set-query). **Example**: ```json { "policy": "attestationBased", "options": [ { "claims": [{ "path": ["last_name"] }], "credentials": [ { "id": "membership", "meta": { "vct_values": ["https://example.com/membership"] }, "format": "sd-jwt-dc", "trusted_authorities": { "type": "aki", "values": ["s9tIpPmhxdiuNkHMEWNpYim8S8Y"] } } ] } ], "url": "https://example.com/disclosure-policy" } ``` > Note: The attestation must be bound to the Access Certificate used for signing > the presentation request. --- ### None Policy **Definition**: No disclosure restrictions are applied. **Rules**: - `policy` must be `none`. - No `options` are required. **Example**: ```json { "policy": "none", "url": "https://example.com/disclosure-policy" } ``` --- ## Providing approaches The policy MUST be included into the [Credential Issuer Metadata](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#section-9) by value, not by reference. Each credential configuration can have its own policy. Policies may apply to **all claims** of a credential or only to **specific claims** as indicated in each `options.claims` array. The Wallet fetches the policy during the issuance process and stores it. If the Issuer updates its policy, it needs to revoke all issued credentials. During reissuance, the Wallet fetches the new policy. **Non-normative example (embedded policy with allow list):** ```json { "credential_configurations_supported": { "SD_JWT_VC_example_in_OpenID4VCI": { "format": "dc+sd-jwt", "scope": "SD_JWT_VC_example_in_OpenID4VCI", "cryptographic_binding_methods_supported": ["jwk"], "credential_signing_alg_values_supported": ["ES256"], "vct": "SD_JWT_VC_example_in_OpenID4VCI", "disclosure_policy": { "policy": "allowList", "options": [ { "claims": [{ "path": ["country"] }], "values": ["EI:SE-5567971433", "NTRDE-HRB123456"] } ], "url": "https://example.com/disclosure-policy" } } } } ``` --- ## Policy discovery Two perspectives must be distinguished: - **Wallet perspective (enforcement)**: Wallets always retrieve the disclosure policy from the Issuer’s metadata endpoint (`.well-known/openid-credential-issuer`) and enforce it during credential presentation. Policies may restrict specific claims, so the Wallet ensures that requested claims are only released if allowed by the stored policy. It will not fetch the policy during presentation to avoid leaking information. - **Relying Party perspective (discovery)**: Relying Parties must know in advance what authorization credentials they need or how to join the list of authorized relying parties. Since this is not yet defined in the ARF, we assume that attestation rulebooks or policy registries will serve as discovery mechanisms for RPs to learn about policy requirements, including claim-specific restrictions. --- ## Authorization Attestation The authorization attestation is not bound to a specific credential format, so any format that can be referenced by [DCQL](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#format_specific_parameters) can be used. Requirements for interoperability: - Attestations should be revocable or short-lived. - Attestations must be bound to the Access Certificates of the RP. A Wallet MUST NOT accept an attestation that is not bound if there is no other way to prove ownership. In case of OID4VP, the authorization attestations have to be attached to the [authorization request](../flows/OID4VC-with-WRP-attestations.md). Below are examples for specific credential formats that can be used for the authorization attestation. --- ## Passing attestations The RP can pass the authorization attestation in the authorization request via the [verifier_info](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-verifier_info). **Non-normative example:** ```json { "verifier_info": [ { "format": "dc+sd-jwt", "data": "eyJ0eXAiOiJ...zLTQ1LTY3ODkiXQ~" } ] } ``` --- ## Use Case Scenarios **Medical Credential Issuer Limits Access to Certified Pharmacies** → Attestation-based policy (specific claims like prescription data). **Tax Authority Restricts Access to Financial Data Credentials** → Root-of-trust policy (claim-specific or global). **Mobility Provider Credential Issuer Limits Requests to Public Authorities** → Allowlist policy (restricted to relevant claims). --- ## EUDI Wallet Link Governance and Implementation Hints **Recommendations on the use of a joint invocation mechanism for both Android and iOS** ## Introduction The purpose of this document is to provide guidance and advice on the use of a joint wallet invocation mechanism among member states EUDI wallet apps and their respective implementations on both iOS and Android. ### Motivation As part of the EU Digital Identity (EUDI) Wallet pilot initiative, each EU member state will offer a wallet app to its citizens, capable of performing various administrative formalities. Regulation requires interoperability among wallets, requiring reliant digital services to accept all wallets from participating EU member states. Interoperability can either be achieved by having each member state's wallet support every other authentication scheme, resulting in 27 implementations in each wallet. Alternatively, every reliant service would have to support 27 schemes and offer some kind of selection, enabling a user to pick their wallet solution. This would result in a sub-par user experience. This can be avoided by the use of a single common invocation mechanism. Every member state would still have to implement said scheme, but the interoperability requirement would essentially be reduced from 27 to 1, as every wallet supports just one authentication scheme. ### Joint Scheme/Domain All wallet solutions are based on a redirection from a given relying party into a user's wallet app in order to identify the user. So far, as an example, the German eID solution used a custom protocol scheme (`Example: eID://auth/12345`). Custom protocol schemes are prone to hijacking, as any app could just implement said protocol and potentially redirect the user to a malicious app. Another option is the use of regular web URLs, as both Android and iOS support linking web URLs to respective native apps. ```http Example: https://wallet.eudi.example/auth/12345 ``` *Figure 1: Example joint authentication URL* The ownership of a given domain can be asserted by placing a verification file online (Android Asset Links or iOS Entitled Domain Verification). Wallet apps of individual member states could rely on a joint domain name like `wallet.eudi.example` and individual wallet solutions could perform their respective tasks using said domain to provide a secure redirection from websites into respective wallet apps. ## Governance Ownership of the shared domain involves administrative duties and long-term oversight. ### Acquisition & Renewal A domain name must be acquired for joint efforts of operating wallet solutions. It cannot be changed, changing is only possible when all member states agree on a new common domain and implement it accordingly. Furthermore, domain registrations must be renewed at least yearly, so financial means should be available to ensure long-term sustainability of a joint domain name. There is a risk in the domain name expiring if not renewed in time. Given the aspiration of attracting millions of users, an attacker could potentially buy the joint domain name and use it for malicious purposes such as redirecting to a phishing app. ### Web Hosting & Scaling Although only smaller, static files need to be hosted under the joint domain name, the intended goal is to provide it to millions of users from all the member states at once, therefore proper hosting, scaling and long-term operation must be guaranteed. Given all member states rely on a joint domain name, it should resolve quickly for every member state, ensuring smooth operation wherever a user may reside. ### Onboarding & Key management A process must be in place allowing member states to add, modify and remove a signing key. The hosted configuration files must be updated in a timely manner to allow member states to roll out their respective app. Furthermore, keys may expire, be stolen or lost, therefore, a process must be in place to modify or remove compromised keys from the configuration files in a timely manner. A verification tool should be used whenever edits to the configuration files are made, as a faulty configuration file will disable the redirection for every member state. It is a single point of failure. ### Appropriate Error and Help Pages As shown in Figure 1, should a redirection to a given wallet app fail, the user would just access said authentication URL in a browser. Therefore, an appropriate website should be shown under the relevant URL, enabling helpful guidance on how to properly set up a respective wallet. Also, a retry button should be shown enabling a user to retry a given authentication after installing respective apps. The install-state of an appropriate wallet app can be determined using the "[Get Installed Related Apps API](https://wicg.github.io/get-installed-related-apps/spec/)". ### SSL/TLS Given the joint domain name should only be accessible using HTTPS, appropriate configuration must be in place to ensure a valid SSL/TLS certificate is always issued and installed properly. It is imperative the SSL configuration does not expire, that is to say it is renewed in time, given an invalid configuration will result in the redirection failing for every member state (Single point of failure). ## Implementation Details Both Android and iOS are major mobile operating systems and feature linking web content to native apps. The use of a domain name for linking web content to native apps is their assertion of ownership. While a custom scheme serves its purpose, any malicious app could implement the scheme, while a domain name's ownership can be established by placing appropriate configuration files on the web. ### iOS #### iOS Client Side Apple refers to the system as "Associated Domain Entitlement". It consists of providing said domain entitlement as a key value pair in the bundle resources of an iOS app. Key: `com.apple.developer.associated-domains` Value: Array of strings, each formatted as `:` The service we're targeting is referred to as "applinks". The full example of a value string should look as follows: ``` applinks:wallet.eudi.example ``` *Figure 2 iOS client-side example* As a side note during development: an alternate mode must be set as follows: `applinks:wallet.eudi.example?mode=developer` Reference: [https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_associated-domains](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_associated-domains) #### iOS Server Side The associated domain entitlement is complemented on the server side through a file called "apple-app-site-association" placed under the following URL: `https://wallet.eudi.example/.well-known/apple-app-site-association` Its content should reflect the associated app IDs of member states as well as a mapping of URLs that should be opened in the wallet app. ```json { "applinks": { "details": [ { "appIDs": [ "ABCDE12345.com.example.app", "ABCDE12345.com.example.app2" ], "components": [ { "/": "/auth/*", "?": { "token": "????" }, "comment": "Matches any URL with a path that starts with /auth/ and that has a query item with name 'token' and a value of exactly four characters." } ] } ] } } ``` *Figure 3 iOS server-side example* As shown above, the "appIDs" entry must be updatable to reflect respective member states' wallet apps. Reference: ### Android Similarly to iOS, the Android system refers to establishing ownership of a domain as Android App Links on the client and "Google Digital Asset Links" on the server side. The following example will illustrate their use. #### Android Client Side For an Android app, its "AndroidManifest.xml" must be modified in order to register an "intent-filter" enabling the Android system to redirect registered URLs to it. ```xml ... ... ``` *Figure 4 AndroidManifest.xml example* As shown in Figure 4, the entry consists of specifying an appropriate host using the "android:host" tag attribute. Furthermore, the scheme should only bind to "https" as it's the only method of ensuring an encrypted resolution of the digital asset links file. Lastly, note the "android:autoVerify" tag. It instructs the Android system to resolve appropriate digital asset links configuration files automatically as well as their verification enabling the user to be redirected without additional prompts. #### Android Server-Side Configuration Similarly to iOS, a special configuration file must be published under the joint target domain. The following example will illustrate how to properly define this file. The contents of Figure 5 must be accessible publicly under the following URL: ```https://wallet.example.org/.well-known/assetlinks.json``` ```json [{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.meberstate1.app", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }, { "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.memberstate2.app", "sha256_cert_fingerprints": ["15:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E6"] } }] ``` *Figure 5 Android server-side configuration file* As shown in Figure 5, multiple apps may be configured. The "package-name" must match the package ID defined in the respective *AndroidManifest.xml* on the client side. Furthermore, the hash of the signing key must be included. Multiple signing keys may be defined for e.g., a development key or a transitional phase to a new signing key. The appropriate SHA256 hash of a signing key can be obtained using the following console command: ``` keytool -list -v -keystore my-release-key.keystore ``` Reference: [https://developer.android.com/training/app-links/verify-android-applinks](https://developer.android.com/training/app-links/verify-android-applinks) ### Scheme Collision Users can have more than one wallet app installed, e.g., when they are citizens of more than one EU member state. Since Android and iOS behave differently when more than one app is registered for the same domain, it is still to be discussed how this case should be handled. --- ## OID4VC Protocol Integration ## Overview This document describes how Access Certificates and Registration Certificates are integrated into the OpenID for Verifiable Credentials (OID4VC) protocol family for issuance and presentation flows. !!! info "Normative Standards" The technical specifications are defined in ETSI standards: - **[ETSI TS 119 472-2](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)**: Presentation requirements - **[ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)**: Issuance requirements - **[ETSI TS 119 411-8](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)**: Access Certificates - **[ETSI TS 119 475](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)**: Registration Certificates For details on the certificates themselves, see [Wallet-Relying Party Authentication](../../ecosystem-concepts/trust/wallet-relying-party-authentication.md). --- ## Design Principle: Privacy-Preserving Direct Inclusion Certificates are included **directly in requests** rather than being fetched from the Registrar. This design: - **Preserves privacy**: The Registrar cannot monitor which Wallet interacts with which RP - **Supports offline use**: No real-time connection to Registrar required - **Reduces latency**: No additional round-trips during the flow The Wallet only contacts the Registrar to fetch revocation status (CRL or Status List), which does not reveal the specific transaction. --- ## Credential Issuance (OID4VCI) Before issuing a credential to a Wallet, the issuer must authenticate itself. ### Flow Overview ```plantuml @startuml skinparam maxMessageSize 200 skinparam sequenceMessageAlign center participant w as "EUDI Wallet" participant i as "(Q)EAA Provider" participant rpr as "Registrar" participant eu as "EU Trust Anchor" note over w: Periodically fetch trust anchor w -> eu: Fetch EU List of Registrars eu -> w: Trust anchor list w -> i: Request Credential Issuer Metadata i -> w: Signed metadata with Access Certificate w -> w: Validate issuer identity\n(chain of trust) w -> rpr: Fetch CRL / Status List rpr -> w: Revocation status note over w: Proceed if valid @enduml ``` ### Key Steps 1. **Trust anchor**: Wallet maintains an up-to-date EU List of Registrars 2. **Metadata request**: Wallet fetches Credential Issuer Metadata 3. **Issuer authentication**: Metadata is signed; Access Certificate included 4. **Validation**: Wallet validates the certificate chain of trust 5. **Revocation check**: Wallet fetches CRL from Registrar 6. **Decision**: Process continues only if all validations pass --- ## Credential Presentation (OID4VP) When requesting a credential presentation, the RP must authenticate and declare its intended use. ### Flow Overview ```plantuml @startuml skinparam maxMessageSize 200 skinparam sequenceMessageAlign center participant u as "User" participant w as "Wallet" participant rp as "Relying Party" participant rpr as "Registrar" note over w: Trust anchor already cached rp -> rp: Create presentation request rp -> w: Send request with certificates note right: Access + Registration\nCertificates attached w -> w: Validate RP identity w -> w: Validate intended use\n(over-asking check) w -> rpr: Fetch revocation status rpr -> w: CRL / Status List w -> u: Display RP info and purpose u -> w: Approve presentation w -> rp: Send presentation response @enduml ``` ### Key Steps 1. **Request creation**: RP creates presentation request signed with Access Certificate key 2. **Certificate inclusion**: Both Access Certificate and Registration Certificate(s) are attached to the request 3. **RP authentication**: Wallet validates the Access Certificate chain 4. **Intended use validation**: Wallet compares request against Registration Certificate 5. **Revocation check**: Wallet fetches status from Registrar 6. **User consent**: Wallet displays RP identity and purpose; user approves 7. **Response**: Wallet sends presentation to RP ### Over-Asking Protection The Wallet validates that the requested attributes are within the scope declared in the Registration Certificate: - Requested credentials must be a subset of registered credentials - Requested claims must be a subset of registered claims - If validation fails, user is warned but may choose to proceed --- ## Certificate Attachment Certificates are attached to requests according to ETSI specifications: | Certificate Type | Purpose | Specification | |--------------------------|--------------------------|------------------------------------------------------------------------------------------| | Access Certificate | RP authentication | [ETSI TS 119 411-8](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | | Registration Certificate | Intended use declaration | [ETSI TS 119 475](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | The technical format for attaching certificates to OID4VP/OID4VCI requests is defined in the respective ETSI standards. --- ## Proximity Flow For proximity (offline) scenarios, the same principles apply: - Certificates are included directly in the request - Validation occurs locally on the device - Revocation status may be checked when connectivity is available - User consent is always required --- ## Related Resources - [Wallet-Relying Party Authentication](../../ecosystem-concepts/trust/wallet-relying-party-authentication.md) — Certificate details - [Trust Validation Overview](../../ecosystem-concepts/trust/trust-validation.md) — Validation procedures - [Disclosure Policies](../06-disclosure-policies/index.md) — Authorization attestations --- ## PID Option B': Authenticated Channel with Cloud Support ## Basic Idea This flow describes a flow that issues PID credentials in ISO mdoc / SD-JWT VC format on-demand when the presentation request is received. It uses the OpenID4VCI protocol for issuance and the OpenID4VP protocol for presentation. The PID credentials are HMAC'd by the PID Provider for the specific transaction. To improve user experience and prevent the users from tapping an eID card every time a Credential needs to be presented, the concept of a seed credential is introduced. A seed credential can be used for a limited period of time to generate presentations instead of the national eID. Such seed credential is derived from the national eID and stored on the mobile device. To secure the seed credential, the user must set up a new PID PIN, which is verified by the PID provider on the server side during on-demand issuance. ## Lifecycle The credential is created on-demand by the PID Provider, i.e., a new credential is created for every transaction. The credential is not stored in the wallet. It is bound to the specific transaction through not only the nonce and audience, but also the symmetric key used for HMAC'ing, which is derived from ephemeral keys of the RP and PID Provider. The seed credential issued and signed by the PID provider should only have a limited lifetime and should be bound to the same key as the wallet attestation issued by the wallet provider and to the key derived from the user PID PIN. The seed credential contains all available PID attributes and is intended exclusively for presentation to the PID provider, therefore it is a credential (in JWT format) that does not provide a mechanism for selective disclosure. ## Credential formats Two solutions are described: - **ISO mdoc:** The ISO mdoc credential format is used with: - issuerAuth as issuer data authentication, a COSE_Sign1 signature over the MobileSecurityObject (see ISO 23220-4 7.1.3.4.2.1) signed by the PID Provider - no signed hashes are transmitted, i.e., `digestAlgorithm` and `valueDigests` are omitted - deviceMAC as mdoc authentication method, a COSE_Mac0 MAC over the deviceAuthentication data (see ISO 18013-5 9.1.3.5) signed by the PID Provider - containing the PID data - **SD-JWT VC:** The SD-JWT VC credential format is used with: - SD-JWT issued by the PID Provider, a JOSE JWS with MAC key derived from ECDH* and signed by the PID Provider - containing the PID data - the Wallet provides an ephemeral, asymmetric key to the PID Provider for the key binding - KB-JWT issued by the Wallet, a JOSE JWS using digital signature and signed by the Wallet - containing nonce and audience of the Relying Party - containing a hash of the SD-JWT and the selected disclosures Note that in mdoc, it is PID Provider and not the Wallet who creates DeviceSigned containing only the selectively disclosed data based on the Verifier's request and user consent. This is different from ISO 18013-5, where it is the Wallet who creates DeviceSigned. It is PID Provider who creates IssuerSigned. In SD-JWT, it is PID Provider who creates SD-JWT and the Wallet who creates KB-JWT. The establishment of the authenticated channel is defined: - for mdoc, in Chapter 9.1.3.5 in ISO 18013-5, in the mdoc MAC Authentication section - for SD-JWT, the IETF Draft for [Designated Verifier Signatures](https://datatracker.ietf.org/doc/draft-bastian-dvs-jose/) defines a JOSE algorithm to be used ## Cryptographic Formats Long-Term keys: - **PID Provider has long-term key pair** $(pp\_pub, pp\_priv)$ which is used - to sign over the ephemeral issuer key, authenticating it for credential issuance - sign the **Seed PID-Credential** - **RP has long-term key pair** $(rp\_pub, rp\_priv)$ which is used - to sign over the authorization request, authenticating its contents - **Wallet Instance has long-term device bound key pair** $(device\_pub, device\_priv)$ which is used - to generate proof of possession of wallet attestation - to bind the PIN proof to the device - **Wallet Instance has long-term AES key** $(pin\_salt)$ which is used - to derive the `pin_derived_eph_priv` used as PoP of PID PIN - **Wallet Backend long-term key pair** $(wp\_pub, wp\_priv)$ which is used - to sign wallet instance's wallet attestations - **Wallet Instance or Wallet Backend long-term key pair** $(dpop\_pub, _dpop\_priv)$ which is used - as the DPoP key Transaction-specific keys: - **Relying Party generates ephemeral key pair** $(rp\_eph\_pub, rp\_eph\_priv)$ which is used - as contribution to HMAC key - **PID Provider generates ephemeral key pair** $(pp\_eph\_pub, pp\_eph\_priv)$ which is used as contribution to HMAC key - **Wallet generates ephemeral key pair** $(kb\_eph\_pub, kb\_eph\_priv)$ which is used - to sign KB-JWT (SD-JWT) - **Wallet Instance generates ephemeral key derived from user PID PIN** $(pin\_derived\_eph\_pub, pin\_derived\_eph\_priv)$ which is used - to generate PIN proof of possession Note: The key derived from user PIN is not stored by the Wallet Instance, instead it is generated every time the user enters the PIN. Artifacts: - PID Provider creates **certificate for ephemeral issuer key**: $x5c\_header := \text{sign}(pp\_eph\_pub)_{pp\_priv}$ - **Key for authenticating SD-JWT:** $hmac\_key := \text{ecdh}(pp\_eph\_priv, rp\_eph\_pub)$ - PID Provider creates **SD-JWT**: $sd\_jwt := \text{hmac}(x5c\_header, \mathit{eID\_data}, kb\_eph\_pub)_{hmac\_key}$ and disclosures - Wallet Backend creates **Wallet Attestation** including $(device\_pub)$ and signed with $(wp\_priv)$, Wallet Attestion is stored by Wallet Instance - PID Provider creates **Seed PID-Credential** as JWT including $(device\_pub)$ and signed with $(pp\_priv)$, which is used to generate the credentials in the "On-the-fly PID Issuance" for presentation. Content of the Seed PID-Credential: - eID data of the holder (PID data set) - Key for the holder binding of the seed credential $(device\_pub)$ ### Dependencies #### SD-JWT *TODO: May want to expand to include metadata.* ```plantuml digraph G { node [shape=box] subgraph cluster_wallet { style=filled color=lightgreen label="Wallet" subgraph cluster_wscd { style=filled color=lightyellow label="WSCD" device_key [label="🗝 (device_priv, device_pub)"] dpop_key [label="🗝 (dpop_priv, dpop_pub)"] } pin_salt [label="🗝 PIN salt key"] pin_key [label="🗝 (pin_derived_eph_priv, pin_derived_eph_pub)"] w_attest_POP[label="wallet attestation POP (wallet attestation nonce)"] kb_key [label="🗝 (kb_eph_priv, kb_eph_pub)"] kb_jwt [label="KB-JWT(nonce,aud,hash(SD-JWT,disclosures))"] dpop [label="DPoP proof (dpop_nonce)"] } subgraph cluster_rp { style=filled color=orchid label="Relying Party" rp [label="🗝 (rp_eph_priv, rp_eph_pub)"] } hmac [label="🗝 HMAC key"] subgraph cluster_pid_provider { style=filled color=lightblue label="PID Provider" pp [label="🗝 (pp_priv, pp_pub)"] seed_C [label="seed credential (device_pub, pin_derived_eph_pub)"] session_id [shape=record,label="{pid_issuer_session_id}"] pp_eph [label="🗝 (pp_eph_priv, pp_eph_pub)"] pp_cert [label="key certificate for pp_eph"] sd_jwt [label="SD-JWT(eID Data, kb_eph_pub)"] } pin_salt->pin_key [label="derived with PIN"] device_key->w_attest_POP [label="sign"] device_key->session_id [label="sign"] pin_key->session_id [label="sign"] rp->hmac [label="ecdh-ka"] pp->seed_C [label="sign"] dpop_key->dpop [label="sign"] kb_key->kb_jwt [label="sign"] pp_eph->hmac [label="ecdh-ka"] pp->pp_cert [label="sign"] hmac->sd_jwt [label="sign"] } ``` #### mdoc *TODO: May want to expand to include metadata.* ```plantuml digraph G { node [shape=box] subgraph cluster_wallet { style=filled color=lightgreen label="Wallet" subgraph cluster_wscd { style=filled color=lightyellow label="WSCD" device_key [label="🗝 (device_priv, device_pub)"] dpop_key [label="🗝 (dpop_priv, dpop_pub)"] } pin_salt [label="🗝 PIN salt key"] pin_key [label="🗝 (pin_derived_eph_priv, pin_derived_eph_pub)"] w_attest_POP[label="wallet attestation POP (wallet attestation nonce)"] dpop [label="DPoP proof (dpop_nonce)"] } subgraph cluster_rp { style=filled color=orchid label="Relying Party" rp [label="🗝 (rp_eph_priv, rp_eph_pub)"] } hmac [label="🗝 HMAC key"] subgraph cluster_pid_provider { style=filled color=lightblue label="PID Provider" pp [label="🗝 (pp_priv, pp_pub)"] seed_C [label="seed credential (device_pub, pin_derived_eph_pub)"] session_id [shape=record,label="{pid_issuer_session_id}"] pp_eph [label="🗝 (pp_eph_priv, pp_eph_pub)"] issuerAuth [label="issuerAuth(pp_eph_pub)"] devAuth [label="deviceAuth(eID Data, SessionTranscript)"] } pin_salt->pin_key [label="derived with PIN"] device_key->w_attest_POP [label="sign"] device_key->session_id [label="sign"] pin_key->session_id [label="sign"] rp->hmac [label="ecdh-ka"] pp->seed_C [label="sign"] dpop_key->dpop [label="sign"] pp_eph->hmac [label="ecdh-ka"] hmac->devAuth [label="sign"] pp->issuerAuth [label="sign"] } ``` ## Sequence Diagrams and Step-by-Step Description of Each Step Each step of the protocol will be explained using a sequence diagram followed by a step-by-step description. ### Wallet Activation [User Journey: Wallet Activation - Authenticated Channel - Cloud](../../../user_journeys/PID-AuthenticatedChannel-cloud-initialization.png) To initialize the wallet, the Wallet obtains wallet attestation as defined in [Wallet Attestation](Wallet-Attestation.md). ### PID Seed-Credential Issuance #### PID Seed-Credential Issuance Sequence Diagram [User Journey: PID Issuance - Authenticated Channel - Cloud](../../../user_journeys/PID-AuthenticatedChannel-cloud-issuance.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title PID Seed Credential Issuance over OpenID4VCI participant u [ PID Holder ---- ""PIN: (//user_pin//)"" ] participant w [ User's EUDI Wallet Instance\ (eID-Client) ---- ""Device Key: (//device_pub//, //device_priv//)"" ""Wallet Attestion bound to //device_pub//"" ""PIN Salt: //pin_salt//"" ] participant i [ PID Provider (eService+eID Server) ---- ""Long-term Key: (//pp_pub//, //pp_priv//)"" ] u --> w : open wallet, unlock wallet hnote over w #dfd: Screen: launch_wallet hnote over w #dfd: Screen: unlock_wallet u --> w : request issuance of PID hnote over w #dfd: Screen: credential_catalog note over w,i: PID Issuer and EUDI Wallet have inherent trust relationship, metadata may be pre-configured or retrieved w -> i : tls() HTTP POST wallet attestation nonce i -> i : generate and store nonce i -> w : tls() HTTP 200 w -> w : create and sign wallet attestation PoP JWT (incl. wallet attestation nonce) w -> i : tls() HTTP POST PAR (PKCE code_challenge, wallet attestation JWT, wallet attestation PoP JWT, redirect_uri) i -> i : verify wallet attestation & PoP \ncheck Wallet Provider solution status on trust list i -> w : tls() HTTP 200 request_uri note right : Attestation guarantees with high certainty that Wallet is trustworthy and not manipulated w -> i : tls() HTTP GET hnote over w #dfd: Screen: consent_add_credential hnote over w #dfd: Screen: eid_start group Read eID or Smart eID acc. to BSI TR-03130 i -> w : tls() starting the eID Process w <-> i : eID Process u <--> w : hnote over w #dfd: Screen: eid_pin w <-> i : eID Process note left : all PID attributes are requested w -> i : tls() HTTP GET finishing the eID process with refreshUrl hnote over w #dfd: Screen: eid_nfc_data end i -> w : tls() HTTP 302 group Generate initial DPoP nonce w -> w : generate placeholder DPoP proof with generic (not HSM-bound) key pair w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> w : tls() HTTP 400 note left : The Wallet should check at this point, whether the Token Endpoint delivered the expected error and nonce. If not, this needs to be handled (retry or abort gracefully). w -> w: store dpop_nonce end w -> w: prepare DPoP proof JWT with //dpop_pub//, dpop_nonce, iat and sign with //dpop_priv// w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> i : lookup authorization code\ngenerate TokenResponse with DPoP access token\nverify PKCE challenge\nverify DPoP proof i -> w : tls() HTTP 200 group set PID PIN w -> w : generate and store AES key: //pin_salt// u <--> w : set PID PIN hnote over w #dfd: Screen: set_pid_pin w -> w : generate key pair (//pin_derived_eph_pub//, //pin_derived_eph_priv//) from KDF(encrypt_AES(//pin_salt//, PIN), PIN) w -> w : generate PoP for pin derived ephemeral key - sign(nonce, //device_pub//) //pin_derived_eph_priv// w -> w : generate PoP for device_key - sign(nonce, //pin_derived_eph_pub//) //device_priv// end w -> w : generate credential response encryption key pair (//cre_eph_pub//, //cre_eph_priv//) w -> w : create credential_response_encryption object with jwk containing //cre_eph_pub// w -> w: prepare DPoP proof JWT with //dpop_pub//, dpop_nonce, iat and sign with //dpop_priv// w -> i : tls() HTTP POST i -> i: lookup access token and verify DPoP proof i -> i: check signatures on the PoPs i -> i: Set up retry counter and save together with //pin_derived_eph_pub// using hash(//device_pub//) as identifier i -> i: generate PID seed credential with eID data, //device_pub// and signed by //pp_priv// i -> i: generate encrypted credential response JWT using the values received in the credential_response_encryption object i -> w : tls() HTTP 200 w -> w : decrypt credential response JWT and retrieve seed credential JWT w -> w : store seed credential hnote over w #dfd: Screen: success hnote over w #dfd: Screen: home @enduml ``` ### PID Seed-Credential Issuance Step-by-Step Description 1. The User opens the Wallet App 2. The User requests a PID issuance 3. The Wallet requests a fresh nonce for the wallet attestation nonce from the PID Provider (wallet attestation nonce) 4. The PID Provider generates a fresh nonce linked to the issuance session 5. The PID Provider returns the wallet attestation nonce to the Wallet 6. The Wallet generates a Wallet Attestation PoP and signs it with *device_priv*; containing - audience - expiration time - wallet attestation nonce 7. The wallet sends the Pushed Authorization Request to the PID Provider; containing - PKCE code_challenge - wallet attestation + PoP - redirect_uri 8. The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list 9. The PID Provider returns a request_uri that is bound to the Pushed Authorization Request 10. The Wallet sends the Authorization Request containing the PAR request_uri. 11. The Wallet starts user authentication process using eID by sending a redirect (303) to the eID Server in response to the Authorization Request. 12. Further communication is exchanged to perform the eID process. 13. The user provides the eID PIN to the wallet app. 14. Further communication is exchanged to perform the eID process 15. The eID process is finished and as a final step the Wallet sends a request to the PID Provider calling the refreshURL. 16. The PID Provider responds to the Wallet with an Authorization Response in response to a request sent as part of an eID process. It contains the authorization code. 17. The Wallet generates (and stores) a placeholder DPoP proof with a generic (not HSM-bound) keypair to trigger an error response from the Token endpoint necessary to retrieve the `dpop_nonce`. 18. The Wallet sends a Token Request to the PID Provider, containing the placeholder DPoP proof JWT. 19. The PID Provider generates and stores a `dpop_nonce`. 20. The PID Provider responds with the expected error "use_dpop_nonce", containing the `dpop_nonce` to be used from now on in the DPoP nonce header. 21. The Wallet extracts and stores the `dpop_nonce`. 22. The Wallet now prepares the actual DPoP proof JWT for `dpop_pub` including the `dpop_nonce` and `iat` and signs it with *dpop_priv*. 23. The Wallet sends a Token Request to the PID Provider; containing: - the authorization code from Authorization Response - the PKCE code_verifier matching the code_challenge from Authorization Request - the DPoP Header 24. The PID Provider generates and stores a fresh `dpop_nonce`. 25. The PID Provider matches the code, verifies the PKCE code_verifier to the previously received code_challenge and verifies the DPoP proof. It then generates an access token bound to the DPoP key. 26. The PID Provider sends a Token Response; containing - DPoP-bound access token - c_nonce - a fresh `dpop_nonce` in the DPoP nonce header 27. The Wallet generates an AES key (*pin_salt*) - This key will be used to generate a salt used by the PID PIN key derivation mechanism 28. The User enters the new PID PIN (most likely twice to ensure that the user has entered the intended PIN) 29. The Wallet generates the key pair (*pin_derived_eph_pub/priv*) derived from the PID PIN - This key pair is used as knowledge factor for authentication with the PID Provider and is discarded after every use - Description of the key derivation: - encryption of the PID PIN with an AES key bound to the device -> pin_secret - Used to generate a salt for the KDF used in the next step. - Could possibly be replaced by the generation & storage of a conventional salt (due to differences in AES in iOS/Android) - use of pin_secret and PID PIN in a KDF -> pin_seed - Generates a cryptographic secret from the PIN and the salt (pin_secret) for use as a seed for creating the key pair in the next step - use pin_seed to seed the EC key generation -> *pin_derived_eph_pub* and *pin_derived_eph_priv* 30. The Wallet signs over the nonce and the device-bound public key *device_pub* using the key *pin_derived_eph_priv* - This is a Proof of Knowledge (over the PID PIN) realized as a Proof of Possession - The nonce is `c_nonce` received in Token Response - The nonce and the *device_pub* key are included as JWT claims 31. The Wallet signs over the nonce and the PID PIN derived public key *pin_derived_eph_pub* using the key *device_priv* - This is a Proof of Possession over the device bound key - The nonce is `c_nonce` received in Token Response - The nonce and the *pin_derived_eph_pub* key are included as JWT claims - It contains audience, expiration time 32. The Wallet generates a new ephemeral keypair (*cre_eph_pub*, *cre_eph_priv*). 33. The Wallet creates the `credential_response_encryption` JSON object containing the following information: - a jwk containing the *cre_eph_pub* - the JWE alg parameter - the JWE enc parameter 34. The Wallet prepares the DPoP proof JWT for `dpop_pub` including the `dpop_nonce` and `iat` and signs it with *dpop_priv*. 35. The Wallet sends a Credential Request to the PID Provider for a newly defined credential format `seed_credential`; containing - the DPoP Header with proof - the DpoP-bound access token - PoP for *device_key* (in a `proof` parameter) - PoP for *pin_derived_eph_pub* containing *pin_derived_eph_pub* - the `credential_response_encryption` object 36. The Issuer validates the access token and DPoP proof 37. The PID Provider validates the PoPs for *pin_derived_eph* and *device_key*s 38. The PID Provider sets up the retry counter for the PID PIN and stores it with *pin_derived_eph_pub* under their identifier: hash(*device_pub*) 39. The PID Provider generates the Seed Credential with eID data, *device_pub* and signed by *pp_priv* 40. The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the Seed Credential JWT to the payload. 41. The PID Provider sends the Credential Response JWT; containing: - Seed Credential as JWT 42. The Wallet decrypts the Credential Response JWT using the *cre_eph_priv* and retrieves the Seed Credential JWT. 43. The Wallet stores the Seed Credential. ### PID Presentation #### PID Presentation Sequence Diagram [User Journey: PID Presentation - Authenticated Channel - Cloud](../../../user_journeys/PID-AuthenticatedChannel-cloud-presentation.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title PID presentation over OpenID4VP and On-the-fly PID Issuance over OpenID4VCI with SD-JWT actor u as "User\nOpenID Holder" participant b as "Browser App\n(same device)" participant v [ Relying Party ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ] participant w [ User's EUDI Wallet Instance\ (eID-Client) ---- ""Device Key: (//device_pub//, //device_priv//)"" ""PIN Salt: //pin_salt//"" ] participant i [ PID Provider (eService+eID Server) ---- ""Long-term Key: (//pp_pub//, //pp_priv//)"" ] u --> b : browse to application hnote over b #dfd: Screen: same_device_relying_party_start b -> v : tls() HTTP GET v -> v : generate ephemeral key pair (//rp_eph_pub//, //rp_eph_priv//) note left: every RP in the ecosystem must always include ephemeral key in client metadata for ECDH-KA for MAC v -> v : create OpenID4VP Authorization Request,\n sign with //rp_priv//,\n store under note left: Authorization Request includes:\n- presentation_definition\n- purpose\n- state\n- nonce\n- //rp_eph_pub// with PoP bound to client_id\n- response_uri v -> v : generate new browser session session_id and bind the authorization request to it v -> b : tls() HTTP 200 HTML containing wallet-link openid4vp://authorize?")\nclient_id=..&request_uri=\nSet-Cookie: sid=session_id u --> b : action to start flow/launch wallet b -> w : launch with wallet-link openid4vp:// note right #fc7: Potential security risk: Wallet app may be spoofed by malicious app hnote over w #dfd: Screen: launch_wallet u --> w : unlock wallet note right: may be moved to later point in flow or removed, see notes. hnote over w #dfd: Screen: unlock_wallet w -> v : tls() HTTP GET note right #fc7: Potential privacy risk: RP learns existence of wallet app and potentially identifying information (e.g., headers) v -> w : tls() HTTP 200 w -> w : validate Authorization Request JWT using //rp_pub// note right: //rp_pub// can be retrieved from metadata using the RP client_id u <--> w : user consent to present PID to Relying Party for given purpose hnote over w #dfd: Screen: consent_present_credential w -> i : tls() HTTP POST PID issuer session id i -> i : generate and store pid_issuer_session_id i -> w : tls() HTTP 200 w -> w: load PID seed credential from credential store u <--> w: enter PID PIN hnote over w #dfd: Screen: pid_pin w -> w : generate key pair (//pin_derived_eph_pub//, //pin_derived_eph_priv//) from KDF(encrypt_AES(//pin_salt//, PIN), PIN) w -> w : generate PoP for pin derived ephemeral key - sign(pid_issuer_session_id | //device_pub//)//pin_derived_eph_priv// w -> w : generate PoP for device_key - sign(pid_issuer_session_id | //pin_derived_eph_pub//)//device_priv// w -> w : Wallet fetches fresh wallet attestation from Wallet Backend and generates PoP with pid_issuer_session_id group on demand PID issuance group Generate initial DPoP nonce w -> w : generate placeholder DPoP proof with generic (not HSM-bound) key pair w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> w : tls() HTTP 400 note left : The Wallet should check at this point, whether the Token Endpoint delivered the expected error and nonce. If not, this needs to be handled (retry or abort gracefully). w -> w: store dpop_nonce end w -> w: prepare DPoP proof JWT with //dpop_pub//, dpop_nonce, iat and sign with //dpop_priv// w -> i : tls() HTTP POST note left: seed credential presentation serves as grant to get access token. new grant type (urn:ietf:params:oauth:grant-type:seed_credential) is defined in this document. note right: the seed credential + PoP (PoP for pin derived ephemeral key + PoP for device_key) is used to authenticate with the PID issuer and convey the user data required to generate the actual PID i -> i : verify wallet attestation & PoP \ncheck Wallet Provider solution status on trust list i -> i: load pin retry counter and //pin_derived_eph_pub// for hash(//device_pub//) i -> i: check user pin retry note left: request would be refused in case of locked pin i -> i: check signatures note left: user pin retry counter would be increased in case of failed pin signature check, user pin would be locked after threshold is exeeded i -> i: store user data from seed PID in session i -> i: generate and store dpop_nonce i -> i: generate TokenResponse with DPoP-bound access token i -> w : tls() HTTP 200 Token Response(DPoP-nonce Header with dpop_nonce, DPoP-bound access_token, c_nonce) w -> w : generate credential response encryption key pair (//cre_eph_pub//, //cre_eph_priv//) w -> w : create credential_response_encryption object with jwk containing //cre_eph_pub// w -> w: prepare DPoP proof JWT with //dpop_pub//, dpop_nonce, iat and sign with //dpop_priv// alt #ddf B.1.1: ISO mdoc w -> w : calculate SessionTranscript(mDocGeneratedNonce, clientId, responseUri, nonce provided by the Verifier in the presentation request) w -> i : tls() Credential Request (DPoP header with proof, DPoP-bound access token, //rp_eph_pub//, credential_response_encryption object, SessionTranscript) note right: -//rp_eph_pub// is sent in `verifier_pub` parameter\n-SessionTranscript is sent in `session_transcript` parameter\n-no `proof`/`proofs` parameters i -> i : generate device key pair (//pp_eph_pub//, //pp_eph_priv//),\n create issuerAuth with //pp_eph_pub// and w/o data items\n and sign with //pp_priv// else #dfd B.1.2: SD-JWT VC w -> w : generate ephemeral key pair for KB-JWT (//kb_eph_pub//, //kb_eph_priv//) and sign nonce w -> i : tls() Credential Request (DPoP header with proof, DPoP-bound access token, //rp_eph_pub//, credential_response_encryption object, //kb_eph_pub//) note right: //rp_eph_pub// is sent in `verifier_pub` parameter i -> i : generate issuer key pair (//pp_eph_pub//, //pp_eph_priv//),\n create certificate for chain with //pp_eph_pub// as x5c header and sign with //pp_priv// end i -> i : perform DH key exchange with //rp_eph_pub// and //pp_eph_priv//,\n generate shared secret k\nand derive MAC key for PID note over i: ECDH-MAC not specified for JOSE yet note over i #AAFFAA: SD-JWT is HMAC'd, not signed alt #ddf B.1.1: ISO mdoc i -> i : create deviceAuth using MAC key with eID data and SessionTranscript provided by the Wallet i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i --> w : tls() HTTP 200 JWT(Credential Response(mdoc)) w -> w : decrypt credential response JWT and retrieve PID else #dfd B.1.2: SD-JWT VC i -> i : - create SD-JWT with eID data, include //kb_eph_pub// and x5c with //pp_eph_pub//, HMAC using MAC key i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i --> w : tls() HTTP 200 JWT(Credential Response(SD-JWT + Disclosures)) note right: SD-JWT contains no KB-JWT w -> w : decrypt credential response JWT and retrieve PID w -> w : Assemble SD-JWT with respective disclosures and create KB-JWT payload with nonce, audience, and hash of SD-JWT and selected disclosures and sign with //kb_eph_priv// end end w -> w : create vp_token and presentation_submission w -> w : add mDL presentation according to with to vp_token and presentation_submission note left #AAFFAA: Wallet may add presentations with keys under its own control as the \ncommunication channel between Relying Part and PID Provider is not E2EE w -> v : tls() HTTP POST encrypted v -> v : look up state in existing sessions\ncreate & store response_code for session v --> w : tls() HTTP 200 w -> b : launch browser with hnote over w #dfd: Screen: success_redirect b -> v : tls() HTTP GET \nCookie: sid=session_id v -> v : look up session with session_id and match response_code v -> v : perform DH key exchange with //rp_eph_priv// from session and //pp_eph_pub//,\n generate shared secret k\n derive MAC key alt #ddf B.1.1: ISO mdoc v -> v : verify contents of :\n- verify mdoc issuerAuth/deviceAuth PID with MAC key\n- calculate and validate correct SessionTranscript else #dfd B.1.2: SD-JWT VC v -> v : verify contents of :\n- verify SD-JWT PID with MAC key\n- verify KB-JWT with //kb_eph_pub// from SD-JWT\n- validate nonce and audience from KB-JWT end v --> b : tls() HTTP 200 hnote over b #dfd: Screen: same_device_relying_party_identified @enduml ``` #### PID Presentation Step-by-Step Description Note: While certain assumptions about session management of the Relaying Party are made here, the concrete implementation is considered out of scope for this document. The usual security considerations for web session management apply. 1. User browses to Relying Party (RP) website 2. Browser app on the user's device opens the RP website 3. RP generates a key pair to be used for ECDH key agreement for SD-JWT HMAC'ing 4. RP generates an OpenID4VP Authorization Request and stores it under a `request_uri` (e.g., `https://rp.example.com/oidc/request/1234`); - The request is bound to the user's browser session - It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id - It contains the ephemeral key for ECDH key agreement for SD-JWT HMAC'ing - It contains RP's nonce and state - It contains the RP's response_uri endpoint for sending the Authorization Response over POST 5. RP generates a new browser session and binds the generated Authorization Request to it 6. RP returns a HTML page to the browser containing a link to the wallet app (e.g., `openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234`); a cookie with the browser session id is set 7. The user clicks on the link 8. The RP website navigates to the custom scheme link to launch the wallet app 9. The user unlocks the wallet app (see notes below) 10. The wallet app retrieves the Authorization Request from the RP website (e.g., `https://rp.example.com/oidc/request/1234`) 11. The wallet app receives the Authorization Request 12. The wallet app validates the Authorization Request using the RP's public key - Was the signature valid and the key bound to the RP's metadata? - **Security:** This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP. 13. The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the PID. 14. The Wallet requests a fresh PID issuer session id from the PID Provider (pid_issuer_session_id) 15. The PID Provider generates a fresh session id linked to the session 16. The PID Provider returns the PID issuer session id to the Wallet 17. The Wallet loads the PID seed credential from the credential store 18. The User enters the PID PIN 19. The Wallet generates the key pair (*pin_derived_eph_pub/priv*) derived from the PID PIN - See PID Seed-Credential Issuance Steps 20 to 22 for a detailed description of the authentication process 20. The Wallet signs over the PID issuer session id and the device-bound public key *device_pub* using the key *pin_derived_eph_priv* 21. The Wallet signs over the PID issuer session id and the PID PIN derived public key *pin_derived_eph_pub* using the key *device_priv* 22. The Wallet fetches fresh wallet attestation from the Wallet Provider backend, generates proof of possession PoP (incl. PID issuer session id) 23. The Wallet generates (and stores) a placeholder DPoP proof with a generic (not HSM-bound) keypair to trigger an error response from the Token endpoint necessary to retrieve the `dpop_nonce`. 24. The Wallet sends a Token Request to the PID Provider, containing the placeholder DPoP proof JWT. 25. The PID Provider generates and stores a `dpop_nonce`. 26. The PID Provider responds with the expected error "use_dpop_nonce", containing the `dpop_nonce` to be used from now on in the DPoP nonce header. 27. The Wallet extracts and stores the `dpop_nonce`. 28. The Wallet now prepares the actual DPoP proof JWT for `dpop_pub` including the `dpop_nonce` and `iat` signed with *dpop_priv*. 29. The wallet sends a Token Request to the PID Provider; containing - PoP for *pin_derived_eph* key - PoP for *device_key* - Seed Credential (bound to *device_pub*) - Wallet Attestation + PoP (incl. pid_provider_session_id) - a DPoP key - grant_type (urn:ietf:params:oauth:grant-type:seed_credential) - seed credential + Wallet attestation PoP (both bound to the same key) - PoP for *pin_derived_eph* and *device_key* serves as grant to get access token. New grant type (urn:ietf:params:oauth:grant-type:seed_credential) is defined in this document. 30. The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list 31. The PID Provider loads the retry counter and *pin_derived_eph_pub* with the identifier hash(*device_pub*) 32. The PID Provider checks the users PID PIN retry counter - If the PIN retry counter has exceeded the defined maximum value, the request is rejected 33. The PID Provider validates the PoP for *pin_derived_eph* and *device_key* 34. The PID Provider stores the user data from the PID seed credential in the session 35. The PID Provider generates and stores a `dpop_nonce`. 36. The PID Provider generates a TokenResponse with a DPoP-bound access token 37. The PID Provider sends a Token Response; containing - DPoP-bound access token - a c_nonce - a fresh `dpop_nonce` in the DPoP nonce header 38. The Wallet generates a new ephemeral keypair (*cre_eph_pub*, *cre_eph_priv*). 39. The Wallet creates the `credential_response_encryption` JSON object containing the following information: - a jwk containing the *cre_eph_pub* - the JWE alg parameter - the JWE enc parameter 40. The Wallet prepares the DPoP proof JWT for `dpop_pub` including the `dpop_nonce` and `iat` signed *dpop_priv*. 41. **(mdoc)** The Wallet calculates the SessionTranscript according to ISO-18013-7 Annex B.4.4 from mDocGeneratedNonce, client_id, responseUri, nonce (provided by the Verifier in the presentation request). The final result is a SHA-256 hash, thus not revealing the client_id and ResponseUri to the PID Provider. 42. **(mdoc)** The Wallet sends a Credential Request; containing - the DPoP-bound access token - SessionTranscript(mdocGeneratedNonce, client_id, responseUri, nonce) - the ephemeral RP key *rp_eph_pub* from the RP's Authorization Request - the `credential_response_encryption` object - it does not contain a "proof" 43. **(mdoc)** The PID Provider generate an ephemeral DeviceKey pair (*pp_eph_pub*,*pp_eph_priv*) and creates the mdoc issuerAuth (MSO) with the public part of DeviceKey and without the IssuerSignedItems and signs it with *pp_priv*. 44. **(SD-JWT)** The Wallet generates an ephemeral key pair for the KB-JWT (*kb_eph_pub*, *kb_eph_priv*) and signs the nonce 45. **(SD-JWT)** The wallet app sends the Credential Request to the PID Provider; containing - the DPoP-bound access token - the ephemeral RP key *rp_eph_pub* from the RP's authorization request - the `credential_response_encryption` object - the ephemeral KB-JWT key *kb_eph_pub* 46. **(SD-JWT)** The PID Provider generates the ephemeral issuer key pair (*pp_eph_pub*, *pp_eph_priv*) and creates a certificate for the chain with *pp_eph_pub* as x5c header and signs it with *pp_priv*. 47. The PID Provider performs DH key exchange with the ephemeral RP public key *rp_eph_pub* and the ephemeral issuer private key *pp_eph_priv*, generates a shared secret k and derives a MAC key for the PID. 48. **(mdoc)** The PID Provider creates the mdoc deviceAuth (using the MAC key) containing - the user claims - the OpenID4VP SessionTranscript(mdocGeneratedNonce, client_id, responseUri, nonce) - SessionTranscript used by the PID Provider is generated by the Wallet and is passed to the PID Provider in step 32, so PID Provider does not need to be aware of the values used to generate SessionTranscript 49. **(mdoc)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID credential to the payload. 50. **(mdoc)** The PID Provider sends the Credential Response JWT; containing: - PID as mdoc 51. **(mdoc)** The Wallet decrypts the Credential Response JWT using the *cre_eph_priv* and retrieves the PID. 52. **(SD-JWT)** The PID Provider creates the issuer-signed part of the SD-JWT (using the MAC key) containing - eID as the user claims - *kb_eph_pub* as cnf claim 53. **(SD-JWT)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID credential to the payload. 54. **(SD-JWT)** The PID Provider sends the Credential Response JWT; containing: - PID as SD-JWT VC - Disclosures 55. **(SD-JWT)** The Wallet decrypts the Credential Response JWT using the *cre_eph_priv* and retrieves the PID. 56. **(SD-JWT)** The Wallet assembles the SD-JWT with the selected disclosures and creates the header and payload for the KB-JWT from audience, nonce, and the hash of SD-JWT and selected disclosures and signs it with its generated *kb_eph_priv*. The Wallet appends the KB-JWT to the SD-JWT + Disclosures. 57. The wallet app creates a VP token and a presentation submission from the received SD-JWT PID. 58. Optional: The wallet app can add further presentations with keys under its own control as the communication channel between Relying Party and PID Provider is not E2EE 59. The wallet app sends the VP token and presentation submission to the RP (encrypted to the RP's public key *rp_eph_pub*). 60. The RP finds a session with the state and generates a response_code for this session 61. The RP returns the redirect_uri with the response_code to the wallet app 62. The wallet app launches the browser with the redirect_uri and response_code. 63. The browser sends the redirect_uri and response code to the RP, attaching the browser session id as a cookie. 64. The RP looks up whether there exists a session with the session id from the cookie and a matching response_code 65. Using the data from the session the RP performs DH key exchange with the PID Provider's public key, generates a shared secret k and derives a MAC key. 66. **(mdoc)** The RP verifies the PID in the VP token with the MAC key and verifies the SessionTranscript. 67. **(SD-JWT)** The RP verifies the SD-JWT PID in the VP token with the MAC key, verifies the KB-JWT using the *kb_eph_pub* in the SD-JWT, and verifies the nonce and audience in the KB-JWT 68. The RP considers the user to be identified in the session context and continues the UX flow. ## Extensions to the Protocols This section defines extensions to the protocols required to implement this flow (Option B'). In this document, the term `RP` has been used, but this since this section is an extension to an OpenID4VCI protocol, a term from that specification is being used, which is `verifier`. ### Issuer Session Endpoint (at the PID Provider) Note that this extension is the same across multiple flows. This endpoint is used by the Wallet to obtain `session_id` from the PID Provider that is used to bind PoPs to the session and prove their freshness. Support for this endpoint is REQUIRED. To fetch the `session_id`, the Wallet MUST send an HTTP request using the POST method and the `application/json` media type. The PID Provider MUST return the HTTP Status Code 200 and a `session_id` parameter defined below. - `session_id`: REQUIRED. String that is a unique session identifier, chosen as a cryptographically random nonce with at least 128 bits of entropy. Communication with the Session Endpoint MUST utilize TLS. Below is a non-normative example of a request to a Session Endpoint: ```http POST /session_endpoint HTTP/1.1 Host: server.example.com Content-Type: application/json ``` Below is a non-normative example of a response from a Session Endpoint: ```http HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "session_id": "iOiJSUzI1NiIsInR" } ``` ### OpenID4VCI Credential Issuer Metadata Note that this extension is the same across multiple flows. This document defines the following additional Credential Issuer Metadata parameters: - `session_endpoint`: REQUIRED. URL of the Credential Issuer's Session Endpoint, as defined in a previous section. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. ### OpenID4VCI Credential Request for Seed Credential Issuance This section defines a Credential Format Profile for a Seed Credential. The Credential Format identifier is `seed_credential`. The following Credential Format specific parameter must be included in the Credential Request to issue a seed credential of this format: - `pin_derived_eph_key_pop`: A string containing a JWT which is generated by the Wallet signing over the `nonce` (`c_nonce` received in Token Response) and the device-bound public key `device_key` parameters using the `pin_derived_eph_priv` key. A PIN-derived ephemeral public key that is needed to validate the signature on this JWT must be included in the `jwk` header parameter. The JWT header must contain a `typ` key with the value being `pin_derived_eph_pub_pop`. The JWT payload must contain an `aud` claim whose value is equal to the PID Provider's Credential Issuer Identifier. Either a `proof` parameter or a `proofs` parameter containing one proof must be present. Proof type must be `jwt`. A proof MUST be a JWT which is generated by the Wallet signing over the `nonce` (`c_nonce` received in Token Response) and the `pin_derived_eph_pub` using the `device_key`. A `device_pub` key that is needed to validate the signature on this JWT must be included in the `jwk` Header parameter. Below is a non-normative example of a Credential Request during Seed Credential issuance: ```json POST /credential HTTP/1.1 Host: server.example.com Content-Type: application/json Authorization: DPoP czZCaGRSa3F0MzpnWDFmQmF0M2JW DPoP: ey… { "format": "seed_credential", "pin_derived_eph_key_pop": "eyJ0eX...Lh1WlA", "proof": { "proof_type": "jwt", "jwt": "eyJraW...KPxgihac0aW9E" }, "credential_response_encryption": { "jwk": { "kty": "EC", "crv": "P-256", "x": "Q71r9rep9wGjorxnnTrxzrN6CxJTc_0vucTkAQSFSzM", "y": "jh7gtLKEMH2PQ6hz2USSvsMAvhyF90OBScZ9KJ-1Z-o" }, "alg": "ECDH-ES", "enc": "A256GCM" } } ``` Below is a non-normative example of a JWT sent in a `pin_derived_eph_key_pop` parameter used as a PoP for pin derived ephemeral key during Seed Credential issuance: ```json { "alg": "...", "typ": "pin_derived_eph_key_pop", "jwk": { "kty": "EC", "crv": "P-256", "x": "bPP7f...gW_ao", "y": "38_Lg...VUCfW" } }. { "nonce": "123456", "aud": "https://pid-issuer.example.com", "device_key": { "jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." } } }.[signature by the pin derived ephemeral pub key] ``` The `jwk` claim contains the public key of a PIN-derived ephemeral key pair. Below is a non-normative example of a JWT used as a proof during Seed Credential issuance, which is a PoP for `device_key`: ```json { "alg": "...", "typ": "openid4vci-proof+jwt", "jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." } }. { "nonce": "123456", "pin_derived_eph_pub": { "jwk": { "kty": "EC", "crv": "P-256", "x": "V03QP...LHN53", "y": "xjilK...i0_tT" } }, "aud": "https://pid-issuer.example.com", "iat": 1701960444 }.[signature by the device_key] ``` Here, the `jwk` claim contains a public key of a device key pair. The payload contains `aud` and `iat` claims and the header contains `alg` and `typ` claims, which is a requirement for `jwt` proof type as defined in OpenID4VCI specification. Below is a non-normative example of a Credential Response JWT (JWE) during the during Seed Credential issuance:: ```json HTTP/1.1 200 OK Content-Type: application/jwt Cache-Control: no-store { "epk": { "kty": "EC", "crv": "P-256", "x": "GNIg9Vdq4gytYyVsANPZGtS_eKWjjWJQYDGaM1olFZI", "y": "Vjk0mlZD_CwXrtIJkPH-ZzdwqJp3QBRVp83pEeQUDC0" }, "enc": "A256GCM", "alg": "ECDH-ES" }.. 3tQxSrYcfmbEWw-Y. yp9e0Kh0THo498bg5nnUIpkS-CwxlS8i6G9RfZBOzUOeohaVnAPAWHY. PhU-FNmCt_ZZPzj5RgPNmQ ``` The decrypted payload of the Credential Response JWT example results in the following structure: ```json { "credential": "" } ``` ### OpenID4VCI Token Request for PID Issuance using Seed Credential A new grant type `urn:ietf:params:oauth:grant-type:seed_credential` is defined by this document. The following parameters must be included in the Token Request: - `seed_credential`: A string containing a JWT that is a previously issued seed credential. - `pin_derived_eph_pub_pop`: A string containing a JWT which is generated by the Wallet signing over the `pid_issuer_session_id` and the device-bound public key `device_key` parameters using the `pin_derived_eph_priv` key. A PIN-derived ephemeral public key that is needed to validate the signature on this JWT must be included in the `jwk` header parameter. There must be a JWT header parameter `typ` with the value being `pin_derived_eph_pub_pop`. The JWT payload must contain an `aud` claim whose value is equal to the PID Provider's Credential Issuer Identifier. - `device_key_pop`: A string containing a JWT which is generated by the Wallet signing over the `pid_issuer_session_id` and the device-bound public key `pin_derived_eph_pub` parameters using the `device_priv` key. A device public key that is needed to validate the signature on this JWT must be included in the `jwk` header parameter. There must be a JWT header parameter `typ` with the value being `device_key_pop`. The JWT payload must contain an `aud` claim whose value is equal to the PID Provider's Credential Issuer Identifier. Below is a non-normative example of a Token Request during the PID issuance (including DPoP and wallet attestation): ```http POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded DPoP: ey... OAuth-Client-Attestation: ey... OAuth-Client-Attestation-PoP: ey... grant_type=urn:ietf:params:oauth:grant-type:seed_credential &seed_credential=ey... &pin_derived_eph_key_pop=ey... &device_key_pop=ey... ``` Note: `client_id` will be present instead of OAuth-Client-Attestation and OAuth-Client-Attestation-PoP headers used to pass wallet attestation, when wallet attestation is not used. Below is a non-normative example of a JWT sent in a `pin_derived_eph_key_pop` parameter used as a PoP for pin derived ephemeral key during PID issuance: ```json { "alg": "...", "typ": "pin_derived_eph_key_pop", "jwk": { "kty": "EC", "crv": "P-256", "x": "bPP7f...gW_ao", "y": "38_Lg...VUCfW" } }. { "pid_issuer_session_id": "123456", "aud": "https://pid-issuer.example.com", "device_key": { "jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." } } }.[signature by the pin derived ephemeral pub key] ``` The `jwk` claim contains the public key of a PIN-derived ephemeral key pair. Below is a non-normative example of a JWT used as a proof during PID issuance, which is a PoP for `device_key`: ```json { "alg": "...", "typ": "device_key_pop", "jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." } }. { "pid_issuer_session_id": "123456", "aud": "https://pid-issuer.example.com", "pin_derived_eph_pub": { "jwk": { "kty": "EC", "crv": "P-256", "x": "V03QP...LHN53", "y": "xjilK...i0_tT" } }, }.[signature by the device_key] ``` Here, the `jwk` claim contains a public key of a device key pair. ### OpenID4VCI Credential Request and Response for PID Issuance in mdoc Credential Format using Authenticated Channel Note that this section is the same as in Option B. Credential Format identifier is `mso_mdoc_authenticated_channel`. The following parameters are defined in addition to those defined for the Credential Format `mso_mdoc` in Annex A.2 of OpenId4VCI: - `session_transcript`: REQUIRED. String that is a base64url encoded SessionTranscriptBytes as defined in Section 9.1.5.1 of ISO 18013-5. - `verifier_pub`: REQUIRED. A JSON object as defined in Section 2 of RFC7591. It contains the ephemeral RP key *rp_eph_pub* from the RP's Authorization Request. `proof` or `proofs` parameter MUST NOT be present. DPoP-bound Access token MUST be present. `credential_response_encryption` parameter MUST be present. Note: The wallet can find out about the supported cryptographic algorithms by using the Issuer's metadata parameter `credential_response_encryption`. Below is a non-normative example of a Credential Request during the PID issuance in ISO mso Credential Format over Authenticated Channel: ```json POST /credential HTTP/1.1 Host: server.example.com Content-Type: application/json Authorization: DPoP czZCaGRSa3F0MzpnWDFmQmF0M2JW DPoP: ey… { "format": "mso_mdoc_authenticated_channel", "doctype": "org.iso.18013.5.1.mDL", "session_transcript": "...", "verifier_pub": { "kty": "EC", "crv": "P-256", "x": "aPPK-...2-Drn", "y": "FqJqG...ksKHp" }, "credential_response_encryption": { "jwk": { "kty": "EC", "crv": "P-256", "x": "1SptQyCUQiQD3dBcVHTclxRtcqhZlF1rIKcBR-i_WK4", "y": "8ayoQrh52zNuRQx8Q0gpmCpOjzbH397mOsaSi8X10c4" }, "alg": "ECDH-ES", "enc": "A256GCM" } } ``` `credential` parameter in the Credential Response MUST contain a base64url-encoded `Document` which contains `IssuerSigned` and the `DeviceSigned` parameters defined in section 8.3.2.1.2.2 of 18013-5. The Device key included in the `IssuerSigned` and used to secure `DeviceSigned` is generated by the PID Provider, and not by the Wallet as defined in ISO 18013-5. SessionTranscript used by the PID Provider when calculating `DeviceSigned` is calculated by the Wallet. Therefore, there is no need for the PID Provider to know the specific values of `mdocGeneratedNonce`, `client_id`, `responseUri`, and `nonce` parameters used for SessionTranscript calculation by the Wallet. Moreover, there is also no way for the PID Provider to reconstruct these values, as the SessionTranscript is hashed and contains random values chosen by the wallet (i.e. `mdocGeneratedNonce`). Below is a non-normative example of a Credential Response JWT (JWE) during the PID issuance in mso Credential Format over Authenticated Channel: ```json HTTP/1.1 200 OK Content-Type: application/jwt Cache-Control: no-store { "epk": { "kty": "EC", "crv": "P-256", "x": "VJUVl-ZqLKzzncZ4Gs_nJfcqY_YBHPkGVN0sRSlF-3s", "y": "y4maAWKte676d0wL6um-8wAUJ9pW-mlc528BFeiXn2Y" }, "enc": "A256GCM", "alg": "ECDH-ES" }.. nLuW9PwrGl76pjTy. nH_XE2LJ2u-N0o8M-tanqoYhJr7hbjo. 3uNrPqJazT9ZSf54sk1Ueg ``` The decrypted payload of the Credential Response JWT example results in the following structure: ```json { "credential": "..." } ``` ### OpenID4VCI Credential Request and Response for PID Issuance in SD-JWT Credential Format using Authenticated Channel Note that this section is the same as in Option B. The following parameter is defined in addition to those defined for the Credential Format `dc+sd-jwt` in Annex A.3 of OpenId4VCI: - `verifier_pub`: REQUIRED. A JSON object as defined in Section 2 of RFC7591. It contains the ephemeral RP key *rp_eph_pub* from the RP's Authorization Request. New Credential Format identifier is not defined PID Issuance in SD-JWT Credential Format using Authenticated Channel, because the issued Credential in the Credential Response is SD-JWT, which is the same as the one defined in Annex A.3 of OpenId4VCI. Since during PID Issuance in SD-JWT Credential Format using Authenticated Channel, not just `IssuerSigned`, but also `DeviceSigned` is returned in the Credential Response as part of the `Document` structure as defined above, it is a significant deviation that necessitated the definition of a new Credential Format identifier `mso_mdoc_authenticated_channel`. `credential_response_encryption` parameter MUST be present. Note: The wallet can find out about the supported cryptographic algorithms for the credential response encryption by using the Issuer's metadata parameter `credential_response_encryption`. Below is a non-normative example of a Credential Request during the PID issuance in IETF SD-JWT VC Credential Format over Authenticated Channel: Note: The wallet can find out about the supported cryptographic algorithms by using the Issuer's metadata parameter `credential_signing_alg_values_supported`. ```json POST /credential HTTP/1.1 Host: server.example.com Content-Type: application/json Authorization: DPoP czZCaGRSa3F0MzpnWDFmQmF0M2JW DPoP: ey… { "format": "dc+sd-jwt", "vct": "SD_JWT_VC_example", "proof": { "proof_type": "jwt", "jwt": "eyJ0e...h1WlA" }, "verifier_pub": { "kty": "EC", "crv": "P-256", "x": "aPPK-...2-Drn", "y": "FqJqG...ksKHp" }, "credential_response_encryption": { "jwk": { "kty": "EC", "crv": "P-256", "x": "1SptQyCUQiQD3dBcVHTclxRtcqhZlF1rIKcBR-i_WK4", "y": "8ayoQrh52zNuRQx8Q0gpmCpOjzbH397mOsaSi8X10c4" }, "alg": "ECDH-ES", "enc": "A256GCM" } } ``` ## Implementation Considerations - The JWA to use the x5c in the SD-JWT and perform ECDH key agreement and derive the MAC key is to be defined. ## Usability Considerations ### Initialization - The wallet can only be used after successful initialization ### Issuance - Credential catalogue should inform users in advance of what is required for the successful issuance of the PID and what steps follow - For reasons of transparency and to increase trust, PID Provider should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the PID Provider itself - eID process is integrated in Wallet. No context switch to the AusweisApp is requiredPhysical ID card is required for issuing the PID seed credential - Online-Ausweisfunktion must be activated - eID PIN must be set by the user (replacement of the Transport PIN) and be known to them so that they can successfully confirm the process - User can have a PID seed credential derived from the eID on several end devices at the same time - A PID-specific PIN must be set. The distinction between eID PIN and PID PIN is certainly not easy for users and must be communicated accordingly - In addition to the PID-specific PIN, several PINs will probably be required to use the wallet (especially for LoA High Credentials). This will also require multiple error counters. This can lead to user confusion, unnecessary complexity and ultimately friction ### Presentation - The device must be online for the PID presentation - Relying Party should inform users in advance of what is required for the process to be completed successfully and what steps follow - It needs to be clarified whether the wallet app needs to be unlocked in this flow and how this should be implemented. - For reasons of transparency and to increase trust, Relying Parties should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the relying party itself, privacy and data retention - The user's data values for the requested attributes can be displayed on the consent screen - The user only needs to enter the PID PIN for each PID presentation - Physical ID card is not required for PID presentation - It must be ensured that users return to the correct tab in the correct browser in order to continue the process or know how to get there manually if necessary (especially for iOS devices, if the process was not started in the default browser) ## Security Considerations - It is to be discussed whether the setting of the PID PIN should be more closely linked to the eID process. In this case, the public keys and PoPs required for the PID PIN check could be transferred as an additional attribute in the eID process. - In Step 8 of the presentation, a malicious app may spoof the wallet app by registering to the same custom URL scheme; an attacker may - **on the attacker's own device:** Capture the request and replay it to a victim on another device, thus having the victim identify itself in a context of the attacker (**Relaying Attack breaking Identification Context**); or - **on the victim's device:** Capture the request and spoof the whole identification process or parts of it (**Wallet App Spoofing**). - In Step 10 of the presentation: An attacker acting as an RP can forward a request from a different RP. - As long as the request remains unchanged, we're in the **Relaying Attack breaking Identification Context** - If the attacker changes anything in the request, this will break the signature. The attacker could otherwise attempt to - insert the attacker's own ephemeral key, leading to an SD-JWT artifact that could be used in a different flow between the attacker and some other RP. - modify state or nonce or other data. **Q:** Any useful attacks resulting from this? - In Step 46 of the presentation: The RP must not consider the user identified at this point; it is important to have the browser redirect in the later steps. - In Step 11 and onward of the PID Seed Credential issuance: Security of PID Provider Interface: - Are additional steps required to protect the interface to the PID Provider? - What exactly is the transaction binding? - How is the eID process tied to the process at the PID Provider? ## Privacy Considerations - Due to the differences in the selective disclosure process of SD-JWT VC and mDoc, it is only possible with the SD-JWT variant to prevent the PID Provider from knowing which attributes are to be disclosed to a relying party. - An initiating step before the authorization request (Step 10 of the presentation) that is performed without the user's interaction might leak information about the user's device to the RP (**Initial Request Privacy Leak**). For example: - the fact that the wallet app is installed, - the fact which wallet app is installed, - some metadata about the wallet app contained in request headers (e.g., version, language, etc.), - network information if the browser uses a VPN but the wallet app does not - Unlinkability: Each Relying Party sees a new credential for each use of the flow. Only ephemeral keys are used. Unless the eID data itself enables linkability, there is no information enabling linkablility between different uses of the flow. --- ## PID Option B: Authenticated Channel with eID Card (B) with mDoc, ISO REST API !!! note this flow is currently not being actively maintained. ## Basic Idea Presentation of PID and QEAAs (EAAs) reusing the entire System for German eID or Smart-eID for PID. The protocol is based on ISO standards ISO 18013-5/-7 and ISO 23220 and has two options for QEAA handling: 1. get PID and QEAA in one shot (request/response) 2. get PID and QEAA independent of each other (multiple requests/responses) ## Cryptographic Formats Long-Term keys: * PID Provider has long-term key pair $(pp\_pub, pp\_priv)$ that can be verified using $x5chain$ * RP has long-term key pair $(rp\_pub, rp\_priv)$ Transaction-specific keys: * **RP contribution to HMAC key:** RP generates ephemeral key pair $(rp\_eph\_pub, rp\_eph\_priv)$ * **PID Provider contribution to HMAC key:** PID provider generates ephemeral device key pair $(dev\_eph\_pub, dev\_eph\_priv)$ for each request Artifacts: * $issuerAuth := \text{sign}(dev\_eph\_pub, x5chain)_{pp\_priv}$ * $hmac\_key := \text{ecdh}(rp\_eph\_pub, dev\_eph\_priv)$ * $deviceAuth := \text{hmac}(\mathit{eID\_data}, \mathit{SessionTranscript})_{hmac\_key}$ ## Sequence Diagram [User Journey: PID Presentation - Authenticated Channel - eID Card](../../../user_journeys/PID-AuthenticatedChannel-eIDcard-presentation.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 actor User participant "Browser App\n(same device)" as IB participant WS [ Relying Party ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ""for Reader Authentication:"" ] participant MDOC as "User's EUDI Wallet Instance\n(eID-Client)" participant IS [ PID Provider (eService+eID Server) ---- ""Long-term Key: (//pp_pub//, //pp_priv//)"" ""for mDoc Authentication (ECDH for HMAC):"" ] autonumber "(000)" User --> IB: browse \nto application hnote over IB #dfd: Screen: same_device_relying_party_start group start session acc. to ISO/IEC 23220-4 and ISO/IEC 18013-7 IB -> WS: tls() HTTP **GET** WS -> WS: create ISO-RestAPI-sessionID\nand ReaderEngagement note right ReaderEngagement contains: - ephemeral session keys for session encryption Reader.EDeviceKey.pub - referrer url incl. sessionID, e.g., https://relying-party-service.de/{uuid}/ - OriginInfo end note WS --> IB: tls() HTTP 200 \nparams("HTML with link to mdoc://base64(ReaderEngagement)") IB -> MDOC: mdoc:// \nparams("/base64(ReaderEngagement)") hnote over MDOC #dfd: Screen: launch_wallet activate MDOC User --> MDOC: user consent (unlock wallet) hnote over MDOC #dfd: Screen: unlock_wallet MDOC -> MDOC: generate ephemeral Session Keys\ncreate Device Engagement MDOC -> WS: tls() HTTP **POST** params("MessageData") note right MessageData contains - deviceEngagementBytes with - RetrievalMethod == RestAPI - ephemeral session key Wallet.EDeviceKey.pub - MacKeySupport := TRUE - MacKeyCurves := [] - OriginInfo.ReferrerURL := https://relying-party-service.de/{uuid}/ - OriginInfo.BaseURL := https://relying-party-service.de end note WS -> WS: validate OriginInfo.ReferrerURL and OriginInfo.BaseURL with OriginIfo from ReaderEngagement note left recognize MiTM attack end note WS -> WS: calculate mdoc_request for PID and mDL note left mdoc_request contains * ephemeral MacKeys Reader.MacKey.pub if DeviceEngagement requests Mac support * ReaderAuthentication :_= COSE_Sign1 with detached ReaderAuthenticationBytes (incl. SessionTranscript) end note WS -> WS: perform key agreement (Wallet.EDeviceKey.pub * EReaderKey.priv) and HKDF for S.key WS -> WS : SessionData := enc(S.key, mdoc_request) WS --> MDOC: tls() HTTP **200** params("SesssionData") MDOC -> MDOC: perform key agreement (EDeviceKey.priv * Reader.EReaderKey.pub) S.key MDOC -> MDOC: mdoc_request := dec(S.key, SesssionData) MDOC -> MDOC: calculate SessionTranscript MDOC -> MDOC: validate ReaderAuthentication note right Signature over detached ReaderAuthenticationBytes (incl. SessionTranscript) ReaderAuthenticationBytes needs to be rebuilt for validation on Device side end note hnote over MDOC #dfd: Screen: consent_present_credential MDOC -> IS: tls() HTTP GET /tcToken params("Reader.MacKey.pub, SessionTranscript") note right #fc7: Security risk: No PoP for MacKey used here; can an attacker forward a MacKey from a different session to the PID Provider? activate IS hnote over MDOC #dfd: Screen: eid_start group Read eID or Smart eID acc. to BSI TR-03130 MDOC <-> IS : tlspsk() eID Process note left : only the required PID attributes are requested hnote over MDOC #dfd: Screen: eid_pin hnote over MDOC #dfd: Screen: eid_nfc_data IS -> IS: store eID data end end group Prepare response for PID acc. ISO 18013-7 and ISO 23220-4 in mdoc format (REST-API) IS -> IS: generate MDoc-Device Key-Pair and create MSO with MDoc.EDeviceKey.pub but w/o data items note left the Device Key pair shall be generated within an HSM and will be referenced by the SessionID end note IS -> IS: perform key agreement (Reader.MacKey.pub * MDoc.EDeviceKey.priv) and HKDF for HMAC IS --> IS: calculate HMAC for DeviceAuth IS -> IS : create mDoc-Response from PID incl. DeviceAuth note over IS #AAFFAA: user data is not signed, but HMACd MDOC -> IS: tls() HTTP **GET** /pid note left #AAFFAA trust relation between wallet and PID-Provider needs to be defined, options are reuse existing TLS-PSK channel for mutual authentication or mTLS end note IS --> MDOC: tls() HTTP **200** params("mdoc-response") note over MDOC : optional: get QEAA MDOC -> MDOC: SessionData := enc(S.key, mdoc-response) MDOC -> WS: tls() HTTP **POST** params("SessionData") WS -> WS: perform key agreement (Reader.MacKey.pub * MDoc.EDeviceKey.priv) and HKDF for HMAC WS -> WS: mdoc _response := dec(S.key, SessionData) WS -> WS: verify HMAC for DeviveAuth in mdoc _response end group request addtional mDoc from wallet WS -> WS: SessionData := enc(S.key, mdoc-request) note left reuse S.key from step 011 end note WS --> MDOC : tls() HTTP 200 params("SessionData") WS -> WS: SessionData := enc(S.key, mdoc-request) note right: Question: This step should probably be something else? note left reuse S.key from step 011 end note MDOC -> WS: tls() HTTP **POST** params("SessionData") MDOC -> MDOC: SessionData := enc(S.key, mdoc-response) note left reuse S.key from step 014 end note WS --> MDOC: tls() HTTP **200** end deactivate MDOC note over WS TLS session from step 002 needs to be matched with ISO REST session (long polling, web sockets or similar). end note note over WS #FAA: Security risk: No protection against relaying requests yet (binding to browser session). hnote over MDOC #dfd: Screen: success_redirect hnote over IB #dfd: Screen: same_device_relying_party_identified @enduml ``` ## Step-by-Step Description User browses to Relying Party (RP) website 1. open the Browser app 2. request RP website within the Browser app 3. RP generates an ephemeral session key pair and a ReaderEngagement structure according to ISO 18013-7 annex A.1 4. ReaderEngagement contains: * the public ephemeral session key * an OriginInfo structure with a referrer-url incl. a REST-API sessionID, e.g., `https://rp.example.com/mdoc-reader/1234` 5. RP returns a HTML page to the browser containing a link to the wallet app (e.g., `mdoc://enc(base64,ReaderEngagement)`) * The user clicks on the link and the wallet will be launched * The wallet app retrieves the Authorization Request from the RP website (e.g., `https://rp.example.com/mdoc-reader/1234`) and the public ephemeral session key 6. The user might be asked for consent to unlock the wallet (needs to be discussed!) 7. RP generates an ephemeral session key pair and a DeviceEngagement structure according to ISO 18013-7 annex A.2 * DeviceEngagement indicates support of Mac keys for mDoc authentication * DeviceEngagement contains an OriginIfo structure. This value shall not be determined using data from the ReaderEngagement structure. 8. Wallet sends a CBOR encoded message data structure via HTTPS **POST** to the RP containing the DeviceEngagement structure 9. RP validates OriginInfo from DeviceEngagement with provided ReaderEngagement from step 2 10. RP calculates mDoc-request * just for PID or PID and QEAA (e.g., mDL) * mDoc-request contains items to request, public Reader Mac-key and ReaderAuthentication 11. RP performs ECDH key agreement and calculates the symmetric session key S.key 12. RP encrypts the mDoc-request with S.key 13. RP returns the mDoc-request to the wallet 14. wallet performs ECDH key agreement and calculates the symmetric session key S.key 15. wallet decrypts mDoc-request with S.key 16. wallet calculates SessionTranscript acc ISO 18013-7 A.8 17. wallet performs Reader Authentication 18. wallet starts eID-process if mdoc-request contains PID request 19. wallet performs eID process acc. TR 03124 20. PID-Provider stores eID data temporarily 21. PID-Provider generates mDoc authentication key pair and creates an MSO structure, this might also be done for one time, e.g., during service startup 22. optional: perform reading of additional QEAA's or EAA's by ruse of existing TLS-PSK channel 23. PID-Provider performs ECDH and HKDF for HMAC key 24. PID-Provider calculates HMAC for Device Authentication using the SessionTranscript 25. PID-Provider calculates mDoc-response * for PID and QEAA, if optional step 22. has been performed * just for PID, if optional step 22. has been omitted 26. wallet encrypts mDoc-response using session key S.key 27. wallet posts the mDoc-response to the RP 28. RP decrypts mDoc-response using S.key 29. RP performs ECDH and HKDF for HMAC key 30. RP verifies mDoc authentication 31. optional: RP calculates an additional mDoc-request 32. optional: RP returns additional mDoc-request to the wallet 33. optional: Wallet encrypts mdoc-response 34. wallet posts mdoc-response to RP 35. RP ends the session ## Implementation Considerations *TBD* ## Usability Considerations The user expects a simple and intuitive user interface with the same or similar user experience as for other security-critical applications such as banking apps. That means, that the entire session will be performed within the same instance of a browser window or tab. This applies in particular for the same-device flow as well as for the cross-device flow. For both flows, the user starts the session by requesting the website in step 002 and expects to get the result in the same browser window or tab. Step 005 might be a deep link within a website behind a button for the same device flow or a qr-code with identical information `mdoc://enc(base64,ReaderEngagement)` for the cross-device flow. At the end of the session the content of the browser window or tab from step 004 needs to be updated. To achieve this, at least 2 options are available: 1. using long polling 2. using websockets with notifications The cross-device flow is mandatory for EUID wallet according to document "EUDIW Design Guide_Data Sharing Scenarios-v1.00_clean.doc". * Unlock wallet (Step 006) should probably be moved to a later point in the flow, ideally just before using the credential. ## Security Considerations **SessionTranscript:** "Device Retrieval" with remote CA keys is defined by the ISO standards 18013-7 and 23220-4. The SessionTranscript is used within the authentication structure for the reader mDoc-request (ReaderAuthentication) and the authentication structure for the mDoc-response structure (DeviceAuthentication). The aim is the cryptographical binding of the data exchange protocol (request/response) with the underlying transport protocol REST-API. The SessionTranscript shall be created independently on each site of the communication channel. * The SessionTranscript structure contains a ReaderEngagementHashBytes structure calculated using SHA256( ReaderEngagementBytes ) where ReaderEngagement contains the ephemeral RP public key (EReaderKeyBytes) and the URI of the RP website(TestApiOptions). * The hashing of ReaderEngagementBytes prevents the leakage of session information from the Relying Party to the PID-Provider, for privacy reasons. **Cross-device Flow** is mandatory for the EUID wallet. The proposed user flow as discussed in Usability Considerations (above) does not solve the problem of session hijacking by an attacker. Compared to the user experience to banking apps in combination with banking services, the RP does not know the wallet. **Proof of Possession (PoP)** requires a kind of key attestation, which is not yet defined. ## Privacy Considerations * Selective Disclosure is achieved by ensuring that the credential contains only those data items (claims) that are requested by the RP. The list of requested claims is part of the request to the PID Provider. --- ## PID Option B: Authenticated Channel with eID Card ## Basic Idea This flow describes a flow that issues PID credentials in ISO mdoc / SD-JWT VC format on-demand when the presentation request is received. It uses the OpenID4VCI protocol for issuance and the OpenID4VP protocol for presentation. The PID credentials are HMAC'd by the PID Provider for the specific transaction. The Wallet Instance is not trusted for the management of the keys, hence majority of the signing is performed by the PID Provider. ## Lifecycle The credential is created on-demand by the PID Provider, i.e., a new credential is created for every transaction. The credential is not stored in the wallet. It is bound to the specific transaction through not only the nonce and audience, but also the symmetric key used for HMAC'ing, which is derived from ephemeral keys of the RP and PID Provider. ## Credential formats Two solutions are described: - **ISO mdoc:** The ISO mdoc credential format is used with: - issuerAuth as issuer data authentication, a COSE_Sign1 signature over the MobileSecurityObject (see ISO 23220-4 7.1.3.4.2.1) signed by the PID Provider - no signed hashes are transmitted, i.e., `digestAlgorithm` and `valueDigests` are omitted - deviceMAC as mdoc authentication method, a COSE_Mac0 MAC over the deviceAuthentication data (see ISO 18013-5 9.1.3.5) signed by the PID Provider - containing the PID data - **SD-JWT VC:** The SD-JWT VC credential format is used with: - SD-JWT issued by the PID Provider, a JOSE JWS with MAC key derived from ECDH* and signed by the PID Provider - containing the hashes of PID data - the Wallet provides an ephemeral, asymmetric key to the PID Provider for the key binding - KB-JWT issued by the Wallet, a JOSE JWS using digital signature and signed by the Wallet - containing nonce and audience of the Relying Party - containing a hash of the SD-JWT and the selected disclosures - the Disclosures - containing the PID data The establishment of the authenticated channel is defined: - for mdoc, in Chapter 9.1.3.5 in ISO 18013-5, in the mdoc MAC Authentication section - for SD-JWT, the IETF Draft for [Designated Verifier Signatures](https://datatracker.ietf.org/doc/draft-bastian-dvs-jose/) defines a JOSE algorithm to be used ## Cryptographic Formats Long-Term keys: - **PID Provider has long-term key pair** $(pp\_pub, pp\_priv)$ is used to sign over the ephemeral issuer key, authenticating it for credential issuance - **Relying Party has long-term key pair** $(rp\_pub, rp\_priv)$ which is used to sign over the authorization request, authenticating its contents - **Wallet Instance has long-term device bound key pair** $(device\_pub, device\_priv)$ which is used to generate proof of possession of wallet attestation Transaction-specific keys: - **Relying Party generates ephemeral key pair** $(rp\_eph\_pub, rp\_eph\_priv)$ which is used as contribution to HMAC key - **PID Provider generates ephemeral key pair** $(pp\_eph\_pub, pp\_eph\_priv)$ which is used as contribution to HMAC key - **Wallet generates ephemeral key pair** $(kb\_eph\_pub, kb\_eph\_priv)$ which is used to sign KB-JWT (SD-JWT) - **Wallet generates ephemeral key pair** $(dpop\_eph\_pub, dpop\_eph\_priv)$ which is used to sign DPoP proof JWT Artifacts mdoc: - PID Provider creates **issuerAuth**: $\text{issuerAuth} := \text{sign}(pp\_eph\_pub, x5chain)_{pp\_priv}$ - **Key for authenticating mdoc:** $hmac\_key := \text{ecdh}(rp\_eph\_pub, pp\_eph\_priv)$ - PID Provider creates **deviceAuth**: $\text{deviceAuth} := \text{hmac}(\mathit{eID\_data}, \mathit{SessionTranscript})_{hmac\_key}$ Artifacts SD-JWT VC: - PID Provider creates **certificate for ephemeral issuer key**: $x5c\_header := \text{sign}(pp\_eph\_pub)_{pp\_priv}$ - **Key for authenticating SD-JWT:** $hmac\_key := \text{ecdh}(rp\_eph\_pub, pp\_eph\_priv)$ - PID Provider creates **SD-JWT**: $sd\_jwt := \text{hmac}(x5c\_header, \mathit{eID\_data}, kb\_eph\_pub)_{hmac\_key}$ - Wallet creates **KB-JWT**: $kb\_jwt := \text{sign}(nonce, audience, \text{hash}(sd\_jwt, disclosures))_{kb\_eph\_priv}$ ### Dependencies *TODO: May want to expand to include metadata.* For mdoc: ```plantuml digraph G { subgraph cluster_pid_provider { style=filled color=lightblue label="PID Provider" pp [label="🗝 (pp_priv, pp_pub)"] pp_eph [label="🗝 (pp_eph_priv, pp_eph_pub)"] pp -> pp_eph [label="sign (issuerAuth)"] deviceAuth [label="deviceAuth(eID data, SessionTranscript(nonce, audience))"] shared_secret_k [label="🗝 shared secret K"] sd_jwt_hmac_key [label="🗝 hmac key"] } subgraph cluster_rp { style=filled color=lightyellow label="Relying Party" rp [label="🗝 (rp_priv, rp_pub)"] rp_eph [label="🗝 (rp_eph_priv, rp_eph_pub)"] rp -> rp_eph [label="sign (Auth. Request)"] } pp_eph -> shared_secret_k [label="ecdh-ka"] rp_eph -> shared_secret_k [label="ecdh-ka"] shared_secret_k -> sd_jwt_hmac_key [label="key derivation"] sd_jwt_hmac_key -> deviceAuth [label="hmac"] } ``` For SD-JWT VC: ```plantuml digraph G { subgraph cluster_pid_provider { style=filled color=lightblue label="PID Provider" pp [label="🗝 (pp_priv, pp_pub)"] pp_eph [label="🗝 (pp_eph_priv, pp_eph_pub)"] pp -> pp_eph [label="sign"] user_data [label="eID data"] shared_secret_k [label="🗝 shared secret K"] sd_jwt_hmac_key [label="🗝 hmac key"] } kb_eph [label="🗝 (kb_eph_priv, kb_eph_pub)"] subgraph cluster_rp { style=filled color=lightyellow label="Relying Party" rp [label="🗝 (rp_priv, rp_pub)"] rp_eph [label="🗝 (rp_eph_priv, rp_eph_pub)"] rp -> rp_eph [label="sign (Auth. Request)"] } subgraph cluster_wallet { style=filled color=lightgreen label="Wallet" nonce_audience [label="nonce, audience"] dpop [label="DPoP proof (dpop_nonce)"] dpop_key [label="🗝 (dpop_eph_priv, dpop_eph_pub)"] } pp_eph -> shared_secret_k [label="ecdh-ka"] rp_eph -> shared_secret_k [label="ecdh-ka"] shared_secret_k -> sd_jwt_hmac_key [label="key derivation"] sd_jwt_hmac_key -> kb_eph [label="hmac (SD-JWT)"] kb_eph -> nonce_audience [label="sign (KB-JWT)"] sd_jwt_hmac_key -> user_data [label="hmac (SD-JWT)"] dpop_key -> dpop [label="sign"] } ``` ## Wallet Activation To initialize the wallet, the Wallet obtains wallet attestation as defined in [Wallet Attestation](Wallet-Attestation.md). ## [Sequence Diagram] On-demand PID Issuance [User Journey: PID Presentation - Authenticated Channel - eID Card](../../../user_journeys/PID-AuthenticatedChannel-eIDcard-presentation.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title PID presentation over OpenID4VP and On-the-fly PID Issuance over OpenID4VCI with SD-JWT actor u as "User\nOpenID Holder" participant b as "Browser App\n(same device)" participant v [ Relying Party ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ] participant w as "User's EUDI Wallet Instance\n(eID-Client)" participant i [ PID Provider (eService+eID Server) ---- ""Long-term Key: (//pp_pub//, //pp_priv//)"" ] u --> b : browse to application hnote over b #dfd: Screen: same_device_relying_party_start b -> v : tls() HTTP GET v -> v : generate ephemeral key pair (//rp_eph_pub//, //rp_eph_priv//) note left: every RP in the ecosystem must always include ephemeral key in client metadata for ECDH-KA for MAC, however we need the ephemeral key anyway for encryption v -> v : create OpenID4VP Authorization Request,\n sign with //rp_priv//,\n store under note left: Authorization Request includes:\n- presentation_definition\n- purpose\n- state\n- nonce\n- //rp_eph_pub// with PoP bound to client_id\n- response_uri v -> v : generate new browser session session_id and bind the authorization request to it v -> b : tls() HTTP 200 HTML containing wallet-link openid4vp://authorize?")\nclient_id=..&request_uri=\nSet-Cookie: sid=session_id u --> b : action to start flow/launch wallet b -> w : launch with wallet-link openid4vp:// note right #fc7: Potential security risk: Wallet app may be spoofed by malicious app hnote over w #dfd: Screen: launch_wallet u --> w : unlock wallet note right: may be moved to later point in flow or removed, see notes. hnote over w #dfd: Screen: unlock_wallet w -> v : tls() HTTP GET note right #fc7: Potential privacy risk: RP learns existence of wallet app and potentially identifying information (e.g., headers) v -> w : tls() HTTP 200 w -> w : validate Authorization Request JWT using //rp_pub// u <--> w : user consent to present PID to Relying Party for given purpose hnote over w #dfd: Screen: consent_present_credential group PID provisioning note over w,i: PID Issuer and EUDI Wallet have inherent trust relationship, metadata may be pre-configured or retrieved w -> w : Wallet fetches fresh wallet attestation from backend w -> i : tls() HTTP POST wallet attestation nonce i -> i : generate and store nonce i -> w : tls() HTTP 200 w -> w : sign wallet attestation PoP JWT (incl. wallet attestation nonce) with //device_priv// w -> i : tls() HTTP POST PAR (PKCE code_challenge, wallet attestation JWT, wallet attestation PoP JWT, redirect_uri, either scope or authorization_details) i -> i : verify wallet attestation & PoP \ncheck Wallet Provider solution status on trust list i -> w : tls() HTTP 200 request_uri note right : Attestation guarantees with high certainty that Wallet is trustworthy and not manipulated w -> i : tls() HTTP GET hnote over w #dfd: Screen: eid_start group Read eID or Smart eID acc. to BSI TR-03130 i --> w : tls() HTTP 200 starting the eID Process w <-> i : eID Process u <--> w : hnote over w #dfd: Screen: eid_pin w <-> i : eID Process w -> i : tls() HTTP GET finishing the eID process with refreshUrl hnote over w #dfd: Screen: eid_nfc_data end i --> w : tls() HTTP 200 Authorization Response (code) group Generate initial DPoP nonce w -> w : generate ephemeral DPoP key pair //dpop_eph_pub//, //dpop_eph_priv// w -> w : generate placeholder DPoP proof using ephemeral DPoP key pair //dpop_eph_pub//, //dpop_eph_priv// w -> i : tls() HTTP POST i -> i : generate and store dpop_nonce i -> w : tls() HTTP 400 note left : The Wallet should check at this point, whether the Token Endpoint delivered the expected error and nonce. If not, this needs to be handled (retry or abort gracefully). w -> w: store dpop_nonce end w -> w: prepare DPoP proof JWT with //dpop_eph_pub//, dpop_nonce, iat and sign with //dpop_eph_priv// w -> i : tls() HTTP POST Token Request(code, code_verifier, DPoP header) i -> i : generate and store dpop_nonce i -> i : lookup authorization code\ngenerate Token Response with DPoP-bound access token\nverify PKCE challenge\nverify DPoP proof i --> w : tls() HTTP 200 Token Response(DPoP nonce header, DPoP-bound access_token, c_nonce, optional authorization_details) w -> w : generate credential response encryption key pair (//cre_eph_pub//, //cre_eph_priv//) w -> w : create credential_response_encryption object with jwk containing //cre_eph_pub// w -> w: prepare DPoP proof JWT with //dpop_eph_pub//, dpop_nonce, iat and sign with //dpop_eph_priv// alt #ddf B.1.1: ISO mdoc w -> w : calculate SessionTranscript (mDocGeneratedNonce, client_id, responseUri, nonce) w -> i : tls() Credential Request (DPoP header with proof, //rp_eph_pub//, credential_response_encryption object, SessionTranscript) note right: -//rp_eph_pub// is sent in `verifier_pub` parameter\n-SessionTranscript is sent in `session_transcript` parameter\n-no `proof`/`proofs` parameters i -> i : generate device key pair (//pp_eph_pub//, //pp_eph_priv//),\n create issuerAuth with //pp_eph_pub// and w/o data items\n and sign with //pp_priv// else #dfd B.1.2: SD-JWT VC w -> w : generate ephemeral key pair for KB-JWT (//kb_eph_pub//, //kb_eph_priv//) and sign c_nonce w -> i : tls() Credential Request (DPoP header with proof, //rp_eph_pub//, credential_response_encryption object, //kb_eph_pub//) note right: //rp_eph_pub// is sent in `verifier_pub` parameter i -> i : generate issuer key pair (//pp_eph_pub//, //pp_eph_priv//),\n create certificate for chain with //pp_eph_pub// as x5c header and sign with //pp_priv// end i -> i : perform DH key exchange with //rp_eph_pub// and //pp_eph_priv// / //pp_eph_priv//,\n generate shared secret k\nand derive MAC key for PID note over i: ECDH-MAC not specified for JOSE yet note over i #AAFFAA: SD-JWT is HMAC'd, not signed alt #ddf B.1.1: ISO mdoc i -> i : create deviceAuth using MAC key with eID data and SessionTranscript i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i --> w : tls() HTTP 200 JWT(Credential Response(mdoc)) w -> w : decrypt credential response JWT and retrieve PID else #dfd B.1.2: SD-JWT VC i -> i : - create SD-JWT with eID data, include //kb_eph_pub// and x5c with //pp_eph_pub//, HMAC using MAC key i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i --> w : tls() HTTP 200 JWT(Credential Response(SD-JWT)) note right: SD-JWT contains no disclosures\nand no KB-JWT w -> w : decrypt credential response JWT and retrieve PID w -> w : create KB-JWT payload with nonce, audience, and hash of SD-JWT and selected disclosures and sign with //kb_eph_priv// end end w -> w : create vp_token and presentation_submission w -> w : add mDL presentation according to with to vp_token and presentation_submission note left #AAFFAA: Wallet may add presentations with keys under its own control as the \ncommunication channel between Relying Part and PID Provider is not E2EE w -> v : tls() HTTP POST encrypted v -> v : look up state in existing sessions\ncreate & store response_code for session v --> w : tls() HTTP 200 w -> b : launch browser with hnote over w #dfd: Screen: success_redirect b -> v : tls() HTTP GET \nCookie: sid=session_id v -> v : look up session with session_id and match response_code v -> v : perform DH key exchange with //rp_eph_priv// from session and //pp_eph_pub//,\n generate shared secret k\n derive MAC key alt #ddf B.1.1: ISO mdoc v -> v : verify contents of :\n- verify mdoc issuerAuth/deviceAuth PID with MAC key\n- calculate and validate correct SessionTranscript else #dfd B.1.2: SD-JWT VC v -> v : verify contents of :\n- verify SD-JWT PID with MAC key\n- verify KB-JWT with //kb_eph_pub// from SD-JWT\n- validate nonce and audience from KB-JWT end v --> b : tls() HTTP 200 hnote over b #dfd: Screen: same_device_relying_party_identified @enduml ``` ## [Step-by-Step Description] On-demand PID Issuance Note: While certain assumptions about session management of the Relaying Party are made here, the concrete implementation is considered out of scope for this document. The usual security considerations for web session management apply. 1. User browses to Relying Party (RP) website 2. Browser app on the user's device opens the RP website 3. RP generates a key pair to be used for ECDH key agreement for SD-JWT HMAC'ing 4. RP generates an OpenID4VP Authorization Request and stores it under a `request_uri` (e.g., `https://rp.example.com/oidc/request/1234`); - The request is bound to the user's browser session - It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id - It contains the ephemeral key for ECDH key agreement for SD-JWT HMAC'ing - It contains RP's nonce and state - It contains the RP's response_uri endpoint for sending the Authorization Response over POST 5. RP generates a new browser session and binds the generated Authorization Request to it 6. RP returns an HTML page to the browser containing a link to the wallet app (e.g., `openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234`); a cookie with the browser session id is set 7. The user clicks on the link 8. The RP website navigates to the custom scheme link to launch the wallet app 9. The user unlocks the wallet app (see notes below) 10. The wallet app retrieves the Authorization Request from the RP website (e.g., `https://rp.example.com/oidc/request/1234`) 11. The wallet app receives the Authorization Request 12. The wallet app validates the Authorization Request using the RP's public key - Was the signature valid and the key bound to the RP's metadata? - **Security:** This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP. 13. The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the PID. 14. The Wallet fetches fresh wallet attestation from the Wallet Provider backend. 15. The Wallet requests a fresh nonce for the wallet attestation nonce from the PID Provider (wallet attestation nonce). 16. The PID Provider generates a fresh nonce linked to the issuance session. 17. The PID Provider returns the wallet attestation nonce to the Wallet. 18. The Wallet generates a Wallet Attestation PoP and signs it with *device_priv*; containing - audience - expiration time - wallet attestation nonce 19. The wallet sends the Pushed Authorization Request to the PID Provider; containing - PKCE code_challenge - wallet attestation + PoP - redirect_uri - either scope or an authorization_details parameter requesting the PID 20. The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list. 21. The PID Provider returns a request_uri that is bound to the Pushed Authorization Request. 22. The Wallet sends the Authorization Request; containing - the PAR request_uri 23. The PID Provider responds with the first step to start the eID process with the wallet app, e.g. the tcToken. Note that this is the direct HTTP Response to Step 14. 24. Further communication is exchanged to perform the eID process 25. The user provides the eID PIN to the wallet app. 26. Further communication is exchanged to perform the eID process 27. The eID process is finished and as a final step the Wallet sends a request to the PID Provider calling the refreshURL. From now on Wallet and PID Provider are using the TLS-PSK channel generated by the eID flow. 28. The PID Provider responds to the Wallet with an Authorization Response; containing - the auth code 29. The Wallet generates an ephemeral DPoP key pair *dpop_eph_pub*, *dpop_eph_priv*. 30. The Wallet generates a placeholder DPoP proof JWT using the ephemeral DPoP key pair to trigger an error response from the Token endpoint necessary to retrieve the `dpop_nonce`. 31. The Wallet sends a Token Request to the PID Provider, containing the placeholder DPoP proof JWT. 32. The PID Provider generates and stores a `dpop_nonce`. 33. The PID Provider responds with the expected error "use_dpop_nonce", containing the `dpop_nonce` to be used from now on in the DPoP nonce header. 34. The Wallet extracts and stores the `dpop_nonce`. 35. The Wallet now prepares the actual DPoP proof JWT for `dpop_eph_pub` including the `dpop_nonce` and `iat` signed with *dpop_eph_priv*. 36. The Wallet sends a Token Request to the PID Provider; containing: - the authorization_code from Authorization Response - the PKCE code_verifier matching the code_challenge from Authorization Request - the DPoP Header 37. The PID Provider generates and stores a `dpop_nonce`. 38. The PID Provider matches the authorization_code and verifies the PKCE code_verifier to the previously received code_challenge. It then generates an access token bound to the DPoP key. 39. The PID Provider sends a Token Response; containing - DPoP-bound access token - a c_nonce - an authorization_details object, in case the authorization_details parameter was used in the Authorization Request - a fresh `dpop_nonce` in the DPoP nonce header 40. The Wallet generates a new ephemeral keypair (*cre_eph_pub*, *cre_eph_priv*). 41. The Wallet creates the `credential_response_encryption` JSON object containing the following information: - a jwk containing the *cre_eph_pub* - the JWE alg parameter - the JWE enc parameter 42. The Wallet prepares the DPoP proof JWT for `dpop_eph_pub` including the `dpop_nonce` and `iat` signed with *dpop_eph_priv*. 43. **(mdoc)** The Wallet calculates the SessionTranscript according to ISO-18013-7 Annex B.4.4 from mDocGeneratedNonce, client_id, responseUri, nonce. The final result is a SHA-256 hash, thus not revealing the client_id and ResponseUri to the PID Provider. 44. **(mdoc)** The Wallet send a Credential Request; containing - DPoP header with proof - sessionTranscript - the ephemeral RP key *rp_eph_pub* from the RP's Authorization Request - the `credential_response_encryption` object - it does not contain a "proof" 45. **(mdoc)** The PID Provider generate an ephemeral DeviceKey pair (*pp_eph_pub*,*pp_eph_priv*) and creates the mdoc issuerAuth (MSO) with the public part of DeviceKey and without the IssuerSignedItems and signs it with *pp_priv*. 46. **(SD-JWT)** The Wallet generates an ephemeral key pair for the KB-JWT (*kb_eph_pub*, *kb_eph_priv*) and signs the nonce 47. **(SD-JWT)** The wallet app sends the Credential Request to the PID Provider; containing - the DPoP header with proof - the ephemeral RP key *rp_eph_pub* from the RP's authorization request, - the `credential_response_encryption` object - the ephemeral KB-JWT key *kb_eph_pub* 48. **(SD-JWT)** The PID Provider generates the ephemeral issuer key pair (*pp_eph_pub*, *pp_eph_priv*) and creates a certificate for the chain with *pp_eph_pub* as x5c header and signs it with *pp_priv*. 49. The PID Provider performs DH key exchange with the ephemeral RP public key *rp_eph_pub* and the ephemeral issuer private key *pp_eph_priv*, generates a shared secret k and derives a MAC key for the PID. 50. **(mdoc)** The PID Provider creates the mdoc deviceAuth (using the MAC key) containing - the user claims - the OpenID4VP SessionTranscript(mdocGeneratedNonce, client_id, responseUri, nonce) 51. **(mdoc)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID credential to the payload. 52. **(mdoc)** The PID Provider sends the Credential Response JWT; containing: - PID as mdoc 53. **(mdoc)** The Wallet decrypts the Credential Response JWT using the *cre_eph_priv* and retrieves the PID. 54. **(SD-JWT)** The PID Provider creates the issuer-signed part of the SD-JWT (using the MAC key) containing - eID as the user claims - *kb_eph_pub* as cnf claim 55. **(SD-JWT)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID credential to the payload. 56. **(SD-JWT)** The PID Provider sends the Credential Response JWT; containing: - PID as SD-JWT VC 57. **(SD-JWT)** The Wallet decrypts the Credential Response JWT using the *cre_eph_priv* and retrieves the PID. 58. **(SD-JWT)** The Wallet creates the header and payload for the KB-JWT from audience, nonce, and the hash of SD-JWT and selected disclosures and signs it with its generated *kb_eph_priv*. The Wallet appends the KB-JWT to the SD-JWT. 59. The wallet app creates a VP token and a presentation submission from the received SD-JWT PID. 60. Optional: The wallet app can add further presentations with keys under its own control as the communication channel between Relying Part and PID Provider is not E2EE 61. The wallet app sends the VP token and presentation submission to the RP (encrypted to the RP's public key *rp_eph_pub*). 62. The RP finds a session with the state and generates a response_code for this session 63. The RP returns the redirect_uri with the response_code to the wallet app 64. The wallet app launches the browser with the redirect_uri and response_code. 65. The browser sends the redirect_uri and response code to the RP, attaching the browser session id as a cookie. 66. The RP looks up whether there exists a session with the session id from the cookie and a matching response_code 67. Using the data from the session the RP performs DH key exchange with the PID Provider's public key, generates a shared secret k and derives a MAC key. 68. **(mdoc)** The RP verifies the PID in the VP token with the MAC key and verifies the SessionTranscript calculated from nonce, mDocGeneratedNonce, client_id, response_uri. 69. **(SD-JWT)** The RP verifies the SD-JWT PID in the VP token with the MAC key, verifies the KB-JWT using the *kb_eph_pub* in the SD-JWT, and verifies the nonce and audience in the KB-JWT 70. The RP considers the user to be identified in the session context and continues the UX flow. ## Extensions to the Protocols This section defines extentions to the protocols required to implement this flow (Option B). In this document, the term `RP` has been used, but this since this section is an extension to an OpenID4VCI protocol, a term from that specification is being used, which is `verifier`. ### Issuer Session Endpoint (at the PID Provider) Note that this extension is the same across multiple flows. This endpoint is used by the Wallet to obtain `session_id` from the PID Provider that is used to bind PoPs to the session and prove their freshness. Support for this endpoint is REQUIRED. To fetch the `session_id`, the Wallet MUST send an HTTP request using the POST method and the `application/json` media type. The PID Provider MUST return the HTTP Status Code 200 and a `session_id` parameter defined below. - `session_id`: REQUIRED. String that is a unique session identifier, chosen as a cryptographically random nonce with at least 128 bits of entropy. Communication with the Session Endpoint MUST utilize TLS. Below is a non-normative example of a request to a Session Endpoint: ```http POST /session_endpoint HTTP/1.1 Host: server.example.com Content-Type: application/json ``` Below is a non-normative example of a response from a Session Endpoint: ```http HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "session_id": "iOiJSUzI1NiIsInR" } ``` ### OpenID4VCI Credential Issuer Metadata Note that this extension is the same across multiple flows. This document defines the following additional Credential Issuer Metadata parameters: - `session_endpoint`: REQUIRED. URL of the Credential Issuer's Session Endpoint, as defined in a previous section. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. ### OpenID4VCI Credential Request and Response for PID Issuance in mdoc Credential Format using Authenticated Channel Note that this section is the same as in Option B'. Credential Format identifier is `mso_mdoc_authenticated_channel`. The following parameters are defined in addition to those defined for the Credential Format `mso_mdoc` in Annex A.2 of OpenId4VCI: - `session_transcript`: REQUIRED. String that is a base64url encoded SessionTranscriptBytes as defined in Section 9.1.5.1 of ISO 18013-5. - `verifier_pub`: REQUIRED. A JSON object as defined in Section 2 of RFC7591. It contains the ephemeral RP key *rp_eph_pub* from the RP's Authorization Request. `proof` or `proofs` parameter MUST NOT be present. `credential_response_encryption` parameter MUST be present. Note: The wallet can find out about the supported cryptographic algorithms by using the Issuer's metadata parameter `credential_response_encryption`. DPoP-bound Access token MUST be present. Below is a non-normative example of a Credential Request during the PID issuance in ISO mso Credential Format over Authenticated Channel: ```json POST /credential HTTP/1.1 Host: server.example.com Content-Type: application/json Authorization: DPoP czZCaGRSa3F0MzpnWDFmQmF0M2JW DPoP: ey… { "format": "mso_mdoc_authenticated_channel", "doctype": "org.iso.18013.5.1.mDL", "session_transcript": "...", "verifier_pub": { "kty": "EC", "crv": "P-256", "x": "aPPK-...2-Drn", "y": "FqJqG...ksKHp" }, "credential_response_encryption": { "jwk": { "kty": "EC", "crv": "P-256", "x": "1SptQyCUQiQD3dBcVHTclxRtcqhZlF1rIKcBR-i_WK4", "y": "8ayoQrh52zNuRQx8Q0gpmCpOjzbH397mOsaSi8X10c4" }, "alg": "ECDH-ES", "enc": "A256GCM" } } ``` `credential` parameter in the Credential Response MUST contain a base64url-encoded `Document` which contains `IssuerSigned` and the `DeviceSigned` parameters defined in section 8.3.2.1.2.2 of 18013-5. The Device key included in the `IssuerSigned` and used to secure `DeviceSigned` is generated by the PID Provider, and not by the Wallet as defined in ISO 18013-5. SessionTranscript used by the PID Provider when calculating `DeviceSigned` is calculated by the Wallet. Therefore, there is no need for the PID Provider to know the specific values of `mdocGeneratedNonce`, `client_id`, `responseUri`, and `nonce` parameters used for SessionTranscript calculation by the Wallet. Moreover, there is also no way for the PID Provider to reconstruct these values, as the SessionTranscript is hashed and contains random values chosen by the wallet (i.e. `mdocGeneratedNonce`). Below is a non-normative example of a Credential Response JWT (JWE) during the PID issuance in mso Credential Format over Authenticated Channel: ```json HTTP/1.1 200 OK Content-Type: application/jwt Cache-Control: no-store { "epk": { "kty": "EC", "crv": "P-256", "x": "VJUVl-ZqLKzzncZ4Gs_nJfcqY_YBHPkGVN0sRSlF-3s", "y": "y4maAWKte676d0wL6um-8wAUJ9pW-mlc528BFeiXn2Y" }, "enc": "A256GCM", "alg": "ECDH-ES" }.. nLuW9PwrGl76pjTy. nH_XE2LJ2u-N0o8M-tanqoYhJr7hbjo. 3uNrPqJazT9ZSf54sk1Ueg ``` The decrypted payload of the Credential Response JWT example results in the following structure: ```json { "credential": "..." } ``` ### OpenID4VCI Credential Request and Response for PID Issuance in SD-JWT Credential Format using Authenticated Channel Note that this section is the same as in Option B. The following parameter is defined in addition to those defined for the Credential Format `dc+sd-jwt` in Annex A.3 of OpenId4VCI: - `verifier_pub`: REQUIRED. A JSON object as defined in Section 2 of RFC7591. It contains the ephemeral RP key *rp_eph_pub* from the RP's Authorization Request. New Credential Format identifier is not defined PID Issuance in SD-JWT Credential Format using Authenticated Channel, because the issued Credential in the Credential Response is SD-JWT, which is the same as the one defined in Annex A.3 of OpenId4VCI. Since during PID Issuance in SD-JWT Credential Format using Authenticated Channel, not just `IssuerSigned`, but also `DeviceSigned` is returned in the Credential Response as part of the `Document` structure as defined above, it is a significant deviation that necessitated the definition of a new Credential Format identifier `mso_mdoc_authenticated_channel`. `credential_response_encryption` parameter MUST be present. Note: The wallet can find out about the supported cryptographic algorithms for the credential response encryption by using the Issuer's metadata parameter `credential_response_encryption`. Below is a non-normative example of a Credential Request during the PID issuance in IETF SD-JWT VC Credential Format over Authenticated Channel: Note: The wallet can find out about the supported cryptographic algorithms by using the Issuer's metadata parameter `credential_signing_alg_values_supported`. ```json POST /credential HTTP/1.1 Host: server.example.com Content-Type: application/json Authorization: DPoP czZCaGRSa3F0MzpnWDFmQmF0M2JW DPoP: ey… { "format": "dc+sd-jwt", "vct": "SD_JWT_VC_example", "proof": { "proof_type": "jwt", "jwt": "eyJ0e...h1WlA" }, "verifier_pub": { "kty": "EC", "crv": "P-256", "x": "aPPK-...2-Drn", "y": "FqJqG...ksKHp" }, "credential_response_encryption": { "jwk": { "kty": "EC", "crv": "P-256", "x": "1SptQyCUQiQD3dBcVHTclxRtcqhZlF1rIKcBR-i_WK4", "y": "8ayoQrh52zNuRQx8Q0gpmCpOjzbH397mOsaSi8X10c4" }, "alg": "ECDH-ES", "enc": "A256GCM" } } ``` ## Implementation Considerations - When the issuance flow is specific to the PID Provider, alternatives to Presentation Exchange may be considered. If the issuance flow is to be generic, sticking to PE might be the best option. - The JWA to use the x5c in the SD-JWT and perform ECDH key agreement and derive the MAC key is to be defined, a proposal is made [here](https://github.com/paulbastian/jose-ecdh-mac-algorithms). ## Usability Considerations - Relying Party should inform users in advance of what is required for the process to be completed successfully and what steps follow - It must be clarified whether the wallet app needs to be unlocked in this flow, as no sensitive data is displayed and the user must identify themselves with their ID card and eID PIN in order to successfully complete the process - For reasons of transparency and to increase trust, Relying Parties should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the relying party itself, privacy and data retention - eID process is integrated in Wallet. No context switch to the AusweisApp is required - Physical ID card is required for every transaction - Online-Ausweisfunktion must be activated - eID PIN must be set by the user (replacement of the Transport PIN) and be known to them so that they can successfully confirm the process - Only the requested data attributes can be displayed on the consent screen, as the user's data values are not available at this point (only after a successful eID process) - It must be ensured that users return to the correct tab in the correct browser in order to continue the process or know how to get there manually if necessary (especially for iOS devices, if the process was not started in the default browser) - To eliminate the PID provider observing which attributes are presented, the PID provider will generate a PID with all attributes; then the wallet will generate the KB-JWT payload based on the Relying Party's request. While this approach increases privacy, it will decrease the user experience by confusing the user. According to the German eID card law, the client needs to display which attributes are read from the eID card. This means, for example, in case of a use case where only the age has to be verified, the client would have to display all PID attributes. This could scare the user and lead them to abort the process, or the information which are shared with the Relying Party are ignored by the user because there are two screens. This problem could be eliminated by introducing an exception for EUDI Wallet in the German eID law. ## Security Considerations - In Step 8, a malicious app may spoof the wallet app by registering to the same custom URL scheme; an attacker may - **on the attacker's own device:** Capture the request and replay it to a victim on another device, thus having the victim identify itself in a context of the attacker (**Relaying Attack breaking Identification Context**); or - **on the victim's device:** Capture the request and spoof the whole identification process or parts of it (**Wallet App Spoofing**). - In Step 10: An attacker acting as an RP can forward a request from a different RP. - As long as the request remains unchanged, we're in the **Relaying Attack breaking Identification Context** - If the attacker changes anything in the request, this will break the signature. The attacker could otherwise attempt to - insert the attacker's own ephemeral key, leading to an SD-JWT artifact that could be used in a different flow between the attacker and some other RP. - modify state or nonce or other data. **Q:** Any useful attacks resulting from this? - In Step 14: Shall the Wallet Attestation be used at the Authorization Request? Which nonce to use for Wallet Attestation at the Token Request? - In Step 15 and onward: Security of PID Provider Interface: - Are additional steps required to protect the interface to the PID Provider? - What exactly is the transaction binding? - How is the eID process tied to the process at the PID provider? - In Step 37: The RP must not consider the user identified at this point; it is important to have the browser redirect in the later steps. ## Privacy Considerations - For the user consent, the user should be informed in a meaningful way about the process for which the identification is performed. This includes the RP's domain name or assured legal name (via a certificate), the purpose of the identification and the context. Note: This may have privacy implications that need to be evaluated. - The Wallet must ensure that the purpose of the Relying Party is not transmitted to the PID Provider. - Selective Disclosure is achieved by ensuring that the credential contains only those data items (claims) that are requested by the RP. The list of requested claims is part of the request to the PID Provider. - An initiating step before the authorization request (Step 10) that is performed without the user's interaction might leak information about the user's device to the RP (**Initial Request Privacy Leak**). For example: - the fact that the wallet app is installed, - the fact which wallet app is installed, - some metadata about the wallet app contained in request headers (e.g., version, language, etc.), - network information if the browser uses a VPN but the wallet app does not. - The SessionTranscript is used to bind the authentication to a specific session: - The SessionTranscript structure for OpenID4VP contains a OID4VPHandover structure containing: - clientIDHash containing the SHA256 of the Relying Parties client_id and the mdocGeneratedNonce - responseUriHash containing the SHA256 of the Relying Parties responseUri and the mdocGeneratedNonce - nonce chosen by the Relying Party - As the relevant information is hashed, the Relying Party identity is not revealed to the PID Provider - Unlinkability: Each Relying Party sees a new credential for each use of the flow. Unless the eID data itself enables linkability, there is no information enabling linkablility between different uses of the flow. --- ## PID Option D: Authenticated Channel with Secure Element ## Basic Ideas * There is an Applet in the Secure Element of the user's device. This applet belongs to the Wallet Provider's domain (difference in case of eUICC?). It could be used for very security sensitive credentials beyond PIDs. * The Wallet Design is composed of three elements: Wallet Backend, Wallet App and Wallet Applet * Applet is installed during Wallet App installation (if supported by the device and provisioning is possible through platform vendor/MNO) * Applet is provisioned with an assertion attesting applet managed key as (internally used) authentication key * Access to authentication key is protected by Applet-managed PIN Note: This flow is shown here using the SD-JWT credential format, but the mdoc format can be used as well. ## Responsibilities of the Wallet Components Wallet App * RP authentication * Request processing * Combination of PID with (Q)EAA presentations * Response encryption * Access to Wallet App and Data managed by the App is protected by platform authentication Wallet Applet * Management of PID specific device keys * Access to PID device keys is protected by Applet-managed PIN * Creation of proof of possession for wallet attestations (with PID device keys) * Data Storage for PIDs and PID data (could also just HMAC and encrypt and hand them over to App) * creation of credential presentations (not responses!) Wallet Provider * Applet provisioning with authentication key * Attestation of Wallet App and PID device keys ## Cryptographic Formats ### Issuance Long-term keys: * Authentication key of Wallet Applet: $(auth\_pub, auth\_priv)$ — authenticates the applet * Wallet provider backend has keys: $(wp\_pub, wp\_priv)$ * PID Provider backend has keys: $(pp\_pub, pp\_priv)$ Transaction-specific keys: * Wallet Secure Area generates device key $(device\_pub, device\_priv)$ * authenticity can be determined by applet assertion* a new key is generated per issuer * Wallet Secure Area generates DPoP key $(dpop\_pub, dpop\_priv)$ * Wallet generates ephemeral key pair used to encrypt the credential response $(cre\_eph\_pub, cre\_eph\_priv)$ Artifacts: * Wallet applet creates device key PoP: $device\_key\_pop := \text{sign}(wallet\_attestation\_nonce)_{device\_priv}$ * Wallet applet creates DPoP proof: $dpop\_proof := \text{sign}(dpop\_nonce, dpop\_pub, iat)_{dpop\_priv}$ * Wallet applet creates signed assertion: $device\_key_\_attestation := \text{sign}(device\_pub)_{auth\_priv}$ * Wallet app creates wallet app attestation: $wallet\_app\_attestation := \text{app\_attestation}(wallet\_attestation\_nonce)_\text{os\_keys}$ * Wallet backend creates wallet attestation: $wallet\_attestation := \text{sign}(device\_pub)_{wp\_priv}$ * Wallet creates wallet attestation PoP: $wallet\_attestation\_pop := \text{sign}(pid\_issuer\_session\_id)_{device\_priv}$ * Wallet applet creates device key PoP for credential issuance: $device\_key\_pop := \text{sign}(c\_nonce)_{device\_priv}$ * PID Provider creates $x5c\_header := \text{sign}(device\_pub)_{pp\_priv}$ * PID Provider creates $user\_data\_jwt := \text{hmac}(user\_data, x5c\_header)_{\text{ecdh(device\_pub, pp\_pub)}}$ ### Presentation Long-term keys: * Device key $(device\_pub, device\_priv)$ Transaction-specific keys: * **RP contribution to HMAC key:** RP generates ephemeral key pair $(rp\_eph\_pub, rp\_eph\_priv)$ * **KB-JWT Keys:** Wallet applet generates ephemeral key pair $(kb\_eph\_pub, kb\_eph\_priv)$ Artifacts: * $hmac\_key := \text{ecdh}(device\_priv, rp\_eph\_pub)$ * $sd\_jwt := \text{hmac}(x5c\_header, \mathit{eID\_data}, kb\_eph\_pub)_{hmac\_key}$ * $kb\_jwt := \text{sign}(nonce, audience, \text{hash}(sd\_jwt, disclosures))_{kb\_eph\_priv}$ ### Dependencies *TODO: May want to expand to include metadata.* ```plantuml digraph G { subgraph cluster_pid_provider { style=filled color=lightblue label="PID Provider" pp [label="🗝 (pp_priv, pp_pub)"] } pp -> device_key [label="sign (x5c header)"] subgraph cluster_rp { style=filled color=lightyellow label="Relying Party" rp [label="🗝 (rp_priv, rp_pub)"] rp_eph [label="🗝 (rp_eph_priv, rp_eph_pub)"] rp -> rp_eph [label="sign (Auth. Request)"] } subgraph cluster_wallet { style=filled color=lightgreen label="Wallet" subgraph cluster_app { label="App" style=filled color=aquamarine } subgraph cluster_applet { label="Applet" style=filled color=cyan auth_key [label="🗝 (auth_priv, auth_pub)"] user_data [label="eID data"] shared_secret_k [label="🗝 shared secret K"] sd_jwt_hmac_key [label="🗝 hmac key"] nonce_audience [label="nonce, audience"] kb_eph [label="🗝 (kb_eph_priv, kb_eph_pub)"] auth_key -> device_key [label="sign (device key attestation)"] device_key [label="🗝 (device_priv, device_pub)"] device_key -> wallet_attestation_nonce [label="sign (device key PoP)"] device_key -> pid_issuer_session_id [label="sign (wallet attestation PoP)"] device_key -> c_nonce [label="sign (credential issuance PoP)"] device_key -> shared_secret_k [label="ecdh-ka"] rp_eph -> shared_secret_k [label="ecdh-ka"] shared_secret_k -> sd_jwt_hmac_key [label="key derivation"] sd_jwt_hmac_key -> user_data [label="hmac (SD-JWT)"] sd_jwt_hmac_key -> kb_eph [label="hmac (SD-JWT)"] kb_eph -> nonce_audience [label="sign (KB-JWT)"] dpop_key [label="🗝 (dpop_priv, dpop_pub)"] dpop [label="DPoP proof (dpop_nonce)"] dpop_key -> dpop [label="sign"] } subgraph cluster_backend { label="Backend" style=filled color=cadetblue1 wp [label="🗝 (wp_priv, wp_pub)"] wp -> device_key [label="sign (wallet attestation)"] } wallet_attestation_nonce [label="wallet attestation nonce"] } subgraph cluster_os { style=filled color=lightgrey label="OS" os [label="🗝 (os_priv, os_pub)"] } os -> wallet_attestation_nonce [label="sign (wallet app attestation)"] } ``` Not shown: `user_data_jwt` Note: x5c header does not have to be signed in SD-JWT ## Sequence Diagrams and Step-by-Step Description of Each Step Each step of the protocol will be explained using a sequence diagram followed by a step-by-step description. ### Wallet Activation [User Journey: Wallet Activation - Authenticated Channel - Secure Element](../../../user_journeys/PID-AuthenticatedChannel-secureElement-initialization.png) To initialize the wallet, the Wallet obtains wallet attestation as defined in [Wallet Attestation](Wallet-Attestation.md). ### Credential Issuance #### Credential Issuance Sequence Diagram [User Journey: PID Issuance - Authenticated Channel - Secure Element](../../../user_journeys/PID-AuthenticatedChannel-secureElement-issuance.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 500 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title PID Issuance over OpenID4VCI using AuthenticatedChannel and Secure Element actor u as "User\nOpenID Holder" participant wscd [ Wallet Secure Cryptographic Device (WSCD) ---- Long-term Key: (//device_pub//, //device_priv//) ] participant w as "User's EUDI Wallet Instance\n(eID-Client)" participant i [ PID Provider (eService+eID Server) ---- Long-term Key: (//pp_pub//, //pp_priv//) ] note over wscd, w: assumption: wallet applet already provisioned and set up with a wallet applet attestation the wallet provider can use to authenticate the applet instance, user authentication with dedicated PIN u --> w : open wallet, unlock wallet hnote over w #dfd: Screen: launch_wallet hnote over w #dfd: Screen: unlock_wallet u --> w : request issuance of PID hnote over w #dfd: Screen: credential_catalog note over w,i: PID Issuer and EUDI Wallet have inherent trust relationship, metadata may be pre-configured or retrieved w -> i : tls() HTTP POST wallet attestation nonce i -> i : generate and store nonce i --> w : tls() HTTP 200 w <-> wscd : get proof of possession for wallet attestation (wallet attestation nonce) note right : Attestation guarantees with high certainty that Wallet is trustworthy and not manipulated w -> i : tls() HTTP POST PAR (client_id, code_challenge, wallet attestation+PoP, either scope or authorization_details) i -> i : verify wallet attestation and check Wallet Provider solution status on trust list i --> w : tls() HTTP 200 request_uri w -> i : tls() HTTP GET hnote over w #dfd: Screen: consent_add_credential hnote over w #dfd: Screen: eid_start group Read eID or Smart eID acc. to BSI TR-03130 i --> w : tls() HTTP 200 starting the eID Process w <-> i : eID Process u <--> w : hnote over w #dfd: Screen: eid_pin w <-> i : eID Process w -> i : tls() HTTP GET finishing the eID process with refreshUrl hnote over w #dfd: Screen: eid_nfc_data end i --> w : tls() HTTP 302 group Generate initial DPoP nonce w -> w : generate placeholder DPoP proof with generic (not WSCD-bound) key pair w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> w : tls() HTTP 400 note left : The Wallet should check at this point, whether the Token Endpoint delivered the expected error and nonce. If not, this needs to be handled (retry or abort gracefully). w -> w: store dpop_nonce end w -> w: prepare DPoP proof JWT with //dpop_pub//, dpop_nonce, iat w <-> wscd: hash and sign DPoP proof JWT with //dpop_priv// w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> i : lookup authorization code\ngenerate TokenResponse with DPoP access token\nverify PKCE challenge\nverify DPoP proof i --> w : tls() HTTP 200 w -> w: prepare DPoP proof JWT with //dpop_pub//, dpop_nonce, iat w <-> wscd: hash and sign DPoP proof JWT with //dpop_priv// w <-> wscd : generate of proof of possession for attested key //device_pub// with c_nonce hnote over w #dfd: Screen: wallet_pin w -> w : generate credential response encryption key pair (//cre_eph_pub//, //cre_eph_priv//) w -> w : create credential_response_encryption object with jwk containing //cre_eph_pub// w -> i: tls() Credential Request (DPoP Header with proof, DpoP bound access token, format, credential_response_encryption object, //device_pub//) i -> i: verify the access token\nverify DPoP proof i -> i: perform ECDH-KA with //device_pub// and //pp_priv// and derive session keys i -> i: create user data JWT from eID data and HMAC i -> i : create certificate chain with //device_pub// as leaf and sign with //pp_priv// i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object note over i, w: repurposing OpenID4VCI as certificate provisioning, instead of credential issuance i --> w: tls() Credential Response JWT with user data as JWT containing signed //device_pub// in x5c header w -> w : decrypt credential response JWT and retrieve user data JWT w --> wscd: user data JWT with x5c header wscd -> wscd: perform ECDH-KA with //device_priv// and //pp_pub// and derive session keys, validate HMAC of user data JWT wscd -> wscd: securely store user data, x5c header and associated (//device_pub//,//device_priv//) wscd --> w: return credential handle hnote over w #dfd: Screen: success hnote over w #dfd: Screen: home @enduml ``` ### Credential Issuance Step-by-Step Description 1. The user opens and unlocks their Wallet 2. The user browses through the pre-configured credential catalogue and chooses to request a PID 3. The Wallet requests a fresh nonce for the wallet attestation nonce (wallet attestation) 4. The PID Provider generates a fresh nonce linked to the issuance session 5. The PID Provider returns the wallet attestation nonce to the Wallet 6. The Wallet performs a wallet attestation * optionally fetches a new wallet attestation from the Wallet Provider if not existent yet * generates a proof of possession (PoP) for the public key of the wallet attestation using its WSCD 7. The wallet sends the Pushed Authorization Request to the PID Provider; containing * the Wallet Provider's client_id * authorization_details for PID * a PKCE code_challenge * a wallet attestation and proof of possession * either scope or an authorization_details parameter requesting the PID 8. The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list 9. The PID Provider returns a request_uri that is bound to the Pushed Authorization Request 10. The Wallet sends the Authorization Request; containing * the PAR request_uri 11. The PID Provider responds with the first step to start the eID process with the wallet app, e.g. the tcToken. Note that this is the direct HTTP Response to Step 14. 12. Further communication is exchanged to perform the eID process 13. The user provides the eID PIN to the wallet app. 14. Further communication is exchanged to perform the eID process 15. The eID process is finished and as a final step the Wallet sends a request to the PID Provider calling the refreshURL. From now on Wallet and PID Provider are using the TLS-PSK channel generated by the eID flow. 16. The PID Provider responds to the Wallet with an Authorization Response; containing * the auth code 17. The Wallet generates (and stores) a placeholder DPoP proof with a generic (not WSCD-bound) keypair to trigger an error response from the Token endpoint necessary to retrieve the `dpop_nonce`. 18. The Wallet sends a Token Request to the PID Provider, containing the placeholder DPoP proof JWT. 19. The PID Provider generates and stores a `dpop_nonce`. 20. The PID Provider responds with the expected error "use_dpop_nonce", containing the `dpop_nonce` to be used from now on in the DPoP nonce header. 21. The Wallet extracts and stores the `dpop_nonce`. 22. The Wallet now prepares the actual DPoP proof JWT for `dpop_pub` including the `dpop_nonce` and `iat`. 23. The Wallet hashes the prepared DPoP proof JWT, signs the hash with `dpop_priv` using the WSCD and includes the signature into the DPoP proof JWT 24. The Wallet sends a Token Request to the PID Provider; containing: * the auth code from Authorization Response * the PKCE code_verifier matching the code_challenge from Authorization Request * the wallet attestation and proof of possession * a DPoP key 25. The PID Provider generates and stores a fresh `dpop_nonce`. 26. The PID Provider matches the code, verifies the PKCE code_verifier to the previously received code_challenge, verifies the DPoP proof and verifies the wallet attestation. It then generates an access token bound to the DPoP key. 27. The PID Provider sends a Token Response; containing * DPoP-bound access token * a c_nonce * an authorization_details object, in case the authorization_details parameter was used in the Authorization Request. * a fresh `dpop_nonce` in the DPoP nonce header 28. The Wallet now prepares the actual DPoP proof JWT for `dpop_pub` including the `dpop_nonce` and `iat`. 29. The Wallet hashes the prepared DPoP proof JWT, signs the hash with `dpop_priv` using the WSCD and includes the signature into the DPoP proof JWT 30. The Wallet uses the device binding key (*device_pub*, *device_priv*) from the wallet attestation and signs the c_nonce using the Secure Element (WSCD) 31. The Wallet generates a new ephemeral keypair (*cre_eph_pub*, *cre_eph_priv*). 32. The Wallet creates the credential_response_encryption JSON object containing the following information: * a jwk containing the *cre_eph_pub* * the JWE alg parameter * the JWE enc parameter 33. The Wallet sends a Credential Request to the PID Provider; containing * the DPoP Header with the proof * the DpoP-bound access token * the credential_response_encryption object * the device binding key *device_pub* and the proof of possession 34. The Issuer validates the access token, the DPoP proof and the proof of possession 35. **(SD-JWT)** The PID Provider performs DH key exchange with the Wallet's public key *device_pub* and its private key *pp_priv*, generates a shared secret k and derives a MAC key 36. **(SD-JWT)** The PID Provider creates a user data JWT containing the eID data and secured with a HMAC 37. **(SD-JWT)** The PID Provider creates a certificate chain containing *device_pub* and signing with *pp_priv* 38. **(SD-JWT)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID credential to the payload. 39. The PID Provider sends the Credential Response JWT; containing: * user data JWT with the certificate chain in x5c header 40. The Wallet decrypts the Credential Response JWT using the *cre_eph_priv* and retrieves the user data JWT. 41. The Wallet forwards both artifacts to the Secure Element. 42. The Secure Element performs DH key exchange with the PID Provider's public key *pp_pub* and its private key *device_priv*, generates a shared secret k, derives the MAC key and validates the authenticity of the user data JWT. 43. The Secure Element stores the user data and the x5c certificate chain securely and associates them to *device_pub*. 44. The Wallet returns a credential handle to the Wallet for future referencing the data for generating a PID. ### Credential Presentation #### Credential Presentation Sequence Diagram [User Journey: PID Presentation - Authenticated Channel - Secure Element](../../../user_journeys/PID-AuthenticatedChannel-secureElement-presentation.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title Presentation of PID for Option D12 actor u as "User\nOpenID Holder" participant b as "Browser App\n(same device)" participant v [ Relying Party ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ] participant w as "User's EUDI Wallet Instance\n(eID-Client)" participant wscd [ Wallet Secure Cryptographic Device (WSCD) as Secure Element ---- Long-term Key: (//device_pub//, //device_priv//) ] u --> b : browse to application hnote over b #dfd: Screen: same_device_relying_party_start b -> v : tls() HTTP GET v -> v : generate ephemeral key pair (//rp_eph_pub//, //rp_eph_priv//) note left: every RP in the ecosystem must always include ephemeral key in client metadata for ECDH-KA for MAC, however we need the ephemeral key anyway for encryption v -> v : create OpenID4VP Authorization Request,\n sign with //rp_priv//,\n store under ,\nbind to browser session note left: Authorization Request includes:\n- presentation_definition\n- state\n- nonce\n- //rp_eph_pub// with PoP bound to client_id v --> b : tls() HTTP 200 HTML containing wallet-link openid4vp://authorize?")\nclient_id=..&request_uri= u --> b : action to start flow/launch wallet b -> w : launch with wallet-link openid4vp:// note right #fc7: Potential security risk: Wallet app may be spoofed by malicious app hnote over w #dfd: Screen: launch_wallet u --> w : unlock wallet note right: may be moved to later point in flow or removed, see notes. hnote over w #dfd: Screen: unlock_wallet w -> v : tls() HTTP GET note right #fc7: Potential privacy risk: RP learns existance of wallet app and potentially identifying information (e.g., headers) v --> w : tls() HTTP 200 w -> w : validate Authorization Request JWT using //rp_pub// u <--> w : user consent to present PID hnote over w #dfd: Screen: consent_present_credential note over w: determine if we need wallet attestation for presentation flows w -> wscd: prepare credential presentation (//rp_eph_pub//, credential reference, claims to disclose, input for KB-JWT) wscd -> wscd : perform DH key exchange with //rp_eph_pub// and //device_priv//,\n generate shared secret k\nand derive MAC key for PID wscd -> wscd : generate ephemeral key pair for KB-JWT (//kb_eph_pub//, //kb_eph_priv//) wscd -> wscd : create SD-JWT with user claims from secure storage, include //kb_eph_pub// and x5c with //device_pub//, HMAC using MAC key note over wscd #AAFFAA: SD-JWT data is HMAC'd, not signed wscd -> wscd: create the KB-JWT with input provided by the wallet app wscd --> w: PID SD-JWT+KB-JWT w -> w : create vp_token and presentation_submission PID SD-JWT+KB-JWT w -> w : add mDL presentation according to with to vp_token and presentation_submission hnote over w #dfd: Screen: wallet_pin w -> v : tls() HTTP POST encrypted v : perform DH key exchange with //rp_eph_priv// and //device_pub//,\n generate shared secret k\nand derive MAC key v -> v : match session with and verify PID with MAC key and //kb_eph_pub// and SD-JWT with ECDSA v --> w : tls() HTTP 200 w -> b : launch browser with hnote over w #dfd: Screen: success_redirect b -> v : tls() HTTP GET v -> v : match response_code v --> b : tls() HTTP 200 hnote over b #dfd: Screen: same_device_relying_party_identified @enduml ``` #### Credential Presentation Step-by-Step Description 1. User browses to Relying Party (RP) website 2. Browser app on the user's device opens the RP website 3. RP generates a key pair to be used for ECDH key agreement for SD-JWT hmac'ing 4. RP generates an OpenID4VP Authorization Request and stores it under a `request_uri` (e.g., `https://rp.example.com/oidc/request/1234`); * The request is bound to the user's browser session * It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id * It contains the ephemeral key for ECDH key agreement for SD-JWT hmacing * It contains RP's nonce and state 5. RP returns a HTML page to the browser containing a link to the wallet app (e.g., `openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234`) 6. The user clicks on the link 7. The RP website navigates to the custom scheme link to launch the wallet app 8. The user unlocks the wallet app (see notes below) 9. The wallet app retrieves the Authorization Request from the RP website (e.g., `https://rp.example.com/oidc/request/1234`) 10. The wallet app receives the Authorization Request 11. The wallet app validates the Authorization Request using the RP's public key * Was the signature valid and the key bound to the RP's metadata? * **Security:** This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP. 12. The user gives consent to present the PID to the RP. 13. The wallet app queries the Secure Element for the PID providing: * the credential handle referring to the PID credential, * the ephemeral RP key *rp_eph_pub* from the RP's authorization request, * a list of claims, * input for the KB-JWT (directly or hash) 14. The Secure Element performs DH key exchange with the ephemeral RP public key *rp_eph_pub* and the private part of DeviceKey *device_priv* , generates a shared secret k and derives a MAC key for the deviceAuth 15. The Secure Element generates an ephemeral key pair for the KB-JWT (*kb_eph_pub*, *kb_eph_priv*). 16. The Secure Element creates the issuer-signed part of the SD-JWT (using the MAC key) containing: * stored x5c header * stored user claims * *kb_eph_pub* as cnf claim 17. The Secure Element creates a KB-JWT payload containing the nonce, audience, and a hash of the SD-JWT and the selected disclosures and signs it using *kb_eph_priv*. 18. The Secure Element sends the SD-JWT and KB-JWT to the wallet app. 19. The wallet app creates a VP token and a presentation submission from the received SD-JWT PID. 20. Optional: The wallet app can add the mDL presentation using the nonce and ECDSA according to the presentation definition 21. The wallet app sends the VP token and presentation submission to the RP (encrypted to the RP's public key *rp_eph_pub*). 22. The RP performs DH key exchange with the PID deviceKey public key, generates a shared secret k and derives a MAC key. 23. The RP finds a session with the state and verifies the PID in the VP token with the MAC key. 24. The RP generates a response code, attaches it to the same session, and returns it to the wallet app via a redirect_uri. 25. The wallet app launches the browser with the redirect_uri and response code. 26. The browser sends the redirect_uri and response code to the RP. 27. The RP matches the response code with the browser session (i.e., ensures that the session tied to the browser session matches the one tied to the response code). 28. The RP considers the user to be identified in the session context and continues the UX flow. ## Extensions to the Protocols This section defines extensions to the protocols required to implement this flow (Option D). ### Issuer Session Endpoint (at the PID Provider) Note that this extension is the same across multiple flows. This endpoint is used by the Wallet to obtain `session_id` from the PID Provider that is used to bind PoPs to the session and prove their freshness. Support for this endpoint is REQUIRED. To fetch the `session_id`, the Wallet MUST send an HTTP request using the POST method and the `application/json` media type. The PID Provider MUST return the HTTP Status Code 200 and a `session_id` parameter defined below. * `session_id`: REQUIRED. String that is a unique session identifier, chosen as a cryptographically random nonce with at least 128 bits of entropy. Communication with the Session Endpoint MUST utilize TLS. Below is a non-normative example of a request to a Session Endpoint: ```http POST /session_endpoint HTTP/1.1 Host: server.example.com Content-Type: application/json ``` Below is a non-normative example of a response from a Session Endpoint: ```http HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "session_id": "iOiJSUzI1NiIsInR" } ``` ### OpenID4VCI Credential Issuer Metadata Note that this extension is the same across multiple flows. This document defines the following additional Credential Issuer Metadata parameters: * `session_endpoint`: REQUIRED. URL of the Credential Issuer's Session Endpoint, as defined in a previous section. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. ## Usability Considerations ### Initialization * The Wallet needs to be initialized on a mandatory basis * During initialization, the user must set a Wallet PIN * Having only one Wallet PIN has the advantage that the same PIN (eID PIN excluded) could probably also be used for other credentials (also at the same LoA). From a UX perspective, this would be a great added value for users. * The wallet can only be used after successful initialization ### Issuance * Credential catalogue should inform users in advance of what is required for the successful issuance of the PID and what steps follow * For reasons of transparency and to increase trust, PID Provider should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the PID Provider itself * eID process is integrated in Wallet. No context switch to the AusweisApp is required * Physical ID card is required for issuing the PID credential * Online-Ausweisfunktion must be activated * eID PIN must be set by the user (replacement of the Transport PIN) and be known to them so that they can successfully confirm the process * User must confirm the process with the eID PIN and the Wallet PIN. The distinction between the two PINs should be easier for users than the distinction between eID PIN and PID PIN * User can have a PID credential derived from the eID on several end devices at the same time ### Presentation * Offline support for PID representation * Relying Party should inform users in advance of what is required for the process to be completed successfully and what steps follow * It needs to be clarified whether the wallet app needs to be unlocked in this flow and how this should be implemented. * For reasons of transparency and to increase trust, Relying Parties should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the relying party itself, privacy and data retention * To be able to display the user's data values for the requested attributes on the consent screen, the wallet must first be unlocked with the wallet PIN (to access data from the SE) * The user only needs to enter the Wallet PIN for each PID presentation * Physical ID card is not required for PID presentation * It must be ensured that users return to the correct tab in the correct browser in order to continue the process or know how to get there manually if necessary (especially for iOS devices, if the process was not started in the default browser) ## Privacy considerations * What is the information that is shared with the wallet provider backend? Is it okay if the backend learn which PID Providers are used? * Multiple device keys must be used to ensure unlinkability across issuers and/or across relying parties * Selective Disclosure is achieved by ensuring that the credential contains only those data items (claims) that are requested by the RP. ## Security considerations * eID Process in the browser means that a remote cooperating party can complete the eID retrieval for the attacker (easier than when used via app) --- ## PID Option C'': Signed Credential with eID Card ## Basic Idea In this design, PID credentials are issued on-demand in ISO mdoc / SD-JWT VC format using the OpenID4VCI protocol and directly presented using the OpenID4VP protocol. While this Option is similar to Option B, the PID credentials are signed by the PID Provider for the specific transaction. The user is authenticated by utilizing the eID card towards the PID Provider in every presentation. In this design, the device key for signing the presentation is generated by the PID Provider in order to achieve a high level of assurance and perform critical key management outside the Wallet. To ensure that the PID Provider does not get to know where a PID credential is used and which claims are provided, the payload of the presentation part (deviceAuth for mdoc or KB-JWT for SD-JWT) is created by the Wallet and only its hash is sent to the PID Provider for signing. This design therefore results in the following properties: - The complexity of implementation is lower for the Wallet, as it does not need to handle and secure the device key. - The PID Provider can enforce that there is exactly one presentation for the PID credential, ensuring a tight binding between the eID Card process and the PID presentation. - It is expected that certification for LoA High is easier for this design, as the PID Provider has full control over all keys and a secure authentication is guaranteed each time via the usage of the eID. Note that this design assumes that the signing algorithm performs a hashing step on the data first; this step is happening at the Wallet, while the rest of the signing is done at the PID Provider. In particular, this works well with ECDSA. ## Credential formats Two solutions are described: - **ISO mdoc:** The ISO mdoc credential format is used with - issuerAuth as issuer data authentication, a COSE_Sign1 signature over the MobileSecurityObject (see ISO 23220-4 7.1.3.4.2.1); containing - an ephemeral key in `deviceKeyInfo` - signed hashes in the `valueDigests` - deviceSignature as mdoc authentication method, a COSE_Sign1 signature over the deviceAuthentication data (see ISO 18013-5 9.1.3.6); containing - the PID data - **SD-JWT VC:** The SD-JWT VC credential format is used with - SD-JWT signed with JWS by the PID Provider; containing - an ephemeral key in `cnf` - the signed hashes in `_sd` arrays - KB-JWT signed by the PID Provider with the Hash; containing - nonce and audience of the Relying Party - a hash of the SD-JWT and the selected disclosures - Disclosures containing the PID data ## Cryptographic Formats (to be defined) ### Issuance Long-Term keys: Transaction-specific keys: Artifacts: ### Presentation Long-Term keys: Transaction-specific keys: Artifacts: ### Dependencies ## Sequence Diagram ### Issuance ```plantuml @startuml 'Lets define some common colors globally !$C_PRT = "#118888" !$C_ARG = "#daa520" !$C_VAR = "#daa520" 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Macro for colored [TLSPSK] block !function tlspsk() !return "[TLS-PSK]" !endfunction 'Macro for colored block !function params($p) !return ""+ $p + "" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title PID presentation over OpenID4VP and On-the-fly PID Issuance over OpenID4VCI with SD-JWT actor u as "User\nOpenID Holder" participant b as "Browser App\n(same device)" participant v [ Relying Party ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ] participant w as "User's EUDI Wallet Instance\n(eID-Client)" participant i [ PID Provider (eService+eID Server) ---- ""Long-term Key: (//pp_pub//, //pp_priv//)"" ] u --> b : browse to application hnote over b #dfd: Screen: same_device_relying_party_start b -> v : tls() HTTP GET v -> v : generate ephemeral key pair (//rp_eph_pub//, //rp_eph_priv//) v -> v : create OpenID4VP Authorization Request,\n sign with //rp_priv//,\n store under note left: Authorization Request includes:\n- presentation_definition\n- purpose\n- state\n- nonce\n- //rp_eph_pub//\n- response_uri v -> v : generate new browser session session_id and bind the authorization request to it v -> b : tls() HTTP 200 HTML containing wallet-link openid4vp://authorize?")\nclient_id=..&request_uri=\nSet-Cookie: sid=session_id u --> b : action to start flow/launch wallet b -> w : launch with wallet-link openid4vp:// note right #fc7: Potential security risk: Wallet app may be spoofed by malicious app hnote over w #dfd: Screen: launch_wallet u --> w : unlock wallet note right: may be moved to later point in flow or removed, see notes. hnote over w #dfd: Screen: unlock_wallet w -> v : tls() HTTP GET note right #fc7: Potential privacy risk: RP learns existence of wallet app and potentially identifying information (e.g., headers) v -> w : tls() HTTP 200 w -> w : validate Authorization Request JWT using //rp_pub// u <--> w : user consent to present PID to Relying Party for given purpose hnote over w #dfd: Screen: consent_present_credential group PID provisioning note over w,i: PID Issuer and EUDI Wallet have inherent trust relationship, metadata may be pre-configured or retrieved w -> w : Wallet fetches fresh wallet attestation from backend w -> i : tls() HTTP POST wallet attestation nonce i -> i : generate and store nonce i -> w : tls() HTTP 200 w -> w : sign wallet attestation PoP JWT (incl. wallet attestation nonce) w -> i : tls() HTTP POST PAR (PKCE code_challenge, wallet attestation JWT, wallet attestation PoP JWT, redirect_uri, either scope or authorization_details i -> i : verify wallet attestation & PoP \ncheck Wallet Provider solution status on trust list i -> w : tls() HTTP 200 request_uri note right : Attestation guarantees with high certainty that Wallet is trustworthy and not manipulated w -> i : tls() HTTP GET hnote over w #dfd: Screen: eid_start group Read eID or Smart eID acc. to BSI TR-03130 i --> w : tls() HTTP 200 starting the eID Process w <-> i : eID Process u <--> w : hnote over w #dfd: Screen: eid_pin w <-> i : eID Process w -> i : tls() HTTP GET finishing the eID process with refreshUrl hnote over w #dfd: Screen: eid_nfc_data end i --> w : tls() HTTP 302 Authorization Response (code) group Generate initial DPoP nonce w -> w : generate ephemeral DPoP key pair //dpop_eph_pub//, //dpop_eph_priv// w -> w : generate placeholder DPoP proof using ephemeral DPoP key pair //dpop_eph_pub//, //dpop_eph_priv// w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> w : tls() HTTP 400 note left : The Wallet should check at this point, whether the Token Endpoint delivered the expected error and nonce. If not, this needs to be handled (retry or abort gracefully). w -> w: store dpop_nonce end w -> w: prepare DPoP proof JWT with //dpop_eph_pub//, dpop_nonce, iat and sign with //dpop_eph_priv// w -> i : tls() HTTP POST Token Request(code, code_verifier, DPoP header) i -> i : generate and store dpop_nonce i -> i : lookup authorization code\ngenerate Token Response with DPoP-bound access token\nverify PKCE challenge i --> w : tls() HTTP 200 w -> w: prepare DPoP proof JWT with //dpop_eph_pub//, dpop_nonce, iat and sign with //dpop_eph_priv// alt #ddf C'': ISO mdoc w -> i : HTTP POST i -> i : lookup access token i -> i : generate ephemeral device key pair (//device_pub//, //device_priv//) i -> i : create mdoc with all eID data attributes and //device_pub//, signed by //pp_priv//, and matching NameSpaceBytes i --> w : tls() HTTP 200 Credential Response(issuerSigned) note right: issuerSigned contains issuerAuth (the signed part, also known as MSO) and nameSpaces (the data elements) w -> w : calculate SessionTranscript (mDocGeneratedNonce, clientId, responseUri, nonce) w -> w : calculate hash of deviceAuth using SessionTranscript and including only selected data elements in nameSpaces w -> i : tls() HTTP POST Presentation Signing Request (deviceAuth hash, DPoP-bound access token) i -> i : create signature over deviceAuth hash using //device_priv// i --> w : tls() HTTP 200 Presentation Signing Response(deviceAuth signature) w -> w : assemble mdoc using deviceAuth and its signature note right: mdoc is ISO18013-5 Document containing issuerAuth and deviceAuth else #dfd C'': SD-JWT VC w -> i : tls() HTTP POST i -> i : lookup access token i -> i : generate ephemeral device key pair (//device_pub//, //device_priv//) i -> i : create SD-JWT with eID data and //device_pub//, signed by //pp_priv// and matching Disclosures i --> w : tls() HTTP 200 Credential Response(SD-JWT) w -> w : calculate hash of KB-JWT using nonce, audience, and sd_hash note right: the SD-JWT+Disclosures are required by the Wallet to calculate sd_hash w -> i : tls() HTTP POST Presentation Signing Request (kb_hash, DPoP-bound access token) note right: Issuer ensures that each device key is only used once and deletes it afterwards i -> i : create KB-JWT signature over kb_hash with //device_priv// i --> w : tls() HTTP 200 Presentation Signing Response(KB-JWT signature) w -> w : assemble KB-JWT using the payload and its signature end end w -> w : create vp_token and presentation_submission w -> w : add mDL presentation according to with to vp_token and presentation_submission note left #AAFFAA: Wallet may add presentations with keys under its own control as the \ncommunication channel between Relying Part and PID Provider is not E2EE w -> v : tls() HTTP POST encrypted v -> v : look up state in existing sessions\ncreate & store response_code for session v --> w : tls() HTTP 200 w -> b : launch browser with hnote over w #dfd: Screen: success_redirect b -> v : tls() HTTP GET \nCookie: sid=session_id v -> v : look up session with session_id and match response_code alt #ddf B.1.1: ISO mdoc v -> v : verify contents of :\n- verify mdoc issuerAuth PID\n- verify deviceAuth with //device_priv// from issuerAuth\n- calculate and validate correct SessionTranscript else #dfd B.1.2: SD-JWT VC v -> v : verify contents of :\n- verify SD-JWT PID\n- verify KB-JWT with //device_priv// from SD-JWT\n- validate nonce and audience from KB-JWT end v --> b : tls() HTTP 200 hnote over b #dfd: Screen: same_device_relying_party_identified @enduml ``` ## Step-by-Step Description Note: While certain assumptions about session management of the Relaying Party are made here, the concrete implementation is considered out of scope for this document. The usual security considerations for web session management apply. 1. User browses to Relying Party (RP) website 2. Browser app on the user's device opens the RP website 3. RP generates a key pair to be used for response encryption 4. RP generates an OpenID4VP Authorization Request and stores it under a `request_uri` (e.g., `https://rp.example.com/oidc/request/1234`); - The request is bound to the user's browser session - It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id - It contains ephemeral key for response encryption - It contains RP's nonce and state - It contains the RP's response_uri endpoint for sending the Authorization Response over POST 5. RP generates a new browser session and binds the generated Authorization Request to it 6. RP returns an HTML page to the browser containing a link to the wallet app (e.g., `openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234`); a cookie with the browser session id is set 7. The user clicks on the link 8. The RP website navigates to the custom scheme link to launch the wallet app 9. The user unlocks the wallet app (see notes below) 10. The wallet app retrieves the Authorization Request from the RP website (e.g., `https://rp.example.com/oidc/request/1234`) 11. The wallet app receives the Authorization Request 12. The wallet app validates the Authorization Request using the RP's public key - Was the signature valid and the key bound to the RP's metadata? - **Security:** This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP. 13. The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the PID. 14. The Wallet fetches fresh wallet attestation from the Wallet Provider backend. 15. The Wallet requests a fresh nonce for the wallet attestation nonce from the PID Provider (wallet attestation nonce). 16. The PID Provider generates a fresh nonce linked to the issuance session. 17. The PID Provider returns the wallet attestation nonce to the Wallet. 18. The Wallet generates a Wallet Attestation PoP and signs it with *dev_priv*; containing - audience - expiration time - wallet attestation nonce 19. The wallet sends the Pushed Authorization Request to the PID Provider; containing - PKCE code_challenge - wallet attestation + PoP - redirect_uri - either scope or an authorization_details parameter requesting the PID 20. The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list. 21. The PID Provider returns a request_uri that is bound to the Pushed Authorization Request. 22. The Wallet sends the Authorization Request; containing - the PAR request_uri 23. The PID Provider responds with the first step to start the eID process with the wallet app, e.g. the tcToken. Note that this is the direct HTTP Response to Step 14. 24. Further communication is exchanged to perform the eID process 25. The user provides the eID PIN to the wallet app. 26. Further communication is exchanged to perform the eID process 27. The eID process is finished and as a final step the Wallet sends a request to the PID Provider calling the refreshURL. From now on Wallet and PID Provider are using the TLS-PSK channel generated by the eID flow. 28. The PID Provider responds to the Wallet with an Authorization Response; containing - the auth code 29. The wallet generates an ephemeral DPoP key pair *dpop_eph_pub*, *dpop_eph_priv*. 30. The Wallet generates a placeholder DPoP proof JWT using the ephemeral DPoP key pair to trigger an error response from the Token endpoint necessary to retrieve the `dpop_nonce`. 31. The Wallet sends a Token Request to the PID Provider, containing the placeholder DPoP proof JWT. 32. The PID Provider generates and stores a `dpop_nonce`. 33. The PID Provider responds with the expected error "use_dpop_nonce", containing the `dpop_nonce` to be used from now on in the DPoP nonce header. 34. The Wallet extracts and stores the `dpop_nonce`. 35. The Wallet now prepares the actual DPoP proof JWT for `dpop_eph_pub` including the `dpop_nonce` and `iat`. 36. The Wallet sends a Token Request to the PID Provider; containing: - the authorization_code from Authorization Response - the PKCE code_verifier matching the code_challenge from Authorization Request - the DPoP header 37. The PID Provider generates and stores a `dpop_nonce`. 38. The PID Provider matches the authorization_code and verifies the PKCE code_verifier to the previously received code_challenge. It then generates an access token bound to the DPoP key. 39. The PID Provider sends a Token Response; containing - DPoP-bound access token - a c_nonce - an authorization_details object, in case the authorization_details parameter was used in the Authorization Request - a fresh `dpop_nonce` in the DPoP nonce header 40. The Wallet prepares a DPoP proof JWT for `dpop_eph_pub` including the `dpop_nonce` and `iat`. 41. **(mdoc)** The Wallet send a Credential Request; containing - DPoP Header with proof - DPoP-bound access token - sessionTranscript - it does not contain a "proof" 42. **(mdoc)** The PID Provider looks up and validates the access token. 43. **(mdoc)** The PID Provider generate an ephemeral DeviceKey pair (*device_pub*,*device_priv*). 44. **(mdoc)** The PID Provider creates the mdoc issuerSigned; containing - issuerAuth (MSO) with the public part of DeviceKey and the hashes of the data elements and signs it with *pp_priv* - nameSpaces with the data elements 45. **(mdoc)** The PID Provider returns the issuerSigned to the Wallet. 46. **(mdoc)** The Wallet calculates the SessionTranscript according to ISO-18013-7 Annex B.4.4 from mDocGeneratedNonce, client_id, responseUri, nonce. The final result is a SHA-256 hash, thus not revealing the client_id and ResponseUri to the PID Provider. 47. **(mdoc)** The Wallet generates the deviceAuth utilizing the SessionTranscript and the requested data elements for nameSpaces and calculates the hash of it 48. **(mdoc)** The Wallet sends the hash of the deviceAuth to the Presentation Signing Endpoint of the PID Provider; the request is protected by a DPoP-bound access token. 49. **(mdoc)** The PID Provider creates the signature for the deviceAuth hash. 50. **(mdoc)** The PID Provider returns the signature to the Wallet. 51. **(mdoc)** The Wallet creates the mdoc using the issuerAuth, the deviceAuth payload and the deviceAuth signature returned by the PID Provider. 52. **(SD-JWT)** The Wallet send a Credential Request; containing - DPoP Header with proof - DPoP-bound access token - it does not contain a "proof" 53. **(SD-JWT)** The PID Provider looks up and validates the access token. 54. **(SD-JWT)** The PID Provider generate an ephemeral DeviceKey pair (*device_pub*,*device_priv*). 55. **(SD-JWT)** The PID Provider creates the issuer-signed part of the SD-JWT and signs it with *pp_priv*; containing - eID as the user claims - *device_pub* as cnf claim 56. **(SD-JWT)** The PID Provider sends the Credential Response; containing: - SD-JWT VC PID with Disclosures 57. **(SD-JWT)** The Wallet creates the header and payload for the KB-JWT from audience, nonce, and the hash of SD-JWT and selected disclosures and hashes it. The Wallet appends the KB-JWT to the SD-JWT. Note that this step can only happen after the SD-JWT has been issued and received by the Wallet, as the KB-JWT payload includes the *sd_hash* parameter, that is a hash over issuerSigned JWT and the Disclosures. 58. **(SD-JWT)** The Wallet sends a Request to the Presentation Signing Endpoint transmitting the hash of the KB-JWT. The request is protected by a DPoP-bound access token. 59. **(SD-JWT)** The PID Provider recognizes the device key from the provided public key reference and uses *device_priv* to create the signature of the KB-JWT using the hash of the KB-JWT. Afterwards, it must ensure that the device key pair is deleted and not used again. 60. **(SD-JWT)** The PID Provider sends the response containing the signature of KB-JWT. 61. **(SD-JWT)** The Wallet assembles the PID presentation from SD-JWT and KB-JWT payload/signature. 62. The wallet app creates a VP token and a presentation submission from the received SD-JWT PID. 63. Optional: The wallet app can add further presentations with keys under its own control as the communication channel between Relying Part and PID Provider is not E2EE 64. The wallet app sends the VP token and presentation submission to the RP (encrypted to the RP's public key *rp_eph_pub*). 65. The RP finds a session with the state and generates a response_code for this session. 66. The RP returns the redirect_uri with the response_code to the wallet app. 67. The wallet app launches the browser with the redirect_uri and response_code. 68. The browser sends the redirect_uri and response code to the RP, attaching the browser session id as a cookie. 69. The RP looks up whether there exists a session with the session id from the cookie and a matching response_code 70. **(mdoc)** The RP verifies the PID in the VP token with the MAC key and verifies the SessionTranscript calculated from nonce, mDocGeneratedNonce, clientID, response_uri. 71. **(SD-JWT)** The RP verifies the SD-JWT PID in the VP token with the MAC key, verifies the KB-JWT using the *kb_eph_pub* in the SD-JWT, and verifies the nonce and audience in the KB-JWT 72. The RP considers the user to be identified in the session context and continues the UX flow. ## Extensions to the Protocols ### Issuer Session Endpoint (at the PID Provider) Note that this extension is the same across multiple flows. This endpoint is used by the Wallet to obtain `session_id` from the PID Provider that is used to bind PoPs to the session and prove their freshness. Support for this endpoint is REQUIRED. To fetch the `session_id`, the Wallet MUST send an HTTP request using the POST method and the `application/json` media type. The PID Provider MUST return the HTTP Status Code 200 and a `session_id` parameter defined below. - `session_id`: REQUIRED. String that is a unique session identifier, chosen as a cryptographically random nonce with at least 128 bits of entropy. Communication with the Session Endpoint MUST utilize TLS. Below is a non-normative example of a request to a Session Endpoint: ```http POST /session_endpoint HTTP/1.1 Host: server.example.com Content-Type: application/json ``` Below is a non-normative example of a response from a Session Endpoint: ```http HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "session_id": "iOiJSUzI1NiIsInR" } ``` ### Presentation Signing Endpoint This endpoint is used by the Wallet to obtain a signature over the KB-JWT or deviceAuth structure. Support for this endpoint is REQUIRED. Communication with this endpoint MUST use TLS and this endpoint MUST be protected using the DPoP-bound access token, similar to the Credential Endpoint. To fetch the bytes of the signature, the Wallet MUST send an HTTP request using the POST method and the `application/json` media type. The request contains a JSON-encoded object with the following parameters: - `hash_bytes`: REQUIRED. base64url-encoded bytes of the hash over the bytes of the deviceAuth structure or the KB-JWT structure, respectively. Note that the hash algorithm MUST be matched to the signing algorithm used by the PID Provider for signing the deviceAuth or KB-JWT structure. The PID Provider MUST return the HTTP Status Code 200 and a `signature_bytes` parameter defined below. - `signature_bytes`: REQUIRED. base64url-encoded bytes of the signature over the deviceAuth or KB-JWT, respectively. ### OpenID4VCI Credential Issuer Metadata Note that this extension is the same across multiple flows. This document defines the following additional Credential Issuer Metadata parameters: - `session_endpoint`: REQUIRED. URL of the Credential Issuer's Session Endpoint, as defined in a previous section. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. - `presentation_signing_endpoint`: REQUIRED: URL of the Presentation Signing Endpoint, as defined above. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. ## Usability Considerations ## Privacy Considerations ## Security Considerations ## Open Topics --- ## PID Option C: Signed Credential with Secure Element ## Basic Idea In this flow, long-lived, digitally signed PID credentials in ISO mdoc and IETF SD-JWT VC formats are issued to the Wallet Instance utilizing the OpenID4VCI protocol. During the issuance, the user is authenticated using the eID card, so when these PID credentials are presented to the Relying Parties over OpenID4VP protocol, there is no need for the user to use physical eID card. This flow trusts Wallet Instance to manage the keys on the device without Wallet Backend's involvement (unlike Option C'). To improve user experience and prevent the users from having to tap an eID card every time a batch of Credentials needs to be refreshed and tapping an eID card as many times as there are Credentials in a batch, a concept of Seed Credential is introduced. A Seed Credential is used to acquire a set of single-use Batch Credentials from the Provider. The Wallet can then present these Batch Credentials to the Relying Parties. The user only needs to present the physical ID card once - to acquire the Seed Credential - instead of every presentation. Such Seed Credential is issued by a PID Provider to the Wallet as a signed DPoP-bound refresh token and can be stored for a longer period. The refresh token is bound to the key stored on the wallet device itself. Wallet Attestation PoP and DPoP Proof are bound to the keys managed by the wallet device. Because the PID is long lived, the [revocation](../00-pid-issuance-and-presentation/index.md#revocation) implementation is crucial. ## Credential formats Two solutions are described: - **ISO mdoc** The ISO mdoc credential format is used with - issuerAuth as issuer data authentication, a COSE_Sign1 signature over the MobileSecurityObject (see ISO 23220-4 7.1.3.4.2.1); containing - the Wallets long-lived key in `deviceKeyInfo` - signed hashes in the `valueDigests` - deviceSignature as mdoc authentication method, a COSE_Sign1 MAC over the deviceAuthentication data (see ISO 18013-5 9.1.3.5) - containing the PID data - **SD-JWT VC** The SD-JWT VC credential format is used with - SD-JWT signed with JWS by the PID Provider; containing - the Wallets long-lived key in `cnf` - the signed hashes in `_sd` arrays - the Disclosures containing the PID data ## Cryptographic Formats ### Issuance Long-Term keys: - PID Provider has long-term key pair $(pp\_pub, pp\_priv)$ which is used - to sign over the issued Credential - to sign over the Refresh Token JWT - RP has long-term key pair $(rp\_pub, rp\_priv)$ which is used - to sign over the authorization request, authenticating its contents - Wallet app has device key pair $(device\_pub, device\_priv)$ which is used - to generate proof of possession of a Credential - Wallet app has device key pair $(device\_dpop\_pub, device\_dpop\_priv)$ which is used - to generate proof of possession of a Refresh Token ## Artifacts ### Issuance of a Credential - PID Provider issues SD-JWT (plus Disclosures): $sd\_jwt := \text{sign}(\mathit{hashed\_eID\_data}, device\_pub)_{pp\_priv}$ ### Issuance of the Refresh Token - PID Provider issues a refresh token: $refresh\_token := \text{sign}((eID\_data)_{pp\_data}, expiration)_{pp\_priv}$. The refresh token itself is bound to $device\_dpop\_priv$ via DPoP token binding mechanisms. **Note that the content of the refresh token needs to be protected against modification.** ### Presentation - $kb\_jwt := \text{sign}(nonce, audience, \text{hash}(sd\_jwt, disclosures))_{device\_priv}$ ### Dependencies *TODO: May want to expand to include metadata.* ```plantuml digraph G { subgraph cluster_pid_provider { style=filled color=lightblue label="PID Provider" pp [label="🗝 (pp_priv, pp_pub)"] user_data [label="eID data"] } subgraph cluster_wallet { style=filled color=lightgreen label="Wallet" nonce_audience [label="nonce, audience"] dpop [label="DPoP proof (dpop_nonce)"] dev [label="🗝 (device_pub, device_priv)"] dpop_key [label="🗝 (dpop_priv, dpop_pub)"] } pp -> dev [label="sign (SD-JWT)"] pp -> user_data [label="sign (SD-JWT)"] dev -> nonce_audience [label="sign (KB-JWT)"] dpop_key -> dpop [label="sign"] } ``` Note: Wallet attestation not shown in this chart. ## Sequence Diagrams and Step-by-Step Description of Each Step Each step of the protocol will be explained using a sequence diagram followed by a step-by-step description. ### Wallet Activation To initialize the wallet, the Wallet obtains wallet attestation as defined in [Wallet Attestation](Wallet-Attestation.md). ### Issuance #### [Sequence Diagram] Issuance [User Journey: PID Issuance - Issuer Signed](../../../user_journeys/PID-IssuerSigned-issuance.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 500 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title PID Issuance over OpenID4VCI using Issuer-Signed Credentials (generic) actor u as "User\nOpenID Holder" participant wscd [ Wallet Secure Cryptographic Device (WSCD) ---- Long-term Key: (//device_pub//, //device_priv//) ] participant w as "User's EUDI Wallet Instance\n(eID-Client)" participant i [ PID Provider (eService+eID Server) ---- Long-term Key: (//pp_pub//, //pp_priv//) ] u --> w : open wallet, unlock wallet hnote over w #dfd: Screen: launch_wallet hnote over w #dfd: Screen: unlock_wallet u --> w : request issuance of PID hnote over w #dfd: Screen: credential_catalog note over w,i: PID Issuer and EUDI Wallet have inherent trust relationship, metadata may be pre-configured or retrieved w -> i : tls() HTTP POST wallet attestation nonce i -> i : generate and store nonce i --> w : tls() HTTP 200 w <-> wscd : get proof of possession for wallet attestation (wallet attestation nonce) note right : Attestation guarantees with high certainty that Wallet is trustworthy and not manipulated w -> i : tls() HTTP POST PAR (client_id, code_challenge, wallet attestation+PoP, either scope or authorization_details) i -> i : verify wallet attestation and check Wallet Provider solution status on trust list i --> w : tls() HTTP 200 request_uri w -> i : tls() HTTP GET hnote over w #dfd: Screen: consent_add_credential hnote over w #dfd: Screen: eid_start group Read eID or Smart eID acc. to BSI TR-03130 i --> w : tls() HTTP 200 starting the eID Process w <-> i : eID Process u <--> w : hnote over w #dfd: Screen: eid_pin w <-> i : eID Process w -> i : tls() HTTP GET finishing the eID process with refreshUrl hnote over w #dfd: Screen: eid_nfc_data end i --> w : tls() HTTP 302 group Generate initial DPoP nonce w -> w : generate placeholder DPoP proof with generic (not WSCD-bound) key pair w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> w : tls() HTTP 400 note left : The Wallet should check at this point, whether the Token Endpoint delivered the expected error and nonce. If not, this needs to be handled (retry or abort gracefully). w -> w: store dpop_nonce end 'generate DPoP proof with DPoP key group WSCD w <-> wscd: generate DPoP key pair (//dpop_pub//, //dpop_priv//) w -> w: prepare DPoP proof for WSCD bound DPoP key incl. dpop_nonce and iat w -> w: hash(DPoP proof for WSCD bound key) w -> wscd: sign hash of DPoP proof wscd -> wscd: sign hash of DPoP proof with //dpop_priv// wscd --> w: signed hash of DPoP proof w -> w: assemble DPoP proof JWT for WSCD bound key with signature end w -> i : tls() HTTP POST i -> i : lookup authorization code\ngenerate Token Response with DPoP-bound access token\nverify PKCE challenge i --> w : tls() HTTP 200 w <-> wscd : generate device binding key pair (//device_pub//, //device_priv//) and proof of possession with c_nonce hnote over w #dfd: Screen: device_authenticator w -> w : generate credential response encryption key pair (//cre_eph_pub//, //cre_eph_priv//) w -> w : create credential_response_encryption object with jwk containing //cre_eph_pub// w -> i : tls() HTTP POST i -> i : lookup access token and validate key proof alt #ddf C: ISO mdoc i -> i : create mdoc with eID data and //device_pub//, signed by //pp_priv//, and matching NameSpaceBytes i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i -> i : generate and store dpop_nonce i -> w : tls() HTTP 200 mdoc))> else #dfd C: SD-JWT VC i -> i : create SD-JWT VC with eID data and //device_pub//, signed by //pp_priv//, and matching Disclosures i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i -> i : generate and store dpop_nonce i --> w : tls() HTTP 200 SD-JWT VC, Disclosures))> end w -> w : decrypt credential response JWT w -> w : store PID credential note left #FFAAAA: PID is signed data w -> w: store dpop_nonce hnote over w #dfd: Screen: success hnote over w #dfd: Screen: home @enduml ``` #### [Step-by-Step Description] Issuance 1. The user opens and unlocks the Wallet. 2. The user browses through the pre-configured credential catalogue and chooses to request a PID. 3. The Wallet requests a fresh nonce for the wallet attestation nonce (wallet attestation). 4. The PID Provider generates a fresh nonce linked to the issuance session. 5. The PID Provider returns the wallet attestation nonce to the Wallet. 6. The Wallet performs a wallet attestation. - Optionally it fetches a new wallet attestation from the Wallet Provider if none exists yet. - It generates a proof of possession (PoP) for the public key of the wallet attestation using its WSCD. 7. The Wallet sends the Pushed Authorization Request to the PID Provider containing - the Wallet Provider's client_id, - the authorization_details for PID, - a PKCE code_challenge, - a wallet attestation and proof of possession, - either scope or an authorization_details parameter requesting the PID. 8. The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list. 9. The PID Provider returns a request_uri that is bound to the Pushed Authorization Request. 10. The Wallet sends the Authorization Request containing - the PAR request_uri. 11. The PID Provider responds with the first step to start the eID process with the wallet app, e.g. the tcToken. Note that this is the direct HTTP Response to Step 14. 12. Further communication is exchanged to perform the eID process. 13. The user provides the eID PIN to the wallet app. 14. Further communication is exchanged to perform the eID process. 15. The eID process is finished and as a final step the Wallet sends a request to the PID Provider calling the refreshURL. From now on Wallet and PID Provider are using the TLS-PSK channel generated by the eID flow. 16. The PID Provider responds to the Wallet with an Authorization Response containing - the auth code. 17. The Wallet generates (and stores) a placeholder DPoP proof JWT using a generic (not HSM-bound) keypair to trigger an error response from the Token endpoint necessary to retrieve the `dpop_nonce`. 18. The Wallet sends a Token Request to the PID Provider, containing the placeholder DPoP proof JWT. 19. The PID Provider generates and stores a `dpop_nonce`. 20. The PID Provider responds with the expected error "use_dpop_nonce", containing the `dpop_nonce` to be used from now on in the DPoP nonce header. 21. The Wallet extracts and stores the `dpop_nonce`. 22. The Wallet generates a new key pair for DPoP (*dpop_pub*, *dpop_priv*). 23. The Wallet now prepares the actual DPoP proof for the WSCD bound `dpop_pub` including the `dpop_nonce` and `iat`. 24. The Wallet hashes the DPoP proof. 25. The Wallet sends a request to the WSCD to sign the hash of the DPoP proof for the WSCD bound key. 26. The WSCD signs the hash of the DPoP proof for the WSCD bound key with *dpop_priv*. 27. The WSCD returns the signed hash of the DPoP proof for the WSCD bound key to the Wallet. 28. The Wallet assembles the DPoP proof JWT for the WSCD bound key using the signature received in the previous step. 29. The Wallet sends a Token Request to the PID Provider containing - the auth_code from Authorization Response, - the PKCE code_verifier matching the code_challenge from Authorization Request, - the wallet attestation and proof of possession, - a DPoP JWT. 30. The PID Provider matches the code, verifies the PKCE code_verifier to the previously received code_challenge and verifies the wallet attestation. It then generates an access token bound to the DPoP key. 31. The PID Provider sends a Token Response containing - DPoP-bound access token and - a c_nonce, - an authorization_details object, in case the authorization_details parameter was used in the Authorization Request. 32. The Wallet generates a new key pair for device binding (*device_pub*, *device_priv*) and signs the c_nonce using its WSCD. 33. The Wallet generates a new ephemeral keypair (*cre_eph_pub*, *cre_eph_priv*). 34. The Wallet creates the `credential_response_encryption` JSON object containing the following information: - a jwk containing the *cre_eph_pub* - the JWE alg parameter - the JWE enc parameter 35. The Wallet sends a Credential Request to the PID Provider containing - the DpoP-bound access token, - the device binding key *device_pub* and the proof of possession and - the `credential_response_encryption` object. 36. The Issuer validates the access token and the proof of possession. 37. **(mdoc)** The PID Provider creates the mdoc by signing with *pp_priv* containing - the issuerAuth with the *device_pub* as deviceKey and hashes of the eID data, - the eID data as NameSpaceBytes and - the status management information 38. **(mdoc)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID as mdoc to the payload. 39. **(mdoc)** The PID Provider generates and stores a fresh `dpop_nonce`. 40. **(mdoc)** The PID Provider sends the Credential Response JWT containing - the PID as mdoc and 41. **(SD-JWT)** The PID Provider creates SD-JWT VC by signing with *pp_priv* containing - the SD-JWT with the *device_pub* as confirmation claim and hashes of the eID data, - the eID data as Disclosures and - the status management information 42. **(SD-JWT)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID as SD-JWT VC to the payload. 43. **(SD-JWT)** The PID Provider generates and stores a fresh `dpop_nonce`. 44. **(SD-JWT)** The PID Provider sends the Credential Response JWT containing - the PID as SD-JWT VC. 45. The Wallet decrypts the Credential Response JWT using the *cre_eph_priv* and retrieves the PID. 46. The Wallet stores the PID credential. 47. The wallet stores the `dpop_nonce`. ### Presentation #### [Sequence Diagram] Presentation [User Journey: PID Presentation - Issuer Signed](../../../user_journeys/PID-IssuerSigned-presentation.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title PID presentation over OpenID4VP actor u as "User\nOpenID Holder" participant b as "Browser App\n(same device)" participant v [ Relying Party ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ] participant w [ User's EUDI Wallet Instance (eID-Client) ---- ""Device binding Key: (//device_pub//, //device_priv//)"" ] participant wscd as "Wallet Secure Cryptographic Device\n(WSCD)" u --> b : browse to application hnote over b #dfd: Screen: same_device_relying_party_start b -> v : tls() HTTP GET v -> v : generate ephemeral key pair (//rp_eph_pub//, //rp_eph_priv//) v -> v : create OpenID4VP Authorization Request,\n sign with //rp_priv//,\n store under note left: Authorization Request includes:\n- presentation_definition\n- purpose\n- state\n- nonce\n- //rp_eph_pub// \n- response_uri v -> v : generate new browser session session_id and bind the authorization request to it v --> b : tls() HTTP 200 HTML containing wallet-link openid4vp://authorize?")\nclient_id=..&request_uri=\nSet-Cookie: sid=session_id u --> b : action to start flow/launch wallet b -> w : launch with wallet-link openid4vp:// note right #fc7: Potential security risk: Wallet app may be spoofed by malicious app hnote over w #dfd: Screen: launch_wallet u --> w : unlock wallet note right: may be moved to later point in flow or removed, see notes. hnote over w #dfd: Screen: unlock_wallet w -> v : tls() HTTP GET note right #fc7: Potential privacy risk: RP learns existance of wallet app and potentially identifying information (e.g., headers) v --> w : tls() HTTP 200 w -> w : validate Authorization Request JWT using //rp_pub// u <--> w : user consent to present PID to Relying Party for given purpose hnote over w #dfd: Screen: consent_present_credential hnote over w #dfd: Screen: device_authenticator alt #ddf B.1.1: ISO mdoc w -> w : prepare mdoc presentation according to by removing unnecessary NameSpaceBytes w -> w : calculate SessionTranscript (mDocGeneratedNonce, clientId, responseUri, nonce) and generate deviceAuth payload else #dfd B.1.2: SD-JWT VC w <-> w : prepare SD-JWT presentation according to by removing unnecessary Disclosures w <-> w : generate KB-JWT payload (nonce, audience and hash of SD-JWT and disclosures) end w <-> wscd : sign payload with //device_priv// alt #ddf C: ISO mdoc w -> w : assemble deviceAuth and build presentation with issuerSigned and deviceSigned(deviceAuth) else #dfd C: SD-JWT VC w -> w : assemble KB-JWT and build presentation with SD-JWT, selected Disclosures and KB-JWT end w -> w : create vp_token and presentation_submission w -> w : add optionally other presentations according to the presentation_definition w -> v : tls() HTTP POST encrypted v -> v : look up state in existing sessions\ncreate & store response_code for session v --> w : tls() HTTP 200 w -> b : launch browser with hnote over w #dfd: Screen: success_redirect b -> v : tls() HTTP GET \nCookie: sid=session_id v -> v : look up session with session_id and match response_code alt #ddf B.1.1: ISO mdoc v -> v : verify contents of :\n- verify mdoc issuerAuth PID\n- verify deviceAuth with //device_priv// from issuerAuth\n- calculate and validate correct SessionTranscript else #dfd B.1.2: SD-JWT VC v -> v : verify contents of :\n- verify SD-JWT PID\n- verify KB-JWT with //device_priv// from SD-JWT\n- validate nonce and audience from KB-JWT end v --> b : tls() HTTP 200 hnote over b #dfd: Screen: same_device_relying_party_identified @enduml ``` #### [Step-by-Step Description] Presentation Note: While certain assumptions about session management of the Relaying Party are made here, the concrete implementation is considered out of scope for this document. The usual security considerations for web session management apply. 1. The user browses to Relying Party (RP) website 2. Browser app on the user's device opens the RP website 3. RP generates a key pair to be used for ECDH key agreement for SD-JWT HMAC'ing 4. RP generates an OpenID4VP Authorization Request and stores it under a `request_uri` (e.g., `https://rp.example.com/oidc/request/1234`); - The request is bound to the user's browser session - It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id - It contains the ephemeral key for response encryption - It contains RP's nonce and state - It contains the RP's response_uri endpoint for sending the Authorization Response over POST 5. RP generates a new browser session and binds the generated Authorization Request to it 6. RP returns a HTML page to the browser containing a link to the wallet app (e.g., `openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234`); a cookie with the browser session id is set 7. The user clicks on the link 8. The RP website navigates to the custom scheme link to launch the wallet app 9. The user unlocks the wallet app (see notes below) 10. The wallet app retrieves the Authorization Request from the RP website (e.g., `https://rp.example.com/oidc/request/1234`) 11. The wallet app receives the Authorization Request 12. The wallet app validates the Authorization Request using the RP's public key - Was the signature valid and the key bound to the RP's metadata? - **Security:** This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP. 13. The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the PID. 14. **(mdoc)** The Wallet prepares an mdoc presentation according to the presentation_definition by removing NameSpaceBytes of not disclosed attributes. 15. **(mdoc)** The Wallet calculates the SessionTranscript according to ISO-18013-7 Annex B.4.4 from mDocGeneratedNonce, client_id, responseUri, nonce and generates the deviceAuthentication structure from SessionTranscript and NameSpaceBytes for signing. 16. **(SD-JWT)** The Wallet generates an SD-JWT VC presentation according to the presentation_definition by removing Disclosures of not disclosed attributes. 17. **(SD-JWT)** The Wallet creates the header and payload for the KB-JWT from audience, nonce, hash of issuer-signed JWT+Disclosures for signing. 18. The Wallet signs the payload with *device_priv*. 19. **(mdoc)** The Wallet assembles the deviceAuth from header, payload and signature and builds the presentation from deviceAuth and issuerSigned 20. **(SD-JWT)** The Wallet assembles the KB-JWT from header, payload and signature and builds the SD-JWT VC presentation from issuer-signed JWT, Disclosures and KB-JWT 21. The wallet app creates a VP token and a presentation submission from the received SD-JWT PID. 22. Optional: The wallet app can add further presentations 23. The wallet app sends the VP token and presentation submission to the RP (encrypted to the RP's public key *rp_eph_pub*). 24. The RP finds a session with the state and generates a response_code for this session 25. The RP returns the redirect_uri with the response_code to the wallet app 26. The wallet app launches the browser with the redirect_uri and response_code. 27. The browser sends the redirect_uri and response code to the RP, attaching the browser session id as a cookie. 28. The RP looks up whether there exists a session with the session id from the cookie and a matching response_code 29. **(mdoc)** The RP verifies the PID in the VP token and verifies the SessionTranscript calculated from nonce, mDocGeneratedNonce, clientID, response_uri. 30. **(SD-JWT)** The RP verifies the SD-JWT PID in the VP token, verifies the KB-JWT using the *device_priv* in the SD-JWT, and verifies the nonce and audience in the KB-JWT 31. The RP considers the user to be identified in the session context and continues the UX flow. ## Extensions to the Protocols This section defines extensions to the protocols required to implement this flow (Option C). ### Issuer Session Endpoint (at the PID Provider) Note that this extension is the same across multiple flows. This endpoint is used by the Wallet to obtain `session_id` from the PID Provider that is used to bind PoPs to the session and prove their freshness. Support for this endpoint is REQUIRED. To fetch the `session_id`, the Wallet MUST send an HTTP request using the POST method and the `application/json` media type. The PID Provider MUST return the HTTP Status Code 200 and a `session_id` parameter defined below. - `session_id`: REQUIRED. String that is a unique session identifier, chosen as a cryptographically random nonce with at least 128 bits of entropy. Communication with the Session Endpoint MUST utilize TLS. Below is a non-normative example of a request to a Session Endpoint: ```http POST /session_endpoint HTTP/1.1 Host: server.example.com Content-Type: application/json ``` Below is a non-normative example of a response from a Session Endpoint: ```http HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "session_id": "iOiJSUzI1NiIsInR" } ``` ### OpenID4VCI Credential Issuer Metadata Note that this extension is the same across multiple flows. This document defines the following additional Credential Issuer Metadata parameters: - `session_endpoint`: REQUIRED. URL of the Credential Issuer's Session Endpoint, as defined in a previous section. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. ## Usability Considerations ### Issuance - Credential catalogue should inform users in advance of what is required for the successful issuance of the PID and what steps follow - For reasons of transparency and to increase trust, PID Provider should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the PID Provider itself, privacy and data retention - eID process is integrated in Wallet. No context switch to the AusweisApp is required - Physical ID card is required for issuing the PID credential - Online-Ausweisfunktion must be activated - eID PIN must be set by the user (replacement of the Transport PIN) and be known to them so that they can successfully confirm the process - User must confirm the process with the eID PIN and the device authenticator - User can have a PID credential derived from the eID on several end devices at the same time ### Presentation - Offline support for PID representation - Relying Party should inform users in advance of what is required for the process to be completed successfully and what steps follow - It needs to be clarified whether the wallet app needs to be unlocked in this flow, as the device authenticator is requested again directly after the consent screen. This might create friction and feel redundant to users - For reasons of transparency and to increase trust, Relying Parties should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the relying party itself, privacy and data retention - The user's data values for the requested attributes can be displayed on the consent screen - The user only needs to confirm the PID presentation with the Device Authenticator - Physical ID card is not required for PID presentation - It must be ensured that users return to the correct tab in the correct browser in order to continue the process or know how to get there manually if necessary (especially for iOS devices, if the process was not started in the default browser) ## Privacy Considerations - Unobservability: - Issuer: the issuer-signed credentials are under sole control of the Wallet, the usage of credentials is not recognized by the Issuer, even when revocation is used - Wallet Provider: see specific sub-options - Unlinkability: - Outsider: Both OpenID4VCI and OpenID4VP are entirely encrypted using TLS, an outsider is therefore *not* able to link any transactions apart from the low-level network traffic itself - Relying Party: the same Relying Party will *not* be able to link transactions when batch-issued single use credentials are issued - Issuer: the PID Issuer will be able to link the transactions - Colluding Relying Parties: colluding Relying Parties will *not* be able to link transactions when batch-issued single use credentials are issued - Colluding Issuers: colluding issuers will *not* be able to link transactions when ephemeral or issuer-specific wallet attestations are used - Colluding Relying Party and Issuer: colluding PID Provider and Relying Party will be able to link transactions due to the nature of SD-JWT VC and ISO mdoc cryptography - Repudiation: - Repudiation of Data Authenticity: issuer-signed credentials are not repudiable due to the nature of signature algorithms. This may be mitigated by key publication, but is currently out of scope - Repudiation of User binding: in the current design presentations are not repudiable due to the use of signature algorithms for key binding. ISO mdoc has the option to use deviceMac, which is currently not in scope. - Selective Disclosure: both SD-JWT VC and ISO mdoc achieve selective disclosure by ensuring that the Wallet contains only those attributes (claims) that are requested by the Relying Party ## Security Considerations - Level of Assurance: - Unforgeability of Credentials: unforgeability is guaranteed by the signature of the issuer-signed credential, i.e. the SD-JWT or the issuerSigned - Freshness of Presentations: freshness is guaranteed by the nonce provided by the Relying Party, which is integrated in the KB-JWT or deviceAuth, see [replay prevention](https://openid.github.io/OpenID4VP/openid-4-verifiable-presentations-wg-draft.html#name-preventing-replay-of-the-vp). - User Binding of presentations: see specific sub-options - Session Integrity: - Issuance: PID Provider and Wallet share a pre-configured trust relationship, established through certificate pinning and other mechanisms - Presentation: Session Integrity is supported by OpenID4VP through browser redirect, see [session fixation](https://openid.github.io/OpenID4VP/openid-4-verifiable-presentations-wg-draft.html#name-session-fixation). - further topics: - In Presentation Step 008, a malicious app may spoof the wallet app; an attacker may - **on the attacker's own device:** Capture the request and replay it to a victim on another device, thus having the victim identify itself in a context of the attacker (**Relaying Attack breaking Identification Context**); or - **on the victim's device:** Capture the request and spoof the whole identification process or parts of it (**Wallet App Spoofing**). - In Presentation Step 008: An attacker acting as an RP can forward a request from a different RP. - As long as the request remains unchanged, we're in the **Relaying Attack breaking Identification Context** - If the attacker changes anything in the request, this will break the signature. The attacker could otherwise attempt to - insert the attacker's own ephemeral key, leading to an SD-JWT artifact that could be used in a different flow between the attacker and some other RP. - modify state or nonce or other data. **Q:** Any useful attacks resulting from this? - In Presentation Step 024: The RP must not consider the user identified at this point; it is important to have the browser redirect in the later steps. ## Open Topics - integrate revocation mechanisms - Security of PID Provider Interface in Issuance Step 3ff: - Are additional steps required to protect the interface to the PID Provider? - What exactly is the transaction binding? - How is the eID process tied to the process at the PID provider? --- ## Presentation during Issuance The PID/(Q)EAA Provider might want to request presentation of the credential(s) as a means to authenticate the user during the issuance of another credential. This document extends a [dynamic credential request](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-dynamic-credential-request) in OID4VCI using the [OAuth 2.0 for First-Party Applications](https://www.ietf.org/archive/id/draft-parecki-oauth-first-party-apps-02.html). By doing so, it allows to start an OID4VP flow using the OID4VCI authorization request during the authorization code flow and to improve the user experience with a browser-less approach. Below is a non-normative diagram illustrating the flow (it includes only the components relevant to the illustration of the flow described in this document): ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title Presentation during issuance participant w [ Wallet ] participant ci [ Credential Issuer ] participant as [ Authorization Server ] participant ov [ OID4VP Verifier ] w -> ci: select credential to receive ci -> w: credential offer\n w -> ci: tls() HTTP GET ./well-known Credential Issuer Metadata ci -> w: tls() HTTP 200 alt optional wallet attestation note over w, ci: Wallet attestation, see [[../EAA-Issuance-OpenID4VC#sequence-diagram]] end w -> as: tls() HTTP POST note over as,ov : generate OID4VP authorization request group OID4VP flow as -> w: tls() HTTP 400 w -> ov: tls() HTTP POST ov -> w: tls() HTTP 200 else credentials not present w -> ov: tls() HTTP POST w -> as: tls() HTTP POST note over as,ov: Authorization Server get's information about the session from the OID4VP Verifier. It can decide how to proceed. end w -> as: tls() HTTP POST as -> w: tls() HTTP 200 w -> as: tls() HTTP POST as -> w: tls() HTTP 200 w -> ci: tls() HTTP POST ci -> w: tls() HTTP 200 @enduml ``` ## Step-by-Step Description 1. The Wallet selects the credential it wants to receive. 2. Optionally, the Credential Issuer sends a credential offer to the Wallet. 3. The Wallet obtains the Credential Issuer's metadata. 4. The Credential Issuers responds with the metadata. 5. The Wallet sends the [Authorization Challenge Request](https://www.ietf.org/archive/id/draft-parecki-oauth-first-party-apps-02.html#name-authorization-challenge-req) to the Authorization Challenge Endpoint of the Issuer's Authorization Server using HTTP POST. - See [Appendix](#example-authorization-challenge-request) for an example request. - In case a wallet attestation is required by the Issuer, it has to be included in this request. The Issuer has to track in the session that the wallet attestation was provided. 6. The Issuer determines whether the information provided to the Authorization Challenge Endpoint is sufficient to grant authorization for the credential issuance. If the presentation of other credential(s) is required, the Issuer generates presentation request for those credential(s), and sends it to the Wallet in the Authorization Challenge Error Response. It uses [presentation](#presentation) parameter defined in this document to do so. - The Issuer is acting as a Relying Party to the Wallet when it is requesting credential presentation. The exact architecture and the deployment of the Issuer's Authorization Server in OID4VCI and RP in OID4VP is out of scope of this flow: they can be different services or the same service. - The [auth_session](#auth_session) value from the OID4VCI flow can be used by the Issuer for state management between issuance and presentation flows. - The RP will start the OID4VP flow with the steps from [EAA Presentation OpenID4VC](../../features/EAA/EAA-Presentation-OpenID4VC.md), with the steps 4 to 5. - An example Authorization Challenge Response is in the [Appendix](#example-authorization-error-response). 7. In case the Wallet is able to present the required credential, it will send and authorization request to the RP. 8. In case the Wallet is not able to present the credentials - The Wallet will respond with an [Error response](#example-error-response), including the [auth_session](#auth_session) value and the error code to the RP. 9. The Wallet will send another authorization challenge including the [auth_session](#auth_session) value to the Issuer's Authorization Server like in step 4. - The Issuer has to contact the RP to get information about the state of the session and to decide how to proceed (creating a new presentation request, send a redirect to the browser, etc.). 10. If the RP has successfully processed the Authorization Response or Authorization Error Response, it responds with a status code 200 as defined in OID4VP. When doing so, the RP MUST send information about the session in `presentation_during_issuance_session` parameter in the body of the response. - The content of the [presentation_during_issuance_session](#presentation_during_issuance_session) parameter is out of scope of this document. It could be the Verifiable Presentation itself represented as a JWT, or a state or nonce from the presentation session. - The content of this parameter is opaque to the wallet. - See [Appendix](#example-validation-response) for an example response. 11. The Wallet sends the request to the Authorization Challenge Endpoint of the Issuer by issuing a POST request via the Wallet with the [auth_session](#auth_session). - See [Appendix](#example-authorization-challenge-request-with-session) for an example request. - The Wallet will use the value from the response and pass it in the [presentation_during_issuance_session](#presentation_during_issuance_session) parameter. 12. The Issuer validates the request, and in case of a successful validation response with an [authorization code](https://www.ietf.org/archive/id/draft-parecki-oauth-first-party-apps-02.html#name-authorization-code-response). 13. The Wallet makes a request to the Token Endpoint of the Issuer to exchange the authorization code for an access token. 14. The Authorization Server responds with a [Token Response](https://www.ietf.org/archive/id/draft-parecki-oauth-first-party-apps-02.html#name-token-endpoint-successful-r). - An example response is in the [Appendix](#example-token-response). 15. The Wallet sends the Credential Request to the Issuer. 16. The Issuer sends the Credential Response to the Wallet. ## Known limitations This flow is based on the "OAuth 2.0 for First-Party Applications" draft, and aims for a browser-less approach to improve user experience. This comes with the limitation that the credential presentation request is handled by the same Wallet that was used to start the OID4VCI process. In case not all of the requested credentials are available in this wallet, the wallet either needs to respond with an error, or to have a way to request issuance of the missing credential(s). It is recommended to indicate to the issuer that requested credential(s) are not available in the wallet in the subsequent authorization challenge request. ## Security Considerations Please have a look at the [Security Considerations](https://www.ietf.org/archive/id/draft-parecki-oauth-first-party-apps-02.html#name-security-considerations) for the first party application usage, especially for the [auth session binding](https://www.ietf.org/archive/id/draft-parecki-oauth-first-party-apps-02.html#name-auth-session-dpop-binding). ## Changes to the OID4VC Flow With the usage of the first party application flow, the issuer metadata need to be extended with the [authorization_challenge_endpoint](https://www.ietf.org/archive/id/draft-parecki-oauth-first-party-apps-02.html#name-authorization-server-metada). Since the OID4VCI flow includes an authorization flow, the lifetime of the session has to be increased. ### Additional parameters The following parameters are defined in this flow and are not part of the normal OID4VCI or first party app specifications: #### auth_session REQUIRED. The auth session allows the authorization server to associate subsequent requests by this client with an ongoing authorization request sequence. The client MUST include the auth_session in follow-up requests to the authorization challenge endpoint if it receives one along with the error response. #### presentation REQUIRED. String containing the OID4VP request URI. The Wallet will use this URI to start the OID4VP flow. #### presentation_during_issuance_session OPTIONAL. String containing information about the session when credential presentation is happening during issuance of another credential. The content of this parameter is opaque to the wallet. When this parameter is present the Wallet MUST use this parameter in the subsequent Authorization Challenge Request. This allows the Issuer to determine which it can be used by to prevent session fixation attacks. The Response URI MAY return this parameter in response to successful Authorization Responses or for Error Responses. ## Appendix: Examples ### Example Authorization Challenge Request Extend the request with the [authorization details parameter](https://openid.github.io/OpenID4VCI/openid-4-verifiable-credential-issuance-wg-draft.html#name-using-authorization-details) or the [scope](https://openid.github.io/OpenID4VCI/openid-4-verifiable-credential-issuance-wg-draft.html#name-using-scope-parameter-to-re). The `request_uri`, `code_challenge`, `code_challenge_method`, `response_type` authorization request parameters MUST NOT be provided. ```http POST /authorize-challenge HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded client_id=bb16c14c73415 ``` ### Example Authorization Error Response ```http HTTP/1.1 400 OK Content-Type: application/json Cache-Control: no-store { "error": "insufficient_authorization", "auth_session": "123456789", "presentation": "/authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234" } ``` ### Example Validation Response ```http HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "presentation_during_issuance_session": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpX..." } ``` ### Example Error Response Sending a request according to the [spec](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#section-6.4-8) ```http POST /authorize-challenge HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded error=access_denied&auth_session=123456789 ``` ### Example Authorization Challenge Request with session ```http POST /authorize-challenge HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded client_id=bb16c14c73415&auth_session=123456789&presentation_during_issuance_session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpX... ``` ### Example Authorization Code Response ```http HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "authorization_code": "uY29tL2F1dGhlbnRpY" } ``` ### Example Token Response ```http HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "auth_session": "123456789" } ``` --- ## Wallet Attestation Wallet Attestations (also called Wallet Instance Attestation or Wallet Trust Evidence) provide the PID or (Q)EAA Provider with the necessary information that a Wallet Instance is authentic and trustworthy and fulfills the security requirements. ## Lifecycle A Wallet Attestation is associated by the Wallet Provider with a particular Wallet Instance and is also associated with a particular Issuer/Relying Party by the Wallet Instance. The lifecycle of a Wallet Attestation is still being evaluated in the eIDAS process. Two general concepts may be used: - Ephemeral Wallet Attestations: A Wallet Attestation is used for a single transaction. A Wallet Attestation is required by the Issuer and the Wallet Instance ad-hoc requests a new one from the Wallet Provider Backend. For every issuance process a new wallet attestation is generated and no linking between these attestations is foreseen. Revocation of Wallet Attestations is not necessary for ephemeral Wallet Attestations. - Long-lived Wallet Attestations: A Wallet Attestation is used for multiple transactions. A Wallet Attestation is required by the Issuer and the Wallet Instance either requests a new one from the Wallet Provider Backend or reuses an existing one. Revocation of Wallet Attestations is foreseen and shall be regularly checked by PID and (Q)EAA Providers. The details of the Wallet Attestation and the corresponding PID/(Q)EAA lifecycles are TBD. ## Protocols Using Wallet Attestations within the [OpenID for Verifiable Credentials protocol family](https://openid.net/sg/openid4vc/) are recommended to use the mechanism described in [OAuth 2.0 Attestation-Based Client Authentication](https://datatracker.ietf.org/doc/draft-ietf-oauth-attestation-based-client-auth/). This enables the Wallet to send a Wallet Attestation (called wallet attestation in the OpenID scope) within the Pushed Authorization Request (PAR) or within the Token Request. The specification is yet to be finalized, so the details are subject to change. ## Attestation format and content The recommended format for a Wallet Attestation is currently described in the [OpenID4VC High Assurance Interoperability Profile with SD-JWT VC](https://openid.net/specs/openid4vc-high-assurance-interoperability-profile-sd-jwt-vc-1_0.html). The specification is yet to be finalized as well, so the details are subject to change. The contents of a Wallet Attestation should include: - the issuer, i.e. the Wallet Provider Backend - the subject, i.e. the client_id of the Wallet Solution - validity information, i.e. the issuance and expiration dates - the wallet instance' public key - the attack potential resistance - optionally specifying the used key type and user authentication mechanism - optionally a list of device keys that may be used for key binding credentials The Wallet Attestation should NOT include: - information on technical capabilities of the wallet - unique identifiers that enable linkability, e.g. information to the Wallet Provider's internal user account Information within the Wallet Attestation shall be reduced to a minimum for privacy and scalability reasons. Further information about the Wallet Solution should be linked on the trust list: - certification scheme - certification status - information on the Wallet Provider and the Wallet Solution ## Revocation The Wallet Provider may revoke a long-lived Wallet Attestation in the following cases: - The Wallet Security Cryptographic Device (WSCD) has a known vulnerability - The Wallet Instance application has a known vulnerability To enable revocation for wallet attestations, the mechanisms described in the [revocation section](../../ecosystem-concepts/trust/status-management.md) apply. ## Cryptographic Formats Long-Term keys: - Wallet Provider has long-term key pair $(wp\_pub, wp\_priv)$ - Wallet Security Cryptographic Device generates device key $(device\_pub, device\_priv)$ Artifacts: - Wallet Provider Backend issues Wallet Attestation: $wallet\_attestation := \text{sign}(\mathit{wallet\_data} | \mathit{device\_pub})_\text{wp\_priv}$ ## Sequence Diagram ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title Issuance of Issuer specific Wallet Attestations participant u [ User ] participant wscd [ User's Wallet Security Cryptographic Device ---- Long-term Key: (//device_pub//, //device_priv//) ] participant w [ User's Wallet Instance ---- Wallet Attestion bound to //device_priv// ] participant b [ User's Wallet Provider Backend ---- Long-term Key: (//wp_pub//, //wp_priv//) ] w -> b: tls() HTTP POST b -> b : generate and store nonces b -> w: tls() HTTP 200 walletAttestationNonces(nonces)> w -> wscd : generate new key (nonce) u <--> wscd : check user authentication note right: user authentication towards the WSCD may be cached for a short duration for further access to WSCD in the issuance process hnote over w #dfd: Screen: Wallet User Authentication wscd -> wscd : generate key pair: (//device_pub//, //device_priv//), including optional key attestations wscd -> wscd : generate proof of possession: sign(nonce)//device_priv// wscd -> w : //device_pub//, optional key attestation, proof of possession w -> w : request app attestations(nonce) from OS attestation service note right: this step involves connection to OS backend services w -> b : tls() HTTP POST b -> b : verify PoP, key and app attestation b -> b : check device black list (Vulnerability Management) b -> b : generate wallet attestation containing //device_pub// and sign with //wp_priv// note left: wallet attestation as defined in "OpenID4VC High Assurance Interoperability Profile with SD-JWT VC - draft 00" b -> w: tls() HTTP 200 w -> w : store walletAttestation for Issuer's client_id @enduml ``` ## Step-by-Step Description 1. The Wallet Instance requests to perform a wallet attestation. It may provide a wallet instance identifier to the Wallet Provider Backend service, that may be used to match a (pseudonymous) user account. 2. The Wallet Provider Backend generates and stores a set of nonces linked to this wallet attestation process. 3. The Wallet Provider Backend returns the wallet attestation nonces to the Wallet Instance. 4. The Wallet Instance requests the generation of a new key pair from its Wallet Security Cryptographic Device (WSCD). 5. The WSCD checks the user authentication. If the User is not authenticated (from previous transactions) yet, the WSCD may initiate and perform a user authentication, e.g. with a PIN. 6. The WSCD generates an attestation key pair (*device_priv*, *device_pub*), which is stored in the secure, hardware-bound WSCD. The WSCD may generate a key attestation (if possible) using a nonce, that attests that this key pair is actually originating from a specific, certified type of WSCD. 7. The WSCD generates a proof of possession by signing a nonce (from Step 3) using *device_priv*. 8. The WSCD sends a response to the Wallet Instance, containing: - the attestation key *device_pub* - the proof of possession - the optional key attestation 9. The Wallet Instance performs Operating System specific attestation (also called app attestation) using a nonce to validate the status and integrity of the Wallet Instance. This step may involve contacting a backend attestation service of the Operating System. 10. The Wallet Instance requests a wallet attestation from the Wallet Provider Backend by sending: - the attestation key *device_pub* - the proof of possession - the optional key attestation - the app attestation 11. The Wallet Provider Backend validates the transmitted keys and attestations 12. The Wallet Provider Backend checks if the device on which the Wallet Instance is installed is listed on a device black list and is known as a vulnerable device / WSCD. 13. The Wallet Provider Backend generates wallet attestation using the attestation key *device_pub* and signing with *wp_priv*. 14. The Wallet Provider Backend returns the wallet attestation to the Wallet Instance. 15. The Wallet Instance stores the wallet attestation on the device and links the usage of the wallet attestation with a specific Issuer. --- ## Archive !!! info "Disclaimer" The contents of this section was relevant for the development but is'nt anymore. It's for documentation purposes of the development process. --- ## Ecosystem Architecture ## Building Block View ### Global Context ```plantuml @startuml skinparam backgroundColor #ffffff skinparam shadowing false skinparam actorStyle awesome skinparam defaultTextAlignment center !define GREY #CCCCCC !define LIGHTGREY #EEEEEE skinparam rectangle { BackgroundColor WHITE BorderColor BLACK } skinparam boxPadding 10 skinparam ArrowColor GREY skinparam ArrowFontColor GREY rectangle "EUDI Wallet Ecosystem" as EUDI { rectangle "Wallet Ecosystem" as WalletEcosystem GREY { skinparam BackgroundColor WHITE } } actor "Wallet User" as User LIGHTGREY rectangle "Relying Parties" as RPs LIGHTGREY rectangle "AppStores / OSs" as AppStores LIGHTGREY User -r[GREY,dashed]-> WalletEcosystem WalletEcosystem -d[GREY,dashed]-> AppStores RPs -l[GREY,dashed]-> WalletEcosystem @enduml ``` | Element | Description | | --- | --- | | `AppStores / OSs` | Apple Appstore or Google Play Store as source where the EUDI Wallet can be downloaded and installed, the operating systems iOS and Android are supported. | | `Wallet User` | Citizen using the EUDI Wallet. | | `Wallet Ecosystem` | System black box described in the following section. | | `Relying Parties` | A Relying Party (RP) is an entity that interacts with EUDI Wallets to verify a user’s identity and attributes for authentication, authorization, or service access. The scope of the EUDI Wallet ecosystem is to create a public and private ecosystem. Both public and private Relying Parties must register and declare their intended use of the EUDI Wallet to ensure compliance with the EUDI wallet ecosystem based on the eIDAS 2.0 regulation. The EUDI wallet ecosystem envisions multiple public, civic and private RPs. | ### Wallet Ecosystem ```plantuml @startuml skinparam backgroundColor #ffffff skinparam shadowing false skinparam actorStyle awesome skinparam defaultTextAlignment center !define GREY #CCCCCC !define LIGHTGREY #EEEEEE skinparam rectangle { BackgroundColor WHITE BorderColor BLACK } skinparam boxPadding 10 skinparam ArrowColor GREY skinparam ArrowFontColor GREY rectangle "EUDI Wallet Ecosystem" as EUDI { rectangle "Registrar / EMP" as Registrar GREY { skinparam BackgroundColor WHITE } rectangle "Access Certificate Provider" as ACP GREY { skinparam BackgroundColor WHITE } rectangle "Wallet Unit" as Wallet GREY { skinparam BackgroundColor WHITE } rectangle "Wallet Backend" as WB GREY { skinparam BackgroundColor WHITE } rectangle "PID Provider" as PP GREY { skinparam BackgroundColor WHITE } } actor "Wallet User" as User LIGHTGREY rectangle "Relying Parties" as RPs LIGHTGREY rectangle "AppStores / OSs" as AppStores LIGHTGREY User -r[GREY,dashed]-> Wallet Registrar -r[GREY,dashed]-> ACP Wallet -r[GREY,dashed]-> PP Wallet <-d[GREY,dashed]-> WB Wallet <-u[GREY,dashed]-> Registrar RPs -d[GREY,dashed]-> Registrar WB -r[GREY,dashed]-> AppStores @enduml ``` | Element | Description | | --- | --- | | `Registrar / EMP` | Ecosystem operator which is providing the Ecosystem Onboarding and also working as the registrar for Relying Parties. | | `Wallet Unit` | The wallet downloaded and installed by the Wallet User on their own compatible device. | | `Wallet Backend` | Backend provided by the Wallet Developer. The Backend fulfills the tasks necessary to check that the Wallet User has installed a proper wallet on a trustworthy device. | | `Access Certificate Provider` | Provider of certificates for central ecosystem components such as the registrar as well as the PID Provider. | | `PID Provider` | A PID Provider is a trusted entity responsible for verifying the identity of the user in compliance with LoA high requirements, issuing a PID to the Wallet, and making information available in a privacy-preserving way so Relying Parties can verify the validity of the PID.The PID Provider ensures that person identification data, such as name and date of birth, is securely generated, validated, and seamlessly provided. The PID Provider is part of the infrastructure of the German EUDI Wallet ecosystem. In the future, additional PID issuance methods that meet the functional and security requirements may be evaluated as part of the German EUDI Wallet project. The EUDI Wallet ecosystem envisions a single PID Provider. | | `AppStores / OSs` | Apple App Store or Google Play Store as sources where the EUDI Wallet can be downloaded and installed; the operating systems iOS and Android are supported. | | `Wallet User` | Citizen using the EUDI Wallet. | | `Relying Parties` | A Relying Party (RP) is an entity that interacts with EUDI Wallets to verify a user’s identity and attributes for authentication, authorization, or service access. The scope of the EUDI Wallet ecosystem is to create a public and private ecosystem. Both public and private Relying Parties must register and declare their intended use of the EUDI Wallet to ensure compliance with the EUDI Wallet ecosystem based on the eIDAS 2.0 regulation. The EUDI Wallet ecosystem envisions multiple public, civic and private RPs. | --- ## Ecosystem Architecture(Ecosystem-concepts) ## Constraints and Decisions ### Constraints | Constraint | Description | | ----------- | ------------------------------------ | | Compliance with eIDAS 2.0 Regulation | The system architecture must comply with Regulation (EU) [**2024/1183**](https://eur-lex.europa.eu/eli/reg/2024/1183/oj/eng) (eIDAS 2.0), which establishes a European framework for digital identity and trust services. This includes support for the European Digital Identity Wallet (EUDI Wallet), qualified electronic attestations of attributes (QEAA), and cross-border recognition of digital identities. The architecture must enable secure, privacy-preserving, and interoperable digital identity solutions in line with the technical, legal, and procedural requirements set out in eIDAS 2.0 and its implementing acts. | | Interoperability with the eIDAS Architectural Reference Framework (ARF) | The system architecture should comply with the eIDAS Architectural Reference Framework (ARF) as defined by the European Union to ensure interoperability and mutual acceptance of electronic identification and trust services across Member States. | | Compliance with eIDAS 2.0 Implementing Acts | The system architecture must adhere to the Implementing Acts adopted under Regulation (EU) 2024/1183 (eIDAS 2.0). These acts define binding technical and procedural specifications for components such as the European Digital Identity Wallet (EUDI Wallet), qualified electronic attestations of attributes (QEAA), trust service providers, and interoperability frameworks. The architecture must be designed to incorporate these requirements as they become applicable, ensuring legal compliance, interoperability, and alignment with the common European digital identity framework. | --- ## Ecosystem Architecture(Crosscutting-concepts) ## Crosscutting Concepts ### Privacy Requirements For system design and comparison of different solutions options we consider the following core privacy properties: #### Intended Use and Transparency Intended use refers to the principle that users should be able to understand and make informed decisions about why specific attestations and credentials are being requested from their digital wallet. This transparency is fundamental to building user trust and ensuring meaningful consent in digital identity transactions. The concept of intended use encompasses several key aspects: * **Purpose Specification:** Relying Parties must clearly communicate the specific purpose for which they are requesting particular credentials or attestations. This includes explaining how the requested information will be used in the context of the specific service or transaction. * **Necessity Justification:** Relying Parties should be able to demonstrate that the requested credentials are necessary and proportionate for the stated purpose. Users should understand why each piece of information is required rather than optional. * **Contextual Clarity:** The request for credentials should be presented in a way that makes the connection between the requested information and the intended service clear to the user. This helps users understand the relevance of sharing specific attributes. * **Scope Limitation:** The intended use should be limited to the specific transaction or service context for which consent was given. Secondary use of the received information should require separate consent or be explicitly covered in the original purpose specification. * **Relying Party Identification:** Users must be able to clearly identify with whom they are interacting in every transaction. Each Relying Party must be securely identified and authenticated before any credential presentation takes place. This ensures that users can make informed decisions about sharing their credentials and prevents impersonation attacks where malicious actors could masquerade as legitimate service providers. **Implementation Considerations:** To support intended use transparency, the ecosystem should provide mechanisms for Relying Parties to communicate their data requests in a standardized, user-friendly manner. This may include: * Structured metadata about the purpose and legal basis for data collection * Machine-readable policy information that wallets can present to users * Standardized iconography or labels for common use cases * Integration with existing privacy frameworks and consent management systems * Secure authentication mechanisms for Relying Party identification (e.g., digital certificates, trusted registries, or qualified electronic signatures) * Clear presentation of Relying Party identity including organization name, legal entity information, and verification status * Protection against domain spoofing and other impersonation attacks through cryptographic verification of Relying Party credentials The wallet should present this information to users in a clear, understandable format before obtaining consent for credential presentation. This includes displaying the verified identity of the Relying Party alongside the purpose and scope of the data request. This supports the user's ability to make informed decisions about their digital identity interactions. **Relationship to Other Privacy Requirements:** Intended use transparency complements other privacy requirements by ensuring that users can meaningfully exercise their privacy rights. It supports data minimization by helping users understand when more information than necessary is being requested, and it enables informed consent for the specific scope of data sharing required for unlinkability and pseudonymity features. #### Unobservability Unobservability refers to the property where an adversary cannot discern any useful information about a communication or transaction. This ensures that sensitive data, such as message content, sender or receiver identity, or any other relevant information, remains hidden from unauthorized parties. In this context, neither Wallet Providers nor Issuers shall be able to track where a user uses their credentials or learn details concerning the attributes provided. For Wallet providers, this implies that the Wallet must run on a device under the user's control; in practice, this usually means a native app on a smartphone. Backend (server) components of the Wallet provider, if used, must not be able to track where users present their credential or learn details concerning the attributes of transactions. For Issuers, this implies that there must be no involvement of the Issuer in the presentation process (e.g., for ad-hoc issuance or revocation checks) unless it can be ensured that the Issuer cannot track where the user presents their credential or learn details concerning the attributes of the presentation. Legal obligations remain unaffected. #### Unlinkability Unlinkability refers to the property that it cannot be distinguished whether two transactions are related to the same user or not. Different definitions of unlinkability can be considered in this context (not all are equally applicable to all functions and use cases): * **Outsider**: An adversary that may observe or modify the transactions should not be able to link two transactions to the same user. * **Relying Party**: A Relying Party should not be able to link two presentation transactions to the same user (unless sufficiently identifying information is part of the presented credential). * **Issuer**: An Issuer should not be able to link two issuance transactions to the same user (unless the user provides sufficiently identifying information as part of its authentication). * **Colluding Relying Parties**: Two Relying Parties should not be able to link two presentation transactions to the same user by sharing the received presentations. * **Colluding Issuers**: Two Issuers should not be able to link two issuance transactions to the same user by sharing the received information during issuance (e.g. wallet attestations). * **Colluding Relying Party and Issuer**: An Issuer and a Relying Party should not be able to link an issuance and presentations session to the same user (unless the user provides sufficiently identifying information as part of their authentication to the issuer and as part of the presented credential). Issuance and presentation protocols should support unlinkability and ensure that cryptographic keys and random numbers cannot be used as correlation identifiers, this also includes less obvious data fields such as timestamps or version numbers. If a Relying Party requires to recognize a user across multiple transactions, it should use pseudonyms. #### Data Minimization and Prevention of Overidentification According to the principle of data minimization, Relying Parties shall only receive the data they need for the specific transaction. Various properties can help to achieve this: * **Pseudonymity:** Pseudonymity refers to the possibility of using a pseudonym when authenticating online or presenting credentials, unless the identification is required by law. * **Selective Disclosure:** Selective Disclosure is the property to disclose only selected attributes of a credential during the presentation. This means that the Wallet (with the user's consent) can present a selected subset of the data fields (claims) in a credential while other fields are not revealed to the Relying Party. * **Enforced Disclosure Limitation:** Enforced Disclosure Limitation means that the scope of data Relying Parties can request can be limited by having Relying Parties register the data fields they need for a specific type of transaction and that the limitation can be enforced by the Wallet. The following mechanisms are not considered in this proposal: * **Zero-Knowledge Proofs:** Zero-knowledge proofs can be used to prove that a certain claim is true without revealing the actual value of the claim. For example, a user could prove that they are over 18 without revealing their exact date of birth. Zero-knowledge proofs are not supported by the credential formats chosen in the ARF and bring significant implementation and security challenges, especially as they are not in widespread use yet. * **Optional Data in User Consent:** Some user consent implementations allow users to select which data fields they want to disclose to a Relying Party, out of those requested by the RP. While this can be seen as a privacy feature, for users, however, it can be difficult to understand which data fields are really required by the RP and what the consequences are of not disclosing certain data fields. When users encounter errors and have to repeat steps in the transaction process, it can be expected that they would refrain from unselecting any data fields in the long run. Therefore, such an option could lead to overidentification in the long run as Relying Parties can exploit user fatigue. Consequently, it seems preferable to ensure (by technical means and data privacy laws) that Relying Parties only request the data they absolutely need and not support optional data in user consent screens. #### Repudiation Repudiation (or “plausible deniability”, since “repudiation” actually refers to a single act of dispute although commonly used as synonym for the general ability to deny transactions) refers to the property that one of the entities involved in an identification transaction can plausibly deny to a third party (i.e., a party not involved in the transaction) in having participated in the transaction after its completion, or can plausibly deny to a third party having provided certain data. The ability to deny the transaction towards third parties does not impact the reliability of the transaction towards the Relying Party involved. Below, two repudiation variants are considered. * **Deniability of Data Authenticity:** Deniability of Data Authenticity refers to the property that the authenticity of a credential and its attributes provided by the Issuer can be plausibly denied to a third party after a presentation. In this context, it is required that a Relying Party should not be able to prove to a third party the authenticity of a credential and the integrity of its attributes that it has previously verified. * **User deniability:** User deniability refers to the role of the user in a presentation transaction and the user's authentication of the presentation. In this context it is required that a Relying Party should not be able to prove to a third party that the user has presented a credential in context of an identification, where the Relying Party was previously involved as verifier. **Note on repudiation in relation to identification:** General understanding of identification processes is their short-lived nature. Presenting one's ID to a verifier in the analogue world has the immediate outcome for both not being able to prove the affair to someone else, as long as the ID has not been copied. Repudiation would achieve the same feature for digital identities. The importance of repudiation for digital identifications might not be obvious, its absence however reveals a string of implications. In case of data breaches with authenticated PID involved, plausible deniability to the public would become highly favorable to the persons affected, especially if the involved Relying Party could arouse social discomfort. Regarding long-term storage, data leaks are generally more a matter of time rather than probability, since this risk cannot be thoroughly eliminated. Data thieves would obviously have a preference for guaranteed genuine copies over unauthenticated PID. In some use cases, records need to be kept by law. The specific requirements encountered by these use cases must be scrutinized. Usually, declarations of intent differ from identifications, so special means suitable for the respective use case are likely to be more appropriate. In any case, if a Relying Party has the requirement to prove an identification to a third party, it is the responsibility of the Relying Party to document and certify the identification procedure to the third party. From an academic point of view, there is a lack of studies that examine the value of repudiation in connection with identification transactions compared to the impact that already arises from the leak of the collected data itself (e.g., use-case specific data in the context of record management requirements). The value of non-repudiation may be limited since the authenticity of leaked data can often be asserted by other means, e.g., by verifying samples of the data against publicly available data. In this context it should also be considered what influence the fulfillment of other requirements, such as unlinkability, could have on the impact of non-repudiation and to what extent the strict application of the GDPR could minimize the risk of amassing authenticated data at Relying Parties. The repudiation requirement and the appropriateness of using authenticated PID is subject of ongoing discussions within the consultation process. #### Data Confidentiality Data confidentiality refers to the protection of data from unauthorized access. This "property" can be applied to data protection in transport, e.g., when sending sensitive data between two parties, to data protection in use, e.g., when processing the data, as well as to data protection at rest, e.g., when storing sensitive data. All three properties shall be fulfilled in a system which handles data with need for protection, e.g., PII or other sensitive information about a user. This applies to the described system of this architecture proposal, namely the wallet, as well, due to the PII inside, e.g., the PID. Which components are affected is currently out of scope, and shall be subject to a future, more in-depth, analysis of this matter. ##### Data Protection at Rest The general requirement for confidentiality of data comes from the implementing acts, as well as the revised eIDAS regulation and the GDPR. For example, as outlined in the following places: * [(revised) eIDAS Regulation (EU) 2024/1183](https://eur-lex.europa.eu/eli/reg/2024/1183/oj/eng): Art. 3 (42) "'European Digital Identity Wallet' means an electronic identification means which allows the user to **securely store**, manage and validate person identification data [...]" * [CIR 2015/1502](https://eur-lex.europa.eu/eli/reg_impl/2015/1502/oj/eng): 2.3.1 "Where **person identification data is stored as part of the authentication mechanism**, that information is **secured** in order to protect against loss and **compromise**, including offline analysis." * [CIR 2015/1502](https://eur-lex.europa.eu/eli/reg_impl/2015/1502/oj/eng): 2.4.6 "All media containing personal, cryptographic or other **sensitive information are stored**, transported and disposed of **in a safe and secure manner**." * [CIR 2024/2979](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=OJ:L_202402979): Art. 2 (3) "'critical assets' means assets within or in relation to a wallet unit of such extraordinary importance that where their availability, **confidentiality** or integrity are compromised, this would have a **very serious, debilitating effect** on the ability to rely on the wallet unit" The first three examples give no doubt about the legal requirement of confidentiality, applying to at least those credentials containing PII that are used for the authentication, e.g., the PID batch credentials. As such, encrypting the batch credentials when stored on the device is a requirement we need to fulfill. What is still unclear however, are the associated (technical) risks that shall be mitigated by the encryption, namely what "level of protection" needs to be achieved. For example, does the PID batch credential, or its corresponding encryption key, fall under the definition of the critical asset, whose compromise of confidentiality has a "very serious, debilitating effect"? One example for critical assets are the user binding keys needed during authentication. If such keys were to be compromised, e.g., due to insecure storage in software or insufficient secure hardware, an attacker would be able to impersonate a user, as possession of such a key would enable them to proof towards another entity the corresponding identity bound to the key. Impersonation in the context of authentication would indeed have a "very serious, debilitating effect on the ability to rely on the wallet unit", as it cannot guarantee its purpose of authenticating a valid user, namely functioning as an eID means. As such, in order to mitigate such a risk, the user binding key must be stored in sufficiently secure hardware (e.g., as the implementing act on 5c requires, the secure hardware shall meet the evaluation assurance level 4+ AVA_VAN5, protecting against attackers with high attack potential). However, the risk is different for the batch credential and corresponding encryption key: compromise of the batch credential itself does not allow for impersonation, as presentation itself is not possible without the user binding key, which, as we have just laid out, is sufficiently protected. Furthermore, the compromise of the encryption key would "only" allow for decryption of the batch credential. In contrast to the aforementioned risk, decryption of the batch credential does not have a "very serious, debilitating effect". E.g., the "plain-text" batch credential is ending up at the relying party after a successful transaction, and thus the goal of a presentation. As such it cannot be a factor for breaching the ability to rely on the wallet unit itself. Furthermore, the possibility of the data to end up at a malicious relying party or other (unauthenticated and unauthorized) party, is already part of a first risk "estimation". Of course, a future, more in-depth, risk assessment/analysis shall be carried out to further estimate the severity and likelihood of such a risk and the resulting necessary measures to protect against it (as well as other risks, such as unavailability/"denial of service" due to preventing the decryption of the credential, when, e.g., breaking the hardware and compromising/deleting the key, or similar). This includes the time "when to decrypt", and the underlying assumptions made on the device. However, as of yet, we do see neither the batch credential nor the encryption key as a critical asset. As such, the secure hardware storing the encryption key does not necessarily have to meet the same evaluation assurance level as the one for protecting the user binding key. ##### Options for Protection of PII The analysis for the security requirements requires a risk-based analysis where the technical possibilities are evaluated based of the privacy risks according to the underlying data protection model. As a first step, the following options for protecting the PII are technically feasible, but need to be evaluated further regarding the protection they provide: 1. Software Keys 2. System Keystore 3. System Keystore with Access Control 4. Backend Encryption 5. (Presentation Re-Keying) A risk-based analysis in the future shall conduct which of the above options is possible to control the risks that were worked out. We will come back to this after such a risk analysis has been concluded (tbc). For the below analysis of the options, we do not consider any app-level protections, such as root detection, system integrity checks or app attestations, as the data might be exfiltrated from a device without the app ever being opened by the attacker. ###### Software Keys Encryption of the PII, namely the batch credential, is done with software keys managed by the wallet app. Although easy to implement and platform independent, it does not add any notable security. ###### System Keystore Encryption of the PII is done with encryption keys managed by the platforms keystore mechanism. A wallet app requests the decryption of the data on start of the app without any user interaction, allowing it to show the decrypted PII directly to the user. For those wallet solutions which rely on native hardware backed keystores, such as secure enclave on iOS or TEEs or Strongbox on Android, no additional access control may be insufficient: Although they may achieve resistance against moderate attack potential (or even higher for some), the usage of the key is not sufficiently protected. I.e., the device unlock in addition with app identifiers may be circumvented on rooted systems. Access to the data is therefore effectively only secured by a single factor. ###### System Keystore with Access Control Similarly to the previous option, encryption of the PII is done with encryption keys managed by the platforms keystore mechanism. However, additional access control is registered for the use of the encryption key. Such measures can be: * Device Unlock * Biometrics * PIN/Passphrase In contrast to before, active user interaction would be required on decryption. The device unlock would utilize the same mechanism as upon unlocking the device, such as the PIN or biometrics, or whatever the user might have enrolled in their device. Alternatively, the key can be set up to require a biometric or knowledge factor different from the device unlock. Similar mechanisms are utilized for, e.g., Indigo, utilizing Apple's Secure Enclave, for clearances comparable to moderate attack potential (similarly "VS NfD" by BSI). But although the hardware key storage (as in some Android Strongbox models) can possibly even achieve a higher level of "security", the second factor does generally not satisfy the requirements on higher levels of assurance. ###### Backend Encryption Encryption of the PII is done with encryption keys managed in the secure hardware on the backend. Active user interaction for the authentication towards the backend is necessary for the key usage. In order to prevent the wallet backend to learn about the users identity through the PII, which would go against the untraceability/unlinkability requirement, a double encryption must be used: $enc(K_{Backend}, enc(K_{App}, PII))$ The app encrypts the PII first, followed by the decryption of the resulting cyphertext by the backend. As such, when the backend receives the ciphertext for encryption, or when performing the decryption, the backend never learns about the plaintext, namely the PII of the user. Only after both sides have decrypted can the PII be viewed. With usage of public key cryptography, the encryption can already be performed at the PID provider during issuance, using the corresponding public keys to not involve the backend for encryption. As the backed and the authentication towards it is the same as used for the provision of the eID functionality of the wallet, we assume that the security guarantees are also the same. For Wallet architectures with the secure hardware in the backend, if they reach a level of assurance high, the protection of the encryption keys, and thus effectively of the PII, would achieve resistance against attackers with high attack potential. It should be noted however, that the implementation costs are higher than for the previous options, as it additionally involves the backend (at least for the decryption). ##### Data Protection Requirements Besides deciding which options for protecting the PII also protect against any security risks, it is also necessary to check for any privacy requirements which need to be fulfilled, and which privacy risks may arise otherwise (a risk analysis shall as such also cover any privacy risks as well). A final decision for an option may only be performed afterwards. This is _tbc_ --- ## Ecosystem Architecture(3) ## Crosscutting Concepts ### Security Requirements For system design and comparison of different solutions options we consider the following core security properties: #### Level of Assurance (LoA) Level of Assurance refers to the degree of confidence in the processes thus providing assurance that the user that uses a particular identity is in fact the user to which that identity was assigned. This property refers to the [LoA of the eIDAS Regulation](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A02015R1502-20220711). #### Unforgeability of Credentials Unforgeability of credentials refers to the property that a credential can only be created by the legitimate Issuer and cannot be tampered by someone else. This property ensures the integrity and authenticity of a credential and its verification. #### Freshness of Presentations Freshness of presentations refers to the property that every presentation must be created anew for every verification. This property refers to the mechanisms used for binding a presentation to the presentation request of the Relying Party to prevent replay of presentations. #### User Binding of presentations User Binding refers to the property that credentials are under the sole control of the user. This property refers to the mechanism used for secure authentication of the user in the context of using the credential (e.g., by two-factor authentication linked with a cryptographic binding to the credential) to prevent unauthorized issuance or presentation of a credential. In the literature, this property is also described as holder binding. #### Session Integrity Session Integrity refers to the property that an attacker is not able to insert themselves into an authentication exchange between a Verifier and a Wallet or into an issuance process between a Wallet and an Issuer. This property requires mechanisms for binding communication to an authenticated session to prevent session hijacking. ### Cryptographic algorithms This section defines the cryptographic algorithms **required** for EU-wide interoperability in the EUDI Wallet ecosystem. The requirements are based on the [eIDAS 2.0 Implementing Acts](https://eur-lex.europa.eu/eli/reg_impl/2024/2982/oj) and the [ENISA Agreed Cryptographic Mechanisms](https://www.enisa.europa.eu/publications/cryptographic-mechanisms) to ensure compliance with **Level of Assurance High (LoA High)**. !!! Info "Standards Reference" Most of the requirements on algorithms etc. come from the relevant technical standards like [TS 119 472-2](https://portal.etsi.org/webapp/WorkProgram/Report_WorkItem.asp?WKI_ID=69601), [TS 119 472-3](https://portal.etsi.org/webapp/WorkProgram/Report_WorkItem.asp?WKI_ID=74935), [OpenID4VC High Assurance Interoperability Profile 1.0](https://openid.net/specs/openid4vc-high-assurance-interoperability-profile-1_0-final.html). !!! warning "Mandatory Algorithm Support" All algorithms specified in this section **SHALL** be implemented by all ecosystem participants (Wallet Providers, Issuers, Verifiers). Using alternative algorithms (e.g., P-384 or P-521 instead of P-256) in ecosystem-specific agreements is **NOT RECOMMENDED**, as Wallets are only required to support the mandatory algorithms. Credentials signed with non-mandatory algorithms may not be parseable or verifiable by compliant Wallets, breaking interoperability. #### Encryption and Confidentiality For secure data exchange in both proximity and remote scenarios: * **Application Layer Encryption: AES-GCM:** * [A128GCM](https://datatracker.ietf.org/doc/html/rfc5116) (128-bit key) * [A256GCM](https://datatracker.ietf.org/doc/html/rfc5116) (256-bit key) * **Transport Encryption:** TLS 1.3 or TLS 1.2 with ENISA-compliant cipher suites for HTTPS communication Note that for Response encryption, verifiers MUST support both, A128GCM, and A256GCM, and wallets can support either or both (see [Section 5 of HAIP](https://openid.net/specs/openid4vc-high-assurance-interoperability-profile-1_0-final.html#section-5) for more details) #### Digital Signatures and Integrity Signature requirements vary by use case and credential format: * **Proximity Presentations (ISO/IEC 18013-5):** * [ECDSA](https://datatracker.ietf.org/doc/html/rfc6090) using [P-256 (secp256r1)](http://www.secg.org/sec2-v2.pdf) for Reader Authentication and Device Signature * **SD-JWT VC (Selective Disclosure JWT):** * Based on [JWS (JSON Web Signature)](https://datatracker.ietf.org/doc/html/rfc7515) * When not serialized in compact format: [JAdES-B-B](https://www.etsi.org/deliver/etsi_ts/119100_119199/11918201/01.01.01_60/ts_11918201v010101p.pdf) signatures required * **ISO/IEC mdoc:** * [COSE signatures](https://datatracker.ietf.org/doc/html/rfc9052) with [CB-AdES-B-B](https://www.etsi.org/deliver/etsi_ts/119100_119199/11919501/01.01.01_60/ts_11919501v010101p.pdf) profile * **Issuer Signatures (general):** * [ECDSA](https://datatracker.ietf.org/doc/html/rfc6090) using [P-256 (secp256r1)](http://www.secg.org/sec2-v2.pdf) and [SHA-256](https://datatracker.ietf.org/doc/html/rfc6234) * **Qualified Signatures (QEAA/PuB-EAA):** * Must be qualified electronic signatures or seals * Underlying cryptographic modules require certification to Common Criteria (minimum EAL 4+) or FIPS 140-3 Level 3 #### Key Management and Exchange * **Elliptic Curve:** * [P-256 (secp256r1)](http://www.secg.org/sec2-v2.pdf) as the standard curve * **Key Exchange (Proximity):** * [ECDH-ES](https://datatracker.ietf.org/doc/html/rfc7748) (Elliptic Curve Diffie-Hellman Ephemeral Static) using P-256 * **Key Binding:** * Wallet must demonstrate Proof of Possession for private keys corresponding to public keys in cryptographic bindings * **DPoP (Demonstrating Proof of Possession):** * [ECDSA](https://datatracker.ietf.org/doc/html/rfc6090) using [P-256 (secp256r1)](http://www.secg.org/sec2-v2.pdf) and [SHA-256](https://datatracker.ietf.org/doc/html/rfc6234) #### Hash Algorithms * **SHA-256:** Required for integrity checks and certificate fingerprints (e.g., `x5t` header in JWS) * All hash functions must comply with ENISA-endorsed mechanisms #### Hashing, PKCE (code challenge method) * [SHA-256](https://datatracker.ietf.org/doc/html/rfc6234) (S256 method) #### Special Services * **Qualified Timestamps (TSA):** * Algorithms must be explicitly listed in ENISA publications to support presumption of conformity with eIDAS Regulation * **Remote QSCDs:** * Providers must implement ENISA-compliant cryptographic controls covering the entire lifecycle of signing techniques !!! note "Interoperability Rationale" All EUDI Wallet ecosystem components **SHALL** support the algorithms specified above. This is mandated by the Implementing Acts for both proximity (ISO/IEC 18013-5) and remote presentation scenarios. **Why no optional algorithms?** While ecosystem-specific agreements (e.g., for diploma credentials) might technically allow stronger algorithms like P-384 or P-521, this creates a fragmentation risk: if an Issuer signs a credential with P-521 but the Wallet only implements the mandatory P-256, the credential becomes unusable. To guarantee that any EUDI-compliant Wallet can process any EUDI-compliant credential, all participants **SHALL** use only the mandatory algorithms specified in this document. #### National Requirements and EU Interoperability Member States may have national regulations that mandate additional cryptographic algorithms beyond those required by the EU Implementing Acts. !!! example "Example: Germany - §44 BSI-Gesetz" According to [§44 BSI-Gesetz](https://www.gesetze-im-internet.de/bsig_2009/__44.html), German federal authorities are legally required to implement the [BSI TR-02102](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.pdf) Technical Guidelines. TR-02102 recommends algorithms including Brainpool curves (brainpoolP256r1, brainpoolP384r1, brainpoolP512r1) which are not part of the EU-mandated algorithm set. **Impact on ecosystem participants:** | Participant Type | EU Algorithms (P-256) | National Algorithms (e.g., TR-02102) | |-----------------|----------------------|-------------------------------------| | Wallet Provider | **SHALL** implement | No requirement | | Issuer (general) | **SHALL** use for credentials | No impact on credential issuance | | Issuer (German federal authority) | **SHALL** use for credentials | **SHALL** implement for internal systems per §44 BSI-Gesetz | | Verifier (general) | **SHALL** support | No requirement | | Verifier (German federal authority) | **SHALL** support | **SHALL** implement for internal systems per §44 BSI-Gesetz | !!! warning "Key Principle: Credentials Must Use EU-Mandated Algorithms" Even if national law requires implementation of additional algorithms (like BSI TR-02102), **credentials issued for use in the EUDI Wallet ecosystem SHALL be signed with EU-mandated algorithms** (P-256) to ensure EU-wide interoperability. National algorithm requirements apply to internal systems, backend communication, and non-EUDI use cases, but **not** to the credential signatures that Wallets must verify. This means German federal authorities acting as Issuers must: 1. **Use P-256** for signing EUDI Wallet credentials (EU interoperability) 2. **Additionally implement TR-02102 algorithms** for other federal IT systems and internal communications (national compliance) --- ## Ecosystem Architecture(4) ## Deployment View This Deployment View describes the allocation of application and technology components to physical infrastructure within the EUDI Wallet ecosystem. It aims to provide a high-level overview and identifies which actors operate which systems and where these systems are deployed. The view provides a structured overview of the logical architecture mapped onto concrete technology elements, including hardware resources, deployed software components, and the interfaces between the participating actors. Its purpose is to illustrate the realization of the ecosystem by explicitly linking software components to specific infrastructure elements, rather than defining a purely hardware-agnostic solution. This enables the identification of required interfaces, clarifies responsibilities across organizational boundaries, and supports the definition of appropriate security controls and trust boundaries for these interfaces. ```plantuml @startuml skinparam backgroundColor #ffffff skinparam shadowing false skinparam actorStyle awesome skinparam defaultTextAlignment center !define GREY #CCCCCC !define LIGHTGREY #EEEEEE skinparam rectangle { BackgroundColor WHITE BorderColor BLACK } skinparam boxPadding 10 skinparam ArrowColor GREY skinparam ArrowFontSize 18 skinparam legend { backgroundColor #GhostWhite entrySeparator #GhostWhite } node "German eID Provider" as eIDProvider { artifact "eID" <> as eID LIGHTGREY component "eID Server" as eIDServer LIGHTGREY } node "User's Device" as UsersDevice { component "User's EUDI Wallet Instance" as Wallet GREY } node "Trust Components" as TrustCom { component "EU List of Trusted Lists" as TrustedLists GREY component "QTSP" as QTSP component "Authentic Sources" as AuthSource component "Access Certificate Issuer" as ACs GREY component "Registration Certificate Issuer" as RCs GREY } node "Wallet Provider" as WalletProvider { component "Wallet Backend" as WalletBackend GREY } node "Orchestrator" as Orchestrator { component "Registrar" as Registrar GREY component "Ecosystem Management Portal" as EMPPortal GREY } node "EAA Provider" as EAAProvider { component "EAA Issuing Service" as EAAIssuingService GREY } node "PID Provider" as PIDProvider { component "PID Provider\nBackend" as PIDBackend GREY } node "Relying Party" as RelyingParty { component "Auth Component" as VerificationComponent GREY } WalletProvider -[hidden]right- TrustCom WalletProvider <--> UsersDevice : ① UsersDevice <-left-> eIDProvider : ② UsersDevice <--> PIDProvider : ③ PIDProvider --> eIDProvider : ④ UsersDevice <--> RelyingParty: ⑤ UsersDevice <--> EAAProvider: ⑥ UsersDevice --> Orchestrator : ⑦ PIDProvider -left-> Orchestrator : ⑦ EAAProvider --> Orchestrator : ⑦ RelyingParty --> Orchestrator : ⑦ legend right <#GhostWhite,#GhostWhite>| |= __Legend__ | || Ecosystem Components| || Not part of the Ecosystem| endlegend @enduml ``` ### Nodes | Nodes | Description | | ----------------------------- | ------------------------------------ | | `EAA Provider` | Electronic Attestations of Attributes (EAA) provide a flexible form of electronic attribute attestations under eIDAS. EAA providers are trusted sources that issue EAAs for the wallet and can access QTSPs and Authentic Source when needed. | | `German eID Provider` | The organization responsible for issuing and operating the German electronic identity (eID). The issuer provides the trust framework, security policies, and backend services required for secure electronic identification and authentication in accordance with applicable regulations. | | `Orchestrator` | Is operating the Registrar to issue access and relying party registration certificates and hosts the Ecosystem Management Portal | | `PID Provider` | The PID Provider represents the one institutional entity that is responsible for the issuance and governance of Personal Identification Data (PID). It is subject to legal requirements and ensures compliance with legal and regulatory provisions. It is also responsible for the correct and lawful provision of personally identifiable data within the system landscape. | | `Relying Party` | The Relying Party represents an organization that relies on issued Personal Identification Data (PID) for identification or verification purposes within its own systems and processes. It is responsible for integrating PID usage into its applications and for ensuring lawful and compliant handling of PID. | | `Trust Components` | List of Trust components that were already established or newly created in the context of building the ecosystem. | | `User's Device` | A mobile device (smartphone) operated by the end user. The application is deployed to the device as a mobile app and runs locally, enabling user interaction and communication with backend services. | | `Wallet Provider` | An organization that provides a German EUDI wallet. The organization is responsible for providing and certifying the wallet and must operate the wallet backend. It implements the security requirements from the blueprint and represents the trust anchor for its own wallet instances. | ### Components | Components | Description | | ---------------------------------------------------- | ------------------------------------ | | EAA Provider - `EAA Issuing Service` | Issuing service provided by serveral providers of Electronics Attribute Attestations (EAA) | | German eID Provider - `eID` | The German electronic identity implemented as a highly secure smartcard. It stores identity attributes and cryptographic keys and enables secure electronic identification and authentication when accessed via authorized backend systems. | | German eID Provider - `eID Server` | Backend system operated by the eID issuer and accessed by the native mobile app on the user device. It provides the eID Server services, orchestrates identification and authentication processes, and securely communicates with the German eID to perform identity verification. | | Orchestrator - `Ecosystem Management Portal` | The Ecosystem Management Portal is the central governance and coordination platform of the German EUDI ecosystem, enabling secure onboarding, certification, and lifecycle management of ecosystem participants. | | Orchestrator - `Registrar` | The Registrar is the authoritative entity within the German EUDI ecosystem responsible for validating, registering, and maintaining verified ecosystem participants and services. | | PID Provider - `PID Provider Backend` | The PID Provider Backend is a technical component responsible for issuing Personal Identification Data (PID) upon request. The backend generates and delivers PID but does not persist or store any personal identification data. It operates in a stateless manner and enforces the applicable institutional and regulatory rules during the issuance process. | | Relying Party - `Auth Component` | The Authentication Component is a technical system provided and operated by the Relying Party to authenticate users or subjects. It interacts with the PID Provider Backend as part of the authentication or identification process and consumes issued PID without storing or generating PID itself. | | Trust Components - `Access Certificate Issuer` | Issues certificates to Relying Parties after Registrar validation.| | Trust Components - `Authentic Sources` | Authentic Sources are authoritative data providers that supply verified and legally reliable identity attributes, such as civil registry, educational, or professional qualification data.| | Trust Components - `EU List of Trusted Lists` | Trust Lists for PID Provider, (Q/Pub)EAA Provider, Wallet Provider, Registrar, Access Certrificates and Registration Certificates | | Trust Components - `Registration Certificate Issuer` | Registration certificates issued to RPs after Registrar validation.| | Trust Components - `QTSP` | The Qualified Trust Service Provider (QTSP) within the eIDAS framework is a certified entity authorized to deliver qualified trust services such as electronic signatures, seals, timestamps, and certificates. | | User's Device - `User's EUDI Wallet Instance` | A native mobile application distributed via the official app stores. The EUDI Wallet Instance is certified and installed on the user’s device. It requires an active network connection and is not capable of offline operation. The app provides the user interface and communicates with backend services. | | Wallet Provider - `Wallet Backend` | A backend operated by the wallet provider for initiating sessions and issuing wallet attestations. The backend ensures the authenticity of the wallet application in all PID processes and implements security functions to verify that it is an official and certified wallet. | ### Connections Connections in this table describe the high-level interactions between actors, nodes, and their components. This table is intended to support a conceptual understanding of the overall collaboration and does not replace the Runtime View, which is described separately. The listed connections are therefore non-normative and focus on explaining the general interplay rather than exact runtime behavior. | Connection | Description | | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 1 | In the EUDI Wallet ecosystem, the user’s device hosts the wallet instance and securely generates, stores, and presents credentials under the user’s sole control. The wallet provider supplies the wallet software, ensures compliance, lifecycle management, and trust framework integration, but has no access to the user’s private keys or credential data. | | 2 | Within the ecosystem, the User’s Device establishes a secure, mutually authenticated connection to the German eID Provider to request identity data and perform user authentication. The eID provider verifies the user’s credentials and attributes and transmits the approved identity data directly to the wallet instance under the user’s control. | | 3 | User's Wallet Instance establishes a secure, mutually authenticated channel with the PID Provider to receive the Person Identification Data (PID) credential after successful identity verification. The credential is generated and cryptographically bound to the wallet instance on the User’s Device, ensuring that it remains under the user’s control and cannot be reused by other parties. | | 4 | The PID Provider establishes a secure, mutually authenticated connection to the German eID provider to perform identity verification and retrieve authoritative identity attributes. The German eID provider authenticates the user and returns verified identity data, which the PID Provider uses as the basis for issuing the PID credential. | | 5 | The User’s Device establishes a secure, mutually authenticated session with the Relying Party to present verifiable credentials or requested attributes. The Relying Party validates the cryptographic proofs and trust chain, while the wallet ensures user consent and selective disclosure before transmitting any data. | | 6 | The User’s Device establishes connection to the EAA Provider to request and receive an Electronic Attestation of Attributes (EAA). The EAA Provider verifies the required evidence and issues the attestation cryptographically bound to the wallet instance on the User’s Device under the user’s control. | | 7 | Within the EUDI Wallet Ecosystem, the User’s Device, PID Provider, EAA Provider, and Relying Party establish secure, mutually authenticated connections to the Orchestrator to exchange transaction metadata, trust information, and protocol messages. The Orchestrator coordinates the interaction flows and enforces trust framework policies, without accessing private keys or the underlying credential contents. | --- ## Ecosystem Architecture(5) This chapter provides the normative definition of the ecosystem architecture for the German ecosystem. It reflects a multi-level approach, starting from the Implementing Acts, further specified by the ARF, and culminating in the national normative definition for Germany presented here. The described architecture is overall based on variant C′, which has been selected from a set of previously evaluated options. Alternative variants (B, B´, C, C″, and D) are excluded from this specification and are available in the archive for reference purposes. For more information on the decision-making process for Option C′, please refer to the documents from the [Open Online Consultations](https://gitlab.opencode.de/bmi/eudi-wallet/eidas2/-/tree/main/03_Open_Online_Consultations). --- ## Ecosystem Architecture(6) ## Introduction and Goals Infrastructure are those components that you build once for use by many ### Stakeholders | Name | Function | | ---- | -------- | | Wallet Development Teams | All Wallet Developer Teams need their information what and how to develop. So they are tremendous interested in these architecture of the ecosystem | | Technical writers | e.g. technical writers for onboarding guides will find their necessary information. | | Other EU memberstates | For getting information about the german development process. | | Standardization Organizations | For getting deeper context information about the german ecosystem. | | Interested Public | For getting deeper information about the EUDI Wallet Ecosystem | --- ## Trust in the EUDI Wallet Ecosystem ## Introduction Trust between participating parties is a fundamental prerequisite for a functioning EUDI Wallet ecosystem. This section provides a comprehensive overview of how trust is established, what distinguishes different attestation types, and how to determine which attestation type is appropriate for specific use cases. The eIDAS 2.0 framework deliberately provides different levels of trust services to match different real-world needs. Understanding these trust models is essential for selecting the appropriate attestation type and avoiding unnecessary effort and costs. !!! Info "Key principle" The appropriate attestation type is the **lowest level** that sufficiently meets the legal and practical requirements of the use case. --- ## How Trust Is Established Trust in the EUDI Wallet ecosystem is established through different mechanisms depending on the attestation type and the relationship between parties. ### Uniform Issuer Identity Assurance All issuers—whether issuing PID, EAA, QEAA, or PubEAA—are identified at the same cryptographic security level via **Access Certificates issued by a Registrar**. Access Certificates: - Bind the legal identity of the issuer - Define the issuer's technical role in the ecosystem - Enable secure interaction with Wallets and Relying Parties Access Certificates do **not** define: - Evidentiary value of the issued attestation - Qualification status of the issuer - Authorization to issue specific attributes !!! Info "Authentication vs. Authorization" Identity assurance answers _who_ an issuer is. Trust models answer _whether_ a specific attestation should be relied upon. ### Trust Models by Attestation Type | Attestation Type | Primary Trust Anchor | Authorization Logic | Liability | | ---------------- | ------------------------------------------------------- | ----------------------- | -------------------------- | | **PID** | Member State certification | National law mandate | Member State | | **EAA** | Accepted rulebook / scheme | Explicit via governance | Contractual / scheme-based | | **QEAA** | QTSP qualification + EU Trusted List | Implicit via regulation | Statutory (QTSP) | | **PubEAA** | Public mandate + certified attributes + EU Trusted List | Explicit via public law | Public authority | --- ## Trust and Liability Understanding liability allocation is crucial when choosing an attestation type: ### EAA (Electronic Attestation of Attributes) - **Liability:** Based on contractual arrangements, scheme rules, and general civil law - **Risk allocation:** Shared between issuer and relying party according to scheme governance - **Recourse:** Through contractual and civil law mechanisms - **Insurance:** Not mandated, but may be required by scheme rules ### QEAA (Qualified Electronic Attestation of Attributes) - **Liability:** Statutory liability regime under eIDAS - **Risk allocation:** QTSP assumes significant liability for damages caused by non-compliance - **Recourse:** Direct statutory claims against the QTSP - **Insurance:** Mandatory professional liability insurance required for QTSPs ### PubEAA (Public Electronic Attestation of Attributes) - **Liability:** Public law liability of the issuing authority - **Risk allocation:** The public body responsible for the authentic source bears liability - **Recourse:** Administrative and public law remedies - **Insurance:** Government liability frameworks apply ### PID (Personal Identification Data) - **Liability:** Member State responsibility under eIDAS - **Risk allocation:** The notifying Member State is liable for the proper functioning - **Recourse:** Through national and EU legal mechanisms - **Insurance:** Covered by state liability frameworks --- ## Common Misconceptions ### "Only QEAA are legally safe" **Incorrect.** QEAA provide higher evidentiary value only where this is legally or practically required. EAAs are explicitly designed by eIDAS to cover the vast majority of use cases and are fully valid trust instruments. ### "EAA providers are not trustworthy because they are not on the EU Trusted List" **Incorrect.** Access Certificates identify the entity with which the Wallet is interacting, but they do not sign credentials. For EAA, trust is established via accepted rulebooks that the Relying Party must accept to consume the attestation and gain trust in it. The difference between EAA and QEAA lies in the trust model, not in the cryptographic security or identity verification of the issuer. ### "Qualification equals better security" **Incorrect.** Technical security mechanisms (cryptography, key management, revocation) are similar across all attestation types. Qualification primarily adds conformity assessment, supervision, and statutory liability—not inherently stronger technical security. ### "Public bodies should always use PubEAA" **Incorrect.** Public bodies can issue EAAs for attributes that do not require document-equivalent evidentiary value. PubEAA is specifically for cases where the attestation should have the same legal effect as a paper original. --- ## Choosing the Right Attestation Type ### Quick Decision Guide There are several key factors to consider when choosing an attestation type for a given use case: | Question | Motivation | | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | Who is the issuer of the credential? | certain rights and obligations for public bodies, responsible for an authentic source, e.g., to issue PubEAA and provide register information | | Required evidentiary value of the credential? | for document-equivalent requirements, QEAA or PubEAA may be legally required | | Existing trust / acceptance structure? | can be used for EAA verification, independent of eIDAS trust lists, e.g., credit scores | | Cross-border scenario, unknown acceptance conditions? | central eIDAS trust mechanisms for QEAA / PubEAA may be used, e.g., language certificates from certified schools | | Should issuance be under control of a public body? | other parties may issue credentials by verifying attributes against the authentic source (if on Minimum List of Attributes) | The requirements for EAA, QEAA, and PubEAA can be compared concisely as follows: | Requirement | EAA | QEAA | PubEAA | PID (for comparison) | |-------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------| | **Evidentual value** | Trust structures of the issuer | Like written document | Like written document | Like notified eID-system | | **Issuer** | All, regularly a trust service provider | Only a QTSP | Only authentic sources from a public authority or its representative | PID-Provider | | **Certification required?** | No | Yes including re-certification | Yes, only initial | Yes, EUDI-Wallet certification (Art 5c eIDAS) | | **Issuing from not self administered sources possible?** | Yes | Yes | No | Yes (can differ from national eID-operator) | | **Sector of issued attestations** | Private and Public | Private and Public | Only Public | Only Public | | **Possibility of using a service provider to issue in its own name?** | Yes | No | Yes | Yes| | **Issuance only in EUDIW compatible formats and protocols?** | Yes | Yes | Yes | Yes | | **User identification required?** | At the discretion of the issuer | Yes | Yes | Yes (level of assurance high) | | **Attribute verification and linking to the user required?** | At the discretion of the issuer | Yes | Yes | Yes (level of assurance high) | | **Rules for the structure of the attestation?** | At the discretion of the issuer | Yes, annex V eIDAS | Yes, annex VII eIDAS | Yes, via implementing act | | **Rules for ensuring integrity and authenticity of the attestation?** | At the discretion of the issuer | Yes, qualified electronic signature/seal | Yes, qualified electronic signature/seal | Yes | | **Revocation required?** | At the discretion of the issuer | Yes, (excluding short time attestations) at the user's request, if the proof becomes inaccurate or if there is a possibility of compromise | Yes, (excluding short time attestations) at the user's request, if the proof becomes inaccurate or if there is a possibility of compromise | Yes, at the user's request, if the proof becomes inaccurate or if there is a possibility of compromise | | **Obligation to fulfil attestation scheme?** | At the discretion of the issuer | Yes | Yes | Yes (PID-Rulebook) | | **Functional separation of EAA service required?** | No | Yes | No | No | | **Logical separation of the data and prohibition of combining EAA with other user data?** | Yes | Yes | Yes | Yes | | **Supervision by an authority?** | Yes ex-post, only if trust service provider | Yes, ex-ante | No | Yes, ex-ante by EUDI-Wallet supervisory authority | | **NIS2-obligation?** | Yes as important entity, only if trust service provider | Yes as essential entity | No, except obligation from another category | Yes regurlarly as critical infrastructure | | **Obligation for accessibility?** | Yes, only if trust service provider | Yes | Yes | Yes | | **Special obligation for incident reporting** | Yes, only if trust service provider | Yes | No | Yes, via EUDI-Wallet mechanisms | | **General technical and organizational requirements for service operation?** | Yes ex-post, only if trust service provider according to Art 19a eIDAS and implementing act (EU) 2025/2160 | Yes, according to Art 24 eIDAS and concretizing implementing acts | Yes, analogue to Art 24 eIDAS | Ja, specific requirements of Art 24 eIDAS | | **Special civil law liability for culpable breach of duty?** | Yes, only if trust service provider | Yes, additionally culpable violation is presumed | No | Via EUDI-Wallet mechanisms according to Art 11 eIDAS | | **Attribute in attribute catalogue of EU-Commission?** | Only if based on an authentic source from a public authority | Only if based on an authentic source from a public authority | Yes | No, but EU trusted list for PID-Provider und PID-Rulebook | | **Attribute in catalogue of attribute schemes of EU-Commission?** | Yes, but only if relevant | Yes, regularly | Yes | No, but EU-trusted list for PID-Provider and PID-Rulebook | | **Sources for validation of the attestation** | If applicable via catalogue of attribute schemes, otherwise through information made available by the issuer | EU trusted list + if applicable. Catolog of attribute schemes | EU trusted list + EU trusted list for PubEAA providers + catalogue of attribute schemes | EU trusted list for PID-Provider + PID-Rulebook | ### Detailed Decision Criteria The differences and reasons for issuing EAA, QEAA, and PubEAA described in detail above provide the following decision-making aid for anyone who, as a potential issuer of attribute certificates, is wondering which of the three types they should issue. **Basic Rule EAA** - Especially if trust structures are already in place - If the legal basis allows the EAA to provide the proof (e.g., mdl) - Existing and accepted private and public law proofs are to be transferred to the EUDI wallet - The proofs are to be issued in a cost-effective, flexible, and customizable manner **Exception: QEAA** - If, in exceptional cases, no adequate trust structure is available or can be established for the attestation to be issued - If the attestation is intended for use abroad and the acceptance rules applicable there are unknown, and it is unclear whether the existing (national) trust structures will be sufficient there - The relying parties expressly request QEAA for legal or risk-based reasons. Instead of issuing QEAA, an attempt can also be made to address these reasons and enable the issuance of EAA **Speciality for public sector authentic sources: PubEAA** - The requirements for issuing a QEAA are met - In addition, the highest possible degree of decision-making autonomy should be exercised, and key decisions regarding the issuance should be made within the public administration The following table helps through key questions to identify the most suitable credentials for specific use case: | Key Question | EAA | QEAA | PubEAA | | -------------------------------------------------------------------------------------- | :-: | :--: | :----: | | Existing acceptance relationship? | ✅ | — | — | | Accepted today without originals? | ✅ | — | — | | Previously required in original form? | — | ✅ | ✅ | | Regulatory demand for document equivalence? | — | ✅ | ✅ | | Cross-border use with unknown acceptance? | — | ✅ | ✅ | | Issuer is authentic source? | ✅ | — | ✅ | | Issued in issuer's own name? | ✅ | — | ✅ | | Public body responsible for authentic source wants to keep most possible control? | — | — | ✅ | !!! tip "Principle of Proportionality" The existence of QEAA does not imply that EAA are insufficient. Choose the **lowest** attestation type that meets your requirements. Anything beyond that is voluntary over-compliance with additional cost and complexity. --- ## Next Steps Based on your use case, proceed to the detailed requirements for each attestation type: - **[PID Trust Requirements](./trust_pid_issuance_presentation.md)** — For Personal Identification Data - **[EAA Trust Requirements](./trust_eaa_issuance_presentation.md)** — For Electronic Attestations of Attributes - **[QEAA and PubEAA Trust Requirements](./trust_q_pub_eaa_issuance_presentation.md)** — For qualified and public attestations If you have decided to issue an EAA, see the design guidance: - **[EAA Overview](../../features/EAA/index.md)** — What EAAs are, who can issue them, and credential formats - **[Credential Anatomy](../../features/EAA/credential-anatomy.md)** — Common mechanisms: signatures, revocation, key binding - **[Design Recommendations](../../features/EAA/design-recommendations.md)** — Best practices for well-made EAAs For technical details on trust validation mechanisms, see: - **[Trust Validation Overview](./trust-validation.md)** — Technical validation procedures - **[Wallet-Relying Party Authentication](./wallet-relying-party-authentication.md)** — RP registration and authentication --- ## Trust Management in the German EUDI Wallet Ecosystem ## Overview This section provides comprehensive guidance on trust in the German EUDI Wallet ecosystem. Whether you are an issuer deciding which attestation type to use, a relying party integrating with Wallets, or a developer implementing trust validation, you will find the relevant information here. Trust between participating parties is a fundamental prerequisite for a functioning EUDI Wallet ecosystem. This trust is based on eIDAS regulations, centralized trust lists, and certifications of technical implementations. ![Trust](../../../figures/trust-level0.png) Figure: High-level overview of trust in the ecosystem --- ## Credentials Overview ### Scope and Design Dimensions eIDAS 2.0 defines a framework for interoperable digital credentials within the European Digital Identity ecosystem. Credential types differ primarily along the following design dimensions: - **Credential Provider**: the legal and organizational entity responsible for issuance and lifecycle management. - **Level of Assurance (LoA)** : the confidence level associated with identity proofing, issuance, and authentication, aligned with eIDAS assurance concepts (Low, Substantial, Qualified, High). - **Legal Effect** : the regulatory recognition and evidentiary value of the credential across member states. These dimensions are combined into two main credential families: **Personal Identification Data (PID)** and **Electronic Attestations of Attributes (EAA)**. ### Credentials Families #### Personal Identification Data (PID) PID credentials represent core identity data of a person and are based on a notified eID system. They form the foundational identity layer within the European Digital Identity Wallet. PID is distinct from EAAs in that it focuses on core identity establishment. #### Electronic Attestations of Attributes (EAA) EAAs represent verifiable statements about one or more attributes of a subject (natural or legal person). Attributes may relate to status, qualifications, rights, or characteristics derived from authentic sources. EAAs may be further extended depending on issuer qualification, assurance level, trust model, and legal recognition into two additional types: - Qualified Electronic Attestations of Attributes (QEAA), representing a specialized form of EAA. - Public Electronic Attestations of Attributes (Pub-EAA), representing another specialized form of EAA. Across the EAA family, the following baseline principles apply: - Attribute data must be traceable to an issuer and connected to a user. - Integrity and authenticity must be cryptographically verifiable. --- ## Navigation Guide | If you want to... | Start here | | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | Understand trust models and choose an attestation type | [Trust Overview and Decision Guide](./decision-guide.md) | | Learn about PID-specific trust requirements | [Trust in PID Issuance and Presentation](./trust_pid_issuance_presentation.md) | | Learn about EAA trust requirements | [Trust in EAA Issuance and Presentation](./trust_eaa_issuance_presentation.md) | | Learn about QEAA/PubEAA trust requirements | [Trust in QEAA and PubEAA Issuance and Presentation](./trust_q_pub_eaa_issuance_presentation.md) | | Design EAAs: formats, signatures, revocation | [EAA Design Section](../../features/EAA/index.md) | | Implement trust validation (roles, trust lists, certs) | [Trust Validation Overview](./trust-validation.md) | | Understand RP registration and authentication | [Wallet-Relying Party Authentication](./wallet-relying-party-authentication.md) | | Understand how users are protected from excessive requests | [Overasking Protection](./overasking-protection.md) | --- ## Reading Paths ### For Issuers 1. Start with the [Decision Guide](./decision-guide.md) to understand which attestation type fits your use case 2. Read the specific trust requirements for your attestation type: - [PID](./trust_pid_issuance_presentation.md) for identity providers - [EAA](./trust_eaa_issuance_presentation.md) for standard attestations - [QEAA/PubEAA](./trust_q_pub_eaa_issuance_presentation.md) for qualified/public attestations 3. Review [Trust Validation](./trust-validation.md) for technical implementation details ### For Relying Parties 1. Start with [Wallet-Relying Party Authentication](./wallet-relying-party-authentication.md) for registration requirements 2. Review [Trust Validation](./trust-validation.md) to understand how to validate credentials 3. Consult the [Decision Guide](./decision-guide.md) to understand which attestation types to accept ### For Developers 1. Start with [Trust Validation](./trust-validation.md) for the technical architecture 2. See the [Wallet Attestation flow](../../archive/flows/Wallet-Attestation.md) for implementation details 3. Review [OID4VC Protocol Integration](../../archive/flows/OID4VC-with-WRP-attestations.md) for certificate usage in protocols 4. Review [Status Management](../trust/status-management.md) for revocation handling --- ## Overasking Protection ## Problem Statement A fundamental concern in digital identity ecosystems is **overasking** — when a Relying Party (RP) requests more personal data than necessary for its service. This creates several risks: - **Privacy violation**: Users may unknowingly share more data than needed - **Data minimization breach**: GDPR requires collection of only necessary data - **Trust erosion**: Users lose confidence if they feel exploited - **Accidental disclosure**: Users may approve requests without fully understanding what they're sharing Without technical safeguards, users must rely solely on their own judgment to assess whether a data request is proportionate — a burden that is unreasonable given the complexity of digital services. !!! example "Overasking Scenario" A cinema ticket website requests not only proof of age (required for age-restricted films) but also the user's full name, address, and nationality. The user, eager to complete their purchase, approves the request without noticing the excessive data collection. --- ## Regulatory Foundation ### eIDAS 2.0 Requirements The eIDAS 2.0 regulation explicitly addresses overasking through Article 5b, which requires: 1. **Registration of intended use**: RPs must declare in advance which attributes they intend to request and for what purpose 2. **Purpose limitation**: Requests must be limited to data necessary for the declared purpose 3. **Transparency**: Users must be informed about who is requesting data and why ### GDPR Alignment The overasking protection mechanism supports GDPR principles: | GDPR Principle | How Overasking Protection Helps | | ---------------------- | -------------------------------------------------------- | | **Data minimization** | Technical enforcement of "only necessary data" | | **Purpose limitation** | Requests tied to declared, registered purposes | | **Transparency** | Users see exactly what is requested vs. what is declared | | **Accountability** | Registered intended use creates auditable record | --- ## How Overasking Protection Works ### Step 1: RP Registers Intended Use Before an RP can request credentials from Wallets, it must register at a national Registrar. This registration includes: !!! example "Intended Use Declaration" | Field | Value | | --------------- | ---------------------------------------- | | **Purpose (EN)**| Age verification for alcohol purchase | | **Purpose (DE)**| Altersverifikation für Alkoholkauf | | **Credentials** | PID | | **Attributes** | `age_over_18` (boolean) | *Purpose can be provided in multiple languages for display to users.* #### What the Registrar Does and Does Not Validate The Registrar validates: - **RP identity** — The legal identity of the Relying Party including an optional intermediary - **Technical correctness** — The declaration is well-formed and complete The Registrar does **not** validate: - **Purpose legitimacy** — Whether the stated purpose is lawful under GDPR - **Proportionality** — Whether the requested attributes match the purpose - **Legal basis** — Whether the RP has a valid legal basis for data collection !!! info "Why the Registrar Does Not Validate Purpose Content" **Avoiding liability and bottlenecks** If the Registrar validated the GDPR compliance of each purpose declaration, it would: 1. **Assume liability** for the correctness of that assessment 2. **Need ongoing verification** — GDPR compliance depends on context that can change (e.g., business model changes, legal interpretations evolve) 3. **Create a bottleneck** — Every registration would require legal review, slowing onboarding and making it much more expensive 4. **Require revocation monitoring** — The Registrar would need to continuously verify that the legal basis remains valid and revoke certificates when it doesn't Instead, the Registrar acts as a **transparent publisher**: - Stores the declared purpose securely - Makes it publicly accessible for scrutiny - Enables third parties (regulators, consumer protection, users) to verify compliance - Leaves GDPR responsibility where it belongs: with the Relying Party #### Why This Approach Works Best | Design Choice | Benefit | | ------------------------------------- | --------------------------------------------- | | **RP self-declares purpose** | RP remains fully accountable under GDPR | | **Registrar publishes transparently** | Enables public audit and regulatory oversight | | **Machine-readable format** | Wallet can automatically enforce boundaries | | **User sees purpose at consent time** | Informed consent with context | | **No central validation bottleneck** | Scalable onboarding for RPs | | **Immutable record** | Creates evidence trail for disputes | This design follows the principle of **transparency over gatekeeping**: rather than creating a central authority that approves purposes (which would be slow, legally risky, and potentially a single point of failure), the system ensures that all declarations are visible and auditable. Importantly, the approach ensures that registration of a use case can happen in an **inexpensive, quick, and automated fashion.** This enables the use of fine-grained registrations for use-cases that provide transparency for end-users and identify the actual receiver of the data, instead of providing incentives for "catch-all" registrations, for relying on bypassing registration (see discussion below), and for centralized data requests and processing. ### Step 2: RP Receives Registration Certificate Upon successful registration, the RP receives a **Registration Certificate** that cryptographically binds: - The RP's identity - The declared purpose (human-readable, multi-language) - The permitted credential types - The permitted attributes within each credential This certificate is machine-readable, enabling automated validation by Wallets. ### Step 3: RP Makes a Request When the RP requests data from a Wallet, it includes: 1. **Access Certificate** — proving who the RP is 2. **Registration Certificate** — declaring what the RP may request 3. **Actual request** — specifying what the RP wants now, which must be a equal or a subset of the attributes registered ### Step 4: Wallet Validates the Request The Wallet automatically compares: | Registered (allowed) | Requested (actual) | Result | | -------------------------- | -------------------------- | ---------- | | `age_over_18` | `age_over_18` | ✅ Valid | | `age_over_18` | `age_over_18`, `full_name` | ⚠️ Warning | | `age_over_18`, `full_name` | `age_over_18` | ✅ Valid | **Rule**: The actual request must be **equal to or a subset of** the registered intended use. ### Step 5: User Is Informed Based on the validation result, the Wallet presents information to the user: #### Normal Request (within scope) !!! success "Consent Screen" **🏪 Liquor Store Online** **Purpose:** Age verification for alcohol purchase **Requesting:** - ☑ Proof that you are over 18 `[Approve]` `[Decline]` #### Overasking Detected !!! warning "Excessive Data Request" **🏪 Liquor Store Online** **Registered purpose:** Age verification for alcohol purchase **Requesting MORE than registered:** - ☑ Proof that you are over 18 *(registered)* - ⚠️ Full name *(NOT registered)* - ⚠️ Address *(NOT registered)* This request exceeds what the service registered. You may still proceed, but consider whether this data is truly necessary. `[Proceed Anyway]` `[Decline]` --- ## Wallet Provider Policy The **default behavior when overasking is detected is determined by each Wallet Provider**. This allows for different approaches based on the provider's privacy stance and user base. ### Recommended Approach: Privacy by Design A privacy-protective default would be: | Scenario | Default Behavior | User Override | | --------------------- | --------------------- | ----------------------------------------------------- | | Request within scope | Allow (with consent) | — | | Request exceeds scope | **Reject by default** | User can enable "Allow extended requests" in settings | | RP not registered | Reject | No override possible | This approach follows **privacy by design** principles: - **Protects non-technical users** — The majority of users who are not skilled in privacy topics are protected automatically - **Informed opt-in** — Advanced users who understand the implications can choose to allow overasking requests via settings - **No surprise data sharing** — Users cannot accidentally share more data than the RP officially registered for !!! tip "Settings Example" **Privacy Settings** - ☐ Allow requests that exceed registered intended use *(When enabled, you will see a warning but can proceed with requests that ask for more data than the service registered for)* ### Alternative Approaches Wallet Providers may choose different defaults based on their target audience: | Approach | Default | Trade-off | | --------------------------- | ------------------ | ------------------------------------------------------------- | | **Strict (recommended)** | Reject overasking | Maximum privacy, may occasionally block legitimate edge cases | | **Warning only** | Allow with warning | More flexible, but risk of accidental over-sharing | | **User choice per request** | Ask each time | Flexible but increases cognitive load | --- ## Benefits ### For Users - **Automatic protection** — no need to manually assess every request - **Clear warnings** — immediately see when something is unusual - **Informed consent** — understand exactly what is being requested and why - **Reduced cognitive load** — trust the system to flag problems - **Privacy by default** — protected even without technical knowledge ### For Relying Parties - **Clear guidelines** — know exactly what can be requested - **Legal compliance** — built-in GDPR data minimization support - **Trust building** — users trust RPs that request only what's needed ### For the Ecosystem - **Accountability** — registered intended use creates audit trail - **Enforcement** — technical mechanism supports regulatory requirements - **Transparency** — public registration enables scrutiny --- ## Updating Intended Use RPs may need to update their intended use over time (e.g., adding new services). The process ensures continued protection: 1. RP submits updated intended use declaration to Registrar 2. Registrar validates the new scope 3. New Registration Certificate is issued 4. Old certificate may be revoked or allowed to expire 5. Requests using the old certificate continue to be validated against the old scope --- ## Related Resources - [Wallet-Relying Party Authentication](./wallet-relying-party-authentication.md) — RP registration and certificates - [Trust Validation Overview](./trust-validation.md) — Technical validation architecture - [OID4VC Protocol Integration](../../archive/flows/OID4VC-with-WRP-attestations.md) — How validation works in protocols --- ## Status Management Revocation of credentials is a process in which the issuer of PID or (Q)EAA declares that the credential is no longer valid. Various use cases and scenarios may require revocation: - the PID/(Q)EAA Provider wants to revoke its issued credential because the contained data is no longer valid - the Wallet Provider wants to revoke a Wallet Instance because Wallet Security Cryptographic Device (WSCD) or the Wallet Instance application is compromised or vulnerable - the user wants to revoke their Wallet Instance because they lost their smartphone - the user wants to revoke their PID - the PID Provider wants to revoke a PID because the person has died Regarding the various PID options, only the issuer-signed variations requires revocation as the Authenticated Channel variations generate fresh credentials for every transaction. To enable revocation for credentials within the EUDI Wallet ecosystem, the following mechanisms for revocation are considered: - Certificate Revocation Lists - Status Lists For the revocation of relying party or issuer certificates, the following mechanisms are - Online Certificate Status Protocol (OCSP) - OCSP stapling ## Mechanisms ### Certificate Revocation Lists Certificate Revocation Lists (CRL) as defined in [RFC5280](https://datatracker.ietf.org/doc/rfc5280/) are an established revocation mechanism for X509 certificate that has been proven in productive environments for a long time. The Issuer maintains a publicly available list that contains the serial numbers of revoked certificates. Relying Parties may discover this list (e.g. as the URL is contained in the certificate) and validate whether the serial number exists in the list. As the issuer of a certificate always delivers the complete list, he will not learn which serial number the Relying Party is interested in, thus guaranteeing the unobservability. As CRLs are currently only used for X509 certificates, it remains open to define how this mechanism is used for the PID credential formats. Additionally, CRLs have seen some scalability limitations in the Browser TLS context, and it remains open to evaluate if CRL sizes remain manageable within the eIDAS ecosystem. Usage of CRL Delta updates may be considered to increase the scalability. ### Status List [IETF Token Status List](https://datatracker.ietf.org/doc/draft-ietf-oauth-status-list/) is a new mechanism with similar properties to CRLs, which defines a status mechanism for JOSE and COSE secured Referenced Tokens. This status links to a Status List in JSON and CBOR formats that describe the individual statuses of multiple Referenced Tokens. The statuses of all Referenced Tokens are conveyed via a bit array in the Status List. Each Referenced Token is allocated an index during issuance that represents its position within this bit array. The value of the bit(s) at this index correspond to the Referenced Token's status. The Status List is provided by the issuer through a public endpoint or as a signed Status List Token in JWT or CWT. As the issuer of a status list always delivers the complete list, he will not learn which index the Relying Party is interested in, thus guaranteeing the unobservability. Status List have shown to have better scalability properties than CRLs under most circumstances, but it remains open to evaluate if this is sufficient for the eIDAS ecosystem. Status Lists have not been widely adopted and proven in productive ecosystems yet. The Status List requires additional communication between the issuance and revocation service during the issuance. ### Online Certificate Status Protocol (OCSP) In the Online Certificate Status Protocol the issuer provides a service(called OSCP Responder), which the Relying Party may use to query the revocation status of a certificate in real time. As the Relying Party provides the specific certificate serial number to the issuer, unobservability can not be achieved. As OCSP is currently only used for X509 certificates, it remains open to define how this mechanism is used for the PID credential formats. Furthermore, the system has shown to have bad scalability properties. Therefore, usage of OSCP is *not* recommended. ### OCSP stapling In the OCSP stapling the TLS certificate owner regularly queries the issuer's OCSP endpoint and "staples" the result to the response of the TLS handshake, thus the other party does not need to fetch it themselves, reducing the traffic and cost for the OCSP Responder. OCSP stapling was introduced to tackle the scalability issues of OCSP but only with modest success. OCSP stapling is currently only defined for X509 certificates, but a [proposal applying the concepts to the PID credential formats is under development](https://datatracker.ietf.org/doc/draft-demarco-oauth-status-attestations/). The concept has the privacy potential as the Relying Party does not fetch the revocation information itself, but it remains open whether sufficient scalability can be achieved. ## Validation procedure Before validating the status of a credential, the Relying Party should check if the credential is not expired yet. If so, the credential is considered invalid which is defined by either being expired or revoked. ## Privacy Considerations It is worth to take a look at the privacy consideration of the different methods like the one from [Token Status List](https://drafts.oauth.net/draft-ietf-oauth-status-list/draft-ietf-oauth-status-list.html#name-privacy-considerations). ## Recommendations When using either CRLs or Status Lists, the issuer needs to find the balance between privacy and required bandwidth. A large CRL or Status List give herd immunity when feting the list. However, when the list is too large, the Relying Party or the Wallet eed to download a lot of data frequently. To reduce the frequency of fetching the list, the issuer is able to define a Time to Live (TTL) for the list. The Relying Party or Wallet should cache the list for the defined TTL. The issuer should also provide a mechanism to fetch the list before the TTL expires. To calculate the maximum size of the list, the issuer has to calculate the worst case scenario. When using a CRL the worst case is the revocation of all credentials. In this case the CRL includes all the identifiers of the revoked credentials. The size depends on the algorithm to generate these identifiers (UUID, SHA256, etc.). **Example**: A UUID has a size of 16 bytes. If the issuer has issued 1 million. The CRL has a size of 16 MB. In case of the Status List, the worst case is a state where the compression algorithm finds no pattern to reduce the size. This is not the case when all credentials are revoked, because then all values are the same and can be compressed to a single bit. **Example**: If the issuer has issued 1 million credentials, the Status List has a size of 125 KB, when using a 1 bit per credential. In case the status list uses n bits per credential to manage more than two states, the size is `125 KB * n`. When the issuer has reached the defined size, it should consider to start with a parallel list. It is not recommended to reuse the bit of a credential that is expired, because it is not guaranteed that the Relying Party or Wallet has fetched the list before. It is the same for the CRL to reduce the risque that an identifier is reused and creates a false positive case. To minimize traceability, the issuer should update the revocation list in batches. For example, if the issuer revokes a batch of 50 credentials, Relying Parties could deduce that these 50 entries are linked to the same batch issued to a single wallet, potentially enabling them to track the wallet. To mitigate this risk, the issuer should include decoy entries in the list. These decoy entries do not correspond to any actual credentials and serve solely to increase the apparent size of credential updates, making it unclear to Relying Parties which entries belong to a specific credential batch. --- ## Trust Validation Overview This chapter defines how ecosystem participants establish and validate trust in the German EUDI Wallet ecosystem. It covers the validation of PIDs, Wallet Unit Attestations (WUA), and Wallet Relying Party certificates, using trust lists based on the [ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) specification. !!! tip "Credential-type-specific trust anchors" This chapter defines *who* is trusted (roles, trust lists, certificates). For credential-type-specific trust anchors—which issuers are authorized for which EAA types—see the [Catalogue of Attestations](../../features/EAA/catalog-of-attestations.md). The catalog's `trustedAuthorities` field references the trust lists defined in this chapter. ## Actors & Roles The following table summarizes the roles and the dependencies for trust validation. A **Wallet Relying Party (WRP)** is any entity that interacts with the Wallet Unit via digital interaction. This includes all attestation providers (PID, EAA, QEAA, PubEAA) and Relying Parties. All WRPs require Access Certificates (WRPAC) and Registration Certificates (WRPRC) to interact with the wallet. | Role | WRP | Issues | Credentials Needed | Validates | | ----------------------------------------------- | --- | ----------------------------------------- | ---------------------- | ---------------------------- | | **PID PROVIDER** | ✓ | Person Identification Data (PID) | WRPAC | WUA | | **EAA PROVIDER** | ✓ | Electronic Attestation of Attributes | WRPAC, WRPRC | WUA (optional) | | **QEAA PROVIDER** | ✓ | Qualified Electronic Attestation of Attr. | WRPAC, WRPRC, TL entry | WUA (optional) | | **PubEAA PROVIDER** | ✓ | Public Electronic Attestation of Attr. | WRPAC, WRPRC, TL entry | WUA (optional) | | **RELYING PARTY (RP)** | ✓ | — | WRPAC, WRPRC | PID, attestations | | **WALLET PROVIDER** | — | Wallet Unit Attestation (WUA) | TL entry | — | | **WALLET UNIT** | — | — | WUA | PID, WRPAC, WRPRC | | **REGISTRAR** | — | — | TL entry | WRP identity data | | **PROVIDER OF ACCESS CERTIFICATES (ACA)** | — | Access Certificates (WRPAC) | TL entry | WRP identity (via Registrar) | | **PROVIDER OF REGISTRATION CERTIFICATES (PRC)** | — | Registration Certificates (WRPRC) | TL entry | WRP identity (via Registrar) | !!! info "Column definitions" - **WRP**: Indicates if the role is a Wallet Relying Party (interacts with wallet via digital interaction) - **Issues**: The artefact(s) issued by that role - **Credentials Needed**: What the role needs to operate (either certificates or a Trust List entry) - **Validates**: What the role validates before issuing or accepting credentials > In the Implementing Acts, the Provider of Registration Certificates is called Registration Certificate Authority. !!! info "PID provider without WRPRC" The PID Provider does not need a registration certificate since we will have only one entity in the German ecosystem issuing PIDs. Therefore, the PID Provider can be uniquely identified by its access certificate (WRPAC) alone. !!! note "Wallet Provider vs. Wallet Unit " **Wallet Provider** and **Wallet Unit** are distinct roles with different responsibilities: - **Wallet Provider**: The organization operating the backend infrastructure that issues Wallet Unit Attestations (WUA). - **Wallet Unit**: The application instance running on the user's device that holds credentials and performs cryptographic operations. The Wallet Provider issues the WUA to authenticate the Wallet Unit towards the PID Provider during issuance flows. --- ## Role-Specific Notes ### PID Provider - **Keys/Certificates:** PID signing keys (for PIDs and for status lists) under a CA chaining to a TL-listed Trusted Entity Certificate; access cert (ACA) for service access as needed. - **Validation duties:** Validate WUA; validate payload from authentic source to issue PID. - **Revocation:** Revoke PID signing and access certs promptly; publish CRL. !!! important "PID Provider Notification Requirements" Per Commission Implementing Regulation (EU) 2024/2980 (Art. 4-5), Germany must: 1. **Notify** the European Commission of the PID Provider information with `serviceTypeIdentifier` values: - `http://uri.etsi.org/19602/SvcType/PID/Issuance` for the issuance service - `http://uri.etsi.org/19602/SvcType/PID/Revocation` for the revocation service 2. The Commission **establishes, maintains and publishes** the **EU PID Providers List** (`http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList`) compiling information from all Member States. There is no separate national list for PID Providers; the EC-published list is the authoritative source for cross-border trust discovery. ### EAA Provider - **Keys/Certificates:** Attestation signing keys; access cert (WRPAC) and registration cert (WRPRC) for wallet interaction. - **Validation duties:** Validate WUA (optional); verify user identity/entitlements from authentic sources. - **Revocation:** Revoke attestation signing certs and status credentials as needed. ### QEAA Provider - **Keys/Certificates:** Qualified attestation signing keys under TL-listed Trusted Entity Certificate; access cert (WRPAC) and registration cert (WRPRC) for wallet interaction. - **Validation duties:** Validate WUA (optional); verify user identity/entitlements; meet QTSP requirements. - **Revocation:** Revoke attestation signing certs and status credentials; comply with QTSP revocation obligations. !!! important "QEAA Provider Publication Requirements" QEAA Providers are **Qualified Trust Service Providers (QTSPs)** and are published in the national **eIDAS Trusted List** ([ETSI TS 119 612](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)), not in the [ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) LoTE. Per eIDAS 2.0 requirements, Germany must: 1. **Publish** each QEAA Provider in the national eIDAS Trusted List with the appropriate QTSP service type. 2. The Commission aggregates national eIDAS Trusted Lists into the **EU List of Trusted Lists (LoTL)**. Each entry must include: - Appropriate status (granted/suspended/withdrawn) - Certificate chains to a Trusted Entity Certificate (TEC) published in the same trust list - Required service metadata and contact information ### PubEAA Provider - **Keys/Certificates:** Public attestation signing keys under TL-listed Trusted Entity Certificate; access cert (WRPAC) and registration cert (WRPRC) for wallet interaction. - **Validation duties:** Validate WUA (optional); verify data from authentic source under public authority responsibility. - **Revocation:** Revoke attestation signing certs and status credentials as needed. !!! important "PubEAA Provider Notification Requirements" Per Commission Implementing Regulation (EU) 2024/2980 (Art. 4-5), Germany must: 1. **Notify** the European Commission of each PubEAA Provider with `serviceTypeIdentifier` values: - `http://uri.etsi.org/19602/SvcType/PubEAA/Issuance` for the issuance service - `http://uri.etsi.org/19602/SvcType/PubEAA/Revocation` for the revocation service 2. The Commission **establishes, maintains and publishes** the **EU PubEAA Providers List** (`http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList`) compiling information from all Member States. Each notification must include: - Appropriate status (granted/suspended/withdrawn) - Certificate chains to a Trusted Entity Certificate (TEC) - Required service metadata and contact information There is no separate national list for PubEAA Providers; the EC-published list is the authoritative source for cross-border trust discovery. ### Wallet Provider - **Keys/Certificates:** WUA signing keys under Trusted Entity Certificate. - **Validation duties:** Validate device attestation and Wallet Unit integrity before issuing WUA. - **Revocation:** Revoke WUA series if compromised/deregistered; publish status. !!! important "Wallet Provider Notification Requirements" Per Commission Implementing Regulation (EU) 2024/2980 (Art. 4-5), Germany must: 1. **Notify** the European Commission of each Wallet Provider with `serviceTypeIdentifier` values: - `http://uri.etsi.org/19602/SvcType/WalletSolution/Issuance` for the issuance service - `http://uri.etsi.org/19602/SvcType/WalletSolution/Revocation` for the revocation service 2. The Commission **establishes, maintains and publishes** the **EU Wallet Providers List** (`http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList`) compiling information from all Member States. The notification must include the Wallet Provider's Trusted Entity Certificate (TEC) and WUA signing keys. This is necessary so that: - PID Providers can validate WUA authenticity - Verifiers can check the authenticity of Wallet Unit Attestations - Cross-border wallet interoperability is ensured through the EU-published list There is no separate national list for Wallet Providers; the EC-published list is the authoritative source for cross-border trust discovery. ### Registrar - **Duties:** Validate RP identity data from authentic sources; notify ACA/PRC on changes; host and maintain the [Catalogue of Attestations](../../features/EAA/catalog-of-attestations.md). !!! important "Registrar Notification Requirements" Per Commission Implementing Regulation (EU) 2024/2980 (Art. 4-5), Germany must: 1. **Notify** the European Commission of each Registrar with `serviceTypeIdentifier` set to `http://uri.etsi.org/19602/SvcType/Register`. 2. The Commission **establishes, maintains and publishes** the **EU Registrars and Registers List** (`http://uri.etsi.org/19602/LoTEType/EURegistrarsAndRegistersList`) compiling information from all Member States. There is no separate national list for Registrars; the EC-published list is the authoritative source for cross-border trust discovery. ### Access CA (ACA) - **Duties:** Issue access certs to RPs **after** Registrar validation. - **Revocation**: Revokes certificates when not aligned with Registrar anymore. Publish status list for issued certs. !!! important "Access CA Notification Requirements" Per Commission Implementing Regulation (EU) 2024/2980 (Art. 4-5), Germany must: 1. **Notify** the European Commission of each Access CA with `serviceTypeIdentifier` values: - `http://uri.etsi.org/19602/SvcType/WRPAC/Issuance` for the issuance service - `http://uri.etsi.org/19602/SvcType/WRPAC/Revocation` for the revocation service 2. The Commission **establishes, maintains and publishes** the **EU WRPAC Providers List** (`http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList`) compiling information from all Member States. There is no separate national list for Access CAs; the EC-published list is the authoritative source for cross-border trust discovery. ### Provider of Registration Certificates (PRC) - **Duties:** Issue registration certs to RPs **after** Registrar validation. - **Revocation**: Revokes certificates when not aligned with Registrar anymore. Publish status list for issued certs. !!! important "PRC Notification Requirements" Per Commission Implementing Regulation (EU) 2024/2980 (Art. 4-5), Germany must: 1. **Notify** the European Commission of each PRC with `serviceTypeIdentifier` values: - `http://uri.etsi.org/19602/SvcType/WRPRC/Issuance` for the issuance service - `http://uri.etsi.org/19602/SvcType/WRPRC/Revocation` for the revocation service 2. The Commission **establishes, maintains and publishes** the **EU WRPRC Providers List** (`http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList`) compiling information from all Member States. There is no separate national list for PRCs; the EC-published list is the authoritative source for cross-border trust discovery. ### Relying Party (RP) - **Holds:** Access + registration certificates. - **Duties:** Validate presented PID; monitor own certificate expiry/rotation. > **Revocation semantics (applies to all):** Treat `revoked` as deny. `unknown`/network errors are policy-defined; for PID/WUA issuer checks Germany adopts **fail-closed**. --- ## EU Trust Lists (Schema) Per Commission Implementing Regulation (EU) 2024/2980, Member States **notify** the European Commission of their trusted entities. The Commission then **establishes, maintains and publishes** the Lists of Trusted Entities following the [ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) specification as signed JSON documents (JWS). Each role type has its own list structure as defined in the specification's Annexes D-I. **There are no separate national trust lists** for these roles. The EC-published lists are the single authoritative source, compiling notifications from all Member States into **separate EU-wide lists per role type**: ```plantuml @startuml skinparam Padding 2 skinparam NodePadding 4 skinparam wrapWidth 200 skinparam RectangleBorderThickness 2 skinparam rectangle { BackgroundColor<> #E3F2FD BorderColor<> #1565C0 BackgroundColor<> #FFF3E0 BorderColor<> #EF6C00 } rectangle "**EU Level (Commission publishes)**" <> { rectangle "EU PID Providers List" as EU_PID <> rectangle "EU Wallet Providers List" as EU_WP <> rectangle "EU WRPAC Providers List" as EU_ACA <> rectangle "EU WRPRC Providers List" as EU_PRC <> rectangle "EU PubEAA Providers List" as EU_PUB <> rectangle "EU Registrars List" as EU_REG <> } rectangle "**Member State (DE) notifies**" <> { rectangle "DE PID Provider info" as DE_PID <> rectangle "DE Wallet Provider info" as DE_WP <> rectangle "DE WRPAC Provider info" as DE_ACA <> rectangle "DE WRPRC Provider info" as DE_PRC <> rectangle "DE PubEAA Provider info" as DE_PUB <> rectangle "DE Registrar info" as DE_REG <> } rectangle "**Other MS notify**" <> { rectangle "..." as OTHER <> } DE_PID -up-> EU_PID : notifies DE_WP -up-> EU_WP : notifies DE_ACA -up-> EU_ACA : notifies DE_PRC -up-> EU_PRC : notifies DE_PUB -up-> EU_PUB : notifies DE_REG -up-> EU_REG : notifies OTHER -up-> EU_PID OTHER -up-> EU_WP note right of EU_PID EC compiles all MS notifications into each EU list end note @enduml ``` Each service entry in the trust list follows the TS 119 602 schema (see Annexes D-I for role-specific profiles), containing: - `entity` — the organization operating the service - `serviceTypeIdentifier` — canonical identifier for the service type (Issuance/Revocation) - `policySet` — applicable policies - `status` — current status (granted, suspended, withdrawn) - Certificates — trust anchors and signing certificates - Metadata — contact information and additional attributes !!! note "Separate Lists per Role Type" TS 119 602 defines **separate profiles and list types** for each role (Annexes D-I). The Commission establishes, maintains and publishes separate EU-wide lists for each role type, compiling notifications from all Member States. There are no national trust lists to aggregate—the EC-published lists are the authoritative source. ### Service Type Identifier Mapping The following table maps ecosystem roles to their canonical `serviceTypeIdentifier` values as defined in [ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) (Annexes D-I): | Role | serviceTypeIdentifier | | -------------------------------- | ------------------------------------------------------------- | | **PID Provider (Issuance)** | `http://uri.etsi.org/19602/SvcType/PID/Issuance` | | **PID Provider (Revocation)** | `http://uri.etsi.org/19602/SvcType/PID/Revocation` | | **Wallet Provider (Issuance)** | `http://uri.etsi.org/19602/SvcType/WalletSolution/Issuance` | | **Wallet Provider (Revocation)** | `http://uri.etsi.org/19602/SvcType/WalletSolution/Revocation` | | **WRPAC Provider (Issuance)** | `http://uri.etsi.org/19602/SvcType/WRPAC/Issuance` | | **WRPAC Provider (Revocation)** | `http://uri.etsi.org/19602/SvcType/WRPAC/Revocation` | | **WRPRC Provider (Issuance)** | `http://uri.etsi.org/19602/SvcType/WRPRC/Issuance` | | **WRPRC Provider (Revocation)** | `http://uri.etsi.org/19602/SvcType/WRPRC/Revocation` | | **PubEAA Provider (Issuance)** | `http://uri.etsi.org/19602/SvcType/PubEAA/Issuance` | | **PubEAA Provider (Revocation)** | `http://uri.etsi.org/19602/SvcType/PubEAA/Revocation` | | **Register** | `http://uri.etsi.org/19602/SvcType/Register` | ### LoTE Type URIs TS 119 602 defines the following LoTE type URIs (see Annex C.2.1) for the aggregated EU lists: | LoTE Type | URI | | --------------------------------- | ----------------------------------------------------------------- | | **PID Providers List** | `http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList` | | **Wallet Providers List** | `http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList` | | **WRPAC Providers List** | `http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList` | | **WRPRC Providers List** | `http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList` | | **PubEAA Providers List** | `http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList` | | **Registrars and Registers List** | `http://uri.etsi.org/19602/LoTEType/EURegistrarsAndRegistersList` | !!! note "Service Type Identifiers" Service type identifiers distinguish between **Issuance** and **Revocation** services. Implementers should refer to [ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) Annexes D-I for the complete profile specifications for each role. --- ## Sandbox vs. Production Environments Both environments are following the same architecture and validation rules, but are strictly separated: - Separate TL URLs/signing keys, PKIs, policy OIDs, DNS/SANs, CRL endpoints. - Clients for SANDBOX must *only* trust SANDBOX TL; ditto for PROD. - Prefer short-lived certs in TEST; re-issue under PROD PKI for go-live. The production trusted entities will be notified to the European Commission and included in the respective **EU Lists of Trusted Entities** (per role type) as per Commission Implementing Regulation (EU) 2024/2980. The sandbox trusted entities will not be notified to the EC, but the endpoints will be made available in the Sandbox environment for testing purposes. !!! note "Validation flow" The [development guide](https://bmi.usercontent.opencode.de/eudi-wallet/developer-guide/) will provide detailed validation flow to help implementers understand how to validate the various artefacts using the trust lists. --- ## Wallet Attestation Within the eIDAS ecosystem, Wallets need to authenticate toward PID Providers and EAA providers to prove their authenticity and trustworthiness. Therefore, Wallet Providers issue assertions regarding particular Wallet Units. These assertions are referred to as **Wallet Attestation** and **Key Attestation**. ### Attestation Flow 1. Before issuing a Wallet Attestation, the Wallet Provider backend checks various inputs, including information from the **Platform Provider** (e.g., mobile OS) about the integrity and version of the Wallet app on the user's device. 2. Wallet Attestation and Key Attestations are signed by the Wallet Provider backend. 3. The corresponding Wallet Provider certificates are included in the EU Wallet Providers List (published by the EC based on MS notifications). 4. By presenting the Wallet Attestation during issuance, the PID Provider validates the authenticity of the Wallet Unit. There may be multiple Key Attestations from a Wallet Unit during one OpenID4VCI flow. The Wallet Provider may set up a pseudonymous user account for a particular user during the installation and activation of the Wallet Unit. ### Technical Format For the [OpenID for Verifiable Credentials](https://openid.net/sg/openid4vc/) protocol family, the Wallet Attestations are JWTs conforming to the definition given in the [OpenID4VC High Assurance Interoperability Profile with SD-JWT VC](https://openid.github.io/OpenID4VC-HAIP/openid4vc-high-assurance-interoperability-profile-wg-draft.html). The Wallet Attestation mechanism ([OAuth 2.0 Attestation-Based Client Authentication](https://datatracker.ietf.org/doc/draft-ietf-oauth-attestation-based-client-auth/)) is yet to be finalized, so details are subject to change. !!! info "Implementation Details" A detailed flow for the issuance of a Wallet Attestation to the Wallet Unit is available in the [Wallet Attestation flow description](../../archive/flows/Wallet-Attestation.md). --- ## Wallet Invocation For Relying Parties it would be helpful if all wallet implementations in Europe share the same invocation mechanism. To ensure that only valid Wallets can be addressed, see the [EUDI-link governance proposal](../../archive/EUDI-link-governance.md). --- ## Transparency and Auditability Transparency features accompany the trust mechanisms: - **User transparency**: The Wallet Unit makes all transactions (PID/EAA issuance and presentations) transparent to the user, e.g., through a dashboard. This information is managed and stored by the Wallet Unit only. - **Public auditability**: Registration information of RPs, including history, is made public to ensure that public audit is possible. --- ## Trust in EAA Issuance and Presentation ## Overview Electronic Attestations of Attributes (EAA) provide a flexible form of electronic attribute attestations under eIDAS 2.0. They rely on scheme-based trust and existing acceptance structures, offering flexibility, scalability, and cost efficiency for use cases where document-equivalent evidentiary value is not required. !!! tip "EAA are appropriate when" - Existing acceptance relationships exist between issuer and relying parties - Document-equivalent evidentiary value is not legally required - Trust can be established through scheme-based governance - Cost efficiency and flexibility are important considerations For guidance on choosing between EAA, QEAA, and PubEAA, see the [Trust Overview and Decision Guide](./decision-guide.md). --- ## Trust Model for EAA ### Scheme-Based Trust For EAA, trust is established through **rulebooks or schemes** accepted by the relying party. These schemes define: - Credential semantics and attribute definitions - Authorized issuers and their requirements - Trust anchors and validation procedures - Acceptance conditions Relying parties explicitly decide which schemes they accept and validate attestations accordingly. This makes EAA: - **Contextual:** Trust depends on the specific scheme - **Purpose-bound:** Schemes are designed for specific use cases - **Verifier-driven:** Relying parties choose which schemes to trust ### Issuer Identity Assurance EAA providers are identified via **Access Certificates issued by a Registrar**, providing the same cryptographic security level as QEAA and PubEAA providers. The key difference from QEAA is not security, but the trust model: | Aspect | EAA | QEAA | |----------------------------------| --------------------------------- | --------------------------------- | | **Issuer identity verification** | Access Certificate from Registrar | Access Certificate from Registrar | | **Trust anchor** | Scheme governance | EU Trusted List | | **Evidentiary value** | Contextual / scheme-dependent | Document-equivalent by law | | **Liability** | Contractual / scheme-based | Statutory | --- ## Catalogues of Schemes for Attestation of Attributes ### National Catalogues Each member state maintains a national catalogue of schemes for the attestation of attributes. For Germany, this includes: - Scheme definitions and identifiers - Trust anchors and validation requirements - List of authorized issuers per scheme For details on catalogue structure, registration, and governance, see [Attribute Catalogues](../../features/EAA/catalog-of-attestations.md). ### Trust-Relevant Content of a Credential Scheme From a trust perspective, a credential scheme defines: 1. **Issuer requirements:** Who may issue attestations under this scheme 2. **Verification rules:** How relying parties validate the attestation 3. **Trust anchors:** What certificates or keys are trusted For credential design aspects (attribute definitions, revocation mechanisms, signatures), see [Design Recommendations](../../features/EAA/design-recommendations.md) --- ## Trust Architecture ![Trust](../../../figures/trust-eaa.png) Figure: Trust architecture for issuance and presentation of EAAs For a description of general trust management between the participants of the ecosystem see [Trust Validation Overview](./trust-validation.md). --- ## During EAA Issuance The EAA provider must: 1. **Authenticate to the Wallet** using its Access Certificate 2. **Verify the Wallet Unit** through Wallet Attestation and Key Attestation(s) 3. **Obtain attribute data** from the authentic source (issuer's own data or authorized source) 4. **Issue the EAA** signed according to the scheme requirements The Wallet Unit: 1. **Verifies the issuer's Access Certificate** against the national access certificate providers list 2. **Checks the revocation status** of the issuer's certificate 3. **Optionally verifies scheme membership** if required by the scheme 4. **Stores the EAA** after successful validation --- ## During EAA Verification The Relying Party Instance: 1. **Presents its Access Certificate and Registration Certificate** to the Wallet Unit 2. **Requests specific attributes** according to its registered intended use 3. **Receives the EAA presentation** from the Wallet The Wallet Unit: 1. **Validates the RP's certificates** against national trust lists 2. **Checks the RP's intended use** against the requested attributes 3. **Obtains user consent** for the presentation 4. **Creates and sends the presentation** The Relying Party then: 1. **Validates the EAA signature** against the scheme's trust anchors 2. **Checks the EAA's validity** via status lists 3. **Verifies the scheme membership** of the issuer (if applicable) 4. **Applies acceptance rules** according to its policies --- ## Legal Effect and Acceptance EAA shall not be denied legal effect or admissibility as evidence in legal proceedings solely on the ground that: - They are in electronic form, or - They do not meet the requirements for qualified electronic attestations of attributes Acceptance of EAA depends on: - Relying party policies - Contractual agreements - Market-related customs, conditions, and practices - Scheme governance rules --- ## Use Cases for EAA EAA are appropriate for: - **Private sector attestations:** Membership cards, loyalty programs, professional certifications (where document equivalence is not required) - **Low to medium risk scenarios:** Where official document quality is not legally mandated - **Established trust relationships:** Where issuer and relying parties have existing acceptance structures - **Sector-specific schemes:** Industry credentials with established governance - **Self-issued attributes:** Where the issuer attests their own characteristics --- ## Related Resources - [Trust Overview and Decision Guide](./decision-guide.md) — For choosing between attestation types - [Trust in QEAA and PubEAA](./trust_q_pub_eaa_issuance_presentation.md) — For qualified attestations - [Trust Validation Overview](./trust-validation.md) — For technical validation details - [Wallet-Relying Party Authentication](./wallet-relying-party-authentication.md) — For RP registration and certificates - [EAA Design Section](../../features/EAA/index.md) — For credential design, formats, signatures, and revocation mechanisms - [Design Recommendations](../../features/EAA/design-recommendations.md) — Best practices for well-made EAAs --- ## Legal References ### Primary Regulation **Regulation (EU) No 910/2014 (eIDAS)** as amended by **Regulation (EU) 2024/1183** (eIDAS 2.0). Key articles for EAA: | Article | Topic | | ------------------ |----------------------------------------------------------| | **Article 45d** | Electronic attestation of attributes (general framework) | | **Article 45d(3)** | Legal effect of electronic attestation of attributes | ### ETSI Standards | Standard | Topic | |----------------------------------------------------------------------------------------------| -------------------------------------------------------------- | | **[ETSI TS 119 472-1](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | General requirements for electronic attestations of attributes | | **[ETSI TS 119 472-2](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | Presentation requirements | | **[ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | Issuance requirements | | **[ETSI TS 119 411-8](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | Access Certificates | | **[ETSI TS 119 475](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | Registration Certificates | --- ## Trust in PID Issuance and Presentation ## Overview Personal Identification Data (PID) represents core identity data of a person and forms the foundational identity layer within the EUDI Wallet ecosystem. PID is distinct from other attestation types (EAA, QEAA, PubEAA) in that it focuses on core identity establishment. !!! info "Note" Only a single PID Provider is planned for the EUDI Ecosystem in Germany at the moment. For guidance on the differences between PID and other attestation types, see the [Trust Overview and Decision Guide](./decision-guide.md). --- ## Trust Model for PID Trust in PID is anchored in: | Trust Element | Description | |---------------------------------|------------------------------------------------------------------| | **Member State responsibility** | PID is issued by or under the responsibility of the Member State | | **National certification** | Based on BSI TR-03189 in Germany | | **Level of Assurance High** | As required by eIDAS | | **National PID providers list** | Trust status published in national trust list | ### Liability under PID The Member State is responsible for the proper functioning of the PID system. This includes: - Ensuring the integrity of the identity proofing process - Operating or supervising the PID Provider - Maintaining the national trust infrastructure --- ## Trust Architecture The technical trust architecture for the PID-related use cases is shown in the following figure: ![Trust](../../../figures/trust-pid.png) Figure: Technical trust architecture for PID issuance and presentation This trust architecture is used by several trust-related processes during the lifecycle of a PID. For a description of general trust management between the participants of the ecosystem see [Trust Validation Overview](./trust-validation.md). --- ## During PID Issuance - Wallet Unit requests the signed issuer metadata from the PID Provider, signed with the PID Providers access certificate and containing the access certificate and service endpoints - Wallet checks the trust status of the access certificate via the national access certificate providers list and the validity via its revocation list - Wallet Unit checks the trust status of the PID Provider via the national PID providers list - Wallet Unit presents a Wallet Attestation and Key Attestation(s) to the PID Provider - PID Provider checks the attestations and the Wallet Provider trust status via the national Wallet providers list - PID provider signs PIDs and PID TSL using certificates from a PID CA, linked to the PID Providers entries in the national trust list --- ## During PID Presentation and Validation - Relying Party Instance presents its access certificate and registration certificate to the Wallet Unit when requesting a PID presentation - Access and registration certificates of the RP are verified by the Wallet Unit via the national access certificate and registration certificate providers lists and the corresponding revocation / status lists - Trust status of Wallet and PID Providers is checked by the Relying Party Instance via the national Wallet and PID providers lists - During PID presentation, an RP does not directly verify the validity of the Wallet Unit but can do so implicitly by verifying the presented PID - PID signature certificate is verified against national PID providers list --- ## PID PKI The issuing and revocation services of a PID Provider use digital certificates to sign issued PID credentials and corresponding PID status lists. These certificates are provided by a PID PKI: - different signing keys and certificates are used for PIDs and for status lists - signing certificates for PIDs and for status lists are issued by different CAs - cryptography is compliant to mandatory algorithms in eIDAS Implementing Acts, see Cryptographic Algorithms in [Security Requirements](../crosscutting-concepts/security-requirements.md) - trust anchor for certificates used by PID Provider services is the national PID providers trust List There are different approaches for the structure and levels of a PID PKI, e.g.: Option 1: ![PKI_PID_M1](../../../figures/pid_pki_model_1.png) - one PID Root CA for different issuing Sub-CAs - Sub-CAs issue signing certificates for PIDs and for status lists - Sub-CAs are published with the PID Providers services on the PID providers trusted list or: Option 2: ![PKI_PID_M2](../../../figures/pid_pki_model_2.png) - self-signed issuing PID CAs for PID and for status list signing certificates - PID CAs are published on the PID providers trusted list The decision for the structure of a PID PKI is an implementation detail of the PID provider and does not inflict the general PID trust mechanism. To verify a PID, a Relying Party follows the certificate chain of a signing certificate to the trust anchor in the corresponding trusted list entry for the issuing PID provider. --- ## Related Resources - [Trust Overview and Decision Guide](./decision-guide.md) — For understanding trust models - [Trust Validation Overview](./trust-validation.md) — For technical validation details - [Wallet-Relying Party Authentication](./wallet-relying-party-authentication.md) — For RP registration and certificates - [Trust Overview and Decision Guide](./decision-guide.md) — For credential definitions and comparison --- ## Trust in QEAA and PubEAA Issuance and Presentation ## Overview Qualified Electronic Attestations of Attributes (QEAA) and Public Electronic Attestations of Attributes (PubEAA) provide the highest level of legal assurance in the eIDAS framework. Both offer **document-equivalent evidentiary value**—the same legal effect as lawfully issued attestations in paper form. !!! warning "QEAA and PubEAA are special-purpose instruments" QEAA and PubEAA are not the default choice for all use cases. They should be used only when document-equivalent evidentiary value is legally or practically required. For guidance on choosing between EAA, QEAA, and PubEAA, see the [Trust Overview and Decision Guide](./decision-guide.md). --- ## QEAA: Qualified Electronic Attestations of Attributes ### When QEAA is Required QEAA are appropriate in **exceptional cases**, particularly when: 1. **No existing trust or acceptance structure** exists between issuer, user, and relying party 2. **Regulatory requirements explicitly demand** original-document equivalence 3. **Cross-border use is intended** and acceptance conditions in other Member States are unknown 4. **Risk must be outsourced** to a supervised third party via statutory liability ### Trust Model for QEAA Trust in QEAA is anchored in the **qualified status of the Trust Service Provider (QTSP)**, including: | Trust Element | Description | | ------------------------------ | ----------------------------------------------------------------- | | **Conformity assessment** | Ex-ante verification by a conformity assessment body | | **Supervision** | Ongoing supervision by the national supervisory body | | **EU Trusted List inclusion** | Publication in the EU List of Trusted Services | | **Qualified signatures/seals** | QEAA must be signed with a qualified electronic signature or seal | | **Statutory liability** | QTSP assumes liability for damages under eIDAS | ### QEAA Providers - QEAA may **only be issued by QTSPs** (Qualified Trust Service Providers) - QTSPs must undergo conformity assessment and be supervised - QTSPs must be listed in the EU Trusted List of qualified services - QTSPs must verify attributes against authentic sources per Article 45e eIDAS ### Liability under QEAA The QTSP is liable for damages caused to any natural or legal person due to failure to comply with the obligations under eIDAS. This statutory liability regime provides: - **Mandatory professional liability insurance** - **Presumption of fault** (QTSP must prove absence of negligence) - **Direct statutory claims** against the QTSP --- ## PubEAA: Public Electronic Attestations of Attributes ### When PubEAA is Appropriate PubEAA are specifically for **public bodies responsible for authentic sources** that need to: 1. Issue attestations with document-equivalent evidentiary value 2. Maintain issuance **under their own authority and control** 3. Issue attestations **in their own name** (not via a QTSP) 4. Avoid the obligation to provide verification mechanisms for QTSPs per Article 45e ### Trust Model for PubEAA Trust in PubEAA is anchored in the **public-law mandate** of the issuing authority: | Trust Element | Description | | ----------------------------------- | ---------------------------------------------------------------- | | **Public mandate** | Authorization by the Member State under public law | | **Authentic source responsibility** | The public body is responsible for the authentic source | | **Certified attributes** | Authorization evidenced via qualified certificates | | **Annex VII compliance** | Must meet requirements specified in Annex VII of eIDAS | | **Member State notification** | Public body must be designated and notified to the EU Commission | ### PubEAA Providers - Issued by or on behalf of a **public body responsible for an authentic source** - The public body must be **designated by the Member State** - Must be **listed by the Member State and notified to the European Commission** - Published on the **national PubEAA providers list** ### Public vs. QTSP Issuance Public bodies have a choice: | Option | Issuer | Control | Name on Attestation | Cost | | ----------------- | ----------- | ------- | ------------------- | ------ | | **PubEAA** | Public body | Full | Public body | Higher | | **QEAA via QTSP** | QTSP | Shared | QTSP | Lower | The decision depends on whether the public body needs to maintain control and issue in its own name versus leveraging QTSP infrastructure. --- ## EU Catalogue of Schemes for Attestation QEAA and PubEAA schemes are registered in the EU catalogue of schemes for the attestation of attributes, as defined in [EU Implementing Act 2025/1569](https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=OJ:L_202501569), Article 8. ### EU Catalogue for Trust Validation The EU catalogue serves as a **trust anchor** for cross-border recognition: | Aspect | National Catalogue | EU Catalogue | |------------------------------| ------------------ | ------------------------ | | **Initial publication** | Required | Optional | | **Cross-border recognition** | National only | EU-wide | | **Trust level** | Member State | EU-wide interoperability | Relying parties verify QEAA/PubEAA by looking up the scheme in the EU catalog to confirm it meets qualified requirements. For general catalogue concepts, structure, and governance, see [Attribute Catalogs](../../features/EAA/catalog-of-attestations.md). --- ## Trust Architecture ![Trust](../../../figures/trust-qeaa-pubeaa.png) Figure: Trust architecture for QEAA / PubEAA issuance and presentation For a description of general trust management between the participants of the ecosystem see [Trust Validation Overview](./trust-validation.md). --- ## During QEAA/PubEAA Issuance ### QEAA Issuance The QTSP must: 1. **Verify the holder's identity** according to Article 24(1) eIDAS 2. **Verify attributes** against authentic sources per Article 45e 3. **Issue the QEAA** signed with a qualified electronic signature or seal 4. **Ensure inclusion** in the EU catalogue of schemes ### PubEAA Issuance The public body must: 1. **Verify the holder's identity** (Article 24(1) applies indirectly; higher levels possible) 2. **Verify attributes** directly from the authentic source (the public body is the authentic source) 3. **Issue the PubEAA** signed with a qualified electronic signature or seal 4. **Ensure inclusion** in the EU List of Enabled Authentic Sources --- ## During QEAA/PubEAA Presentation The Relying Party Instance verifies: 1. **Look up the scheme** by name from the credential in the EU catalogue of attestations - If not found in EU catalogue: look up in national catalogue 2. **Verify credential type** (QEAA or PubEAA) 3. **Validate the qualified signature/seal** against the EU Trusted List 4. **Check status/revocation** via Token Status List ### Trust Chain Validation For QEAA: 1. Verify the issuing QTSP is listed in the EU Trusted List 2. Verify the signature certificate chains to a qualified trust anchor 3. Verify the scheme is registered in the catalogue For PubEAA: 1. Verify the issuing public body is in the EU List of Enabled Authentic Sources 2. Verify the signature with qualified seal/signature 3. Verify the scheme is registered in the catalogue --- ## Legal Effect and Recognition Both QEAA and PubEAA have: - **Same legal effect as lawfully issued attestations in paper form** - **Recognition across all Member States** under eIDAS qualified trust services - **Admissibility as evidence** in legal proceedings throughout the EU --- ## Use Cases ### QEAA Use Cases - **Banking and insurance sector:** Regulatory requirements demand document equivalence - **Cross-border transactions:** Unknown acceptance conditions in other Member States - **High-risk scenarios:** Where statutory liability and supervision provide assurance to relying parties ### PubEAA Use Cases - **Government-issued attestations:** Driving licenses, professional qualifications, residence permits - **Authentic source attestations:** Where the public body is the authoritative source of the data - **Exemption from Article 45e:** To avoid providing verification mechanisms for QTSPs --- ## Related Resources - [Trust Overview and Decision Guide](./decision-guide.md) — For choosing between attestation types - [Trust in EAA](./trust_eaa_issuance_presentation.md) — For EAA - [Trust Validation Overview](./trust-validation.md) — For technical validation details - [EAA Design Section](../../features/EAA/index.md) — For credential design, formats, and technical mechanisms - [Design Recommendations](../../features/EAA/design-recommendations.md) — Best practices applicable to all credential types --- ## Legal References The following are the primary normative sources for QEAA and PubEAA: ### Primary Regulation **Regulation (EU) No 910/2014 (eIDAS)** on electronic identification and trust services for electronic transactions in the internal market, **as amended by Regulation (EU) 2024/1183** (eIDAS 2.0). Key articles for QEAA and PubEAA: | Article | Topic | | ----------------- | ------------------------------------------------------------ | | **Article 45a** | European Digital Identity Wallets | | **Article 45b** | Relying parties of European Digital Identity Wallets | | **Article 45d** | Electronic attestation of attributes | | **Article 45e** | Verification of attributes against authentic sources | | **Article 45f** | Qualified electronic attestation of attributes | | **Article 45g** | Electronic attestation of attributes issued by public bodies | | **Article 24(1)** | Identity verification requirements for trust services | ### Annexes to eIDAS 2.0 | Annex | Content | Applies to | | ------------- |--------------------------------------------------------------------------------| ----------------- | | **Annex V** | Requirements for qualified electronic attestations of attributes | QEAA | | **Annex VI** | Minimum list of attributes (attribute catalogue context) | EAA, QEAA, PubEAA | | **Annex VII** | Requirements for electronic attestations of attributes issued by public bodies | PubEAA | ### Implementing Acts | Implementing Act | Topic | | ----------------------------------------------------- | ----------------------------------------------------------------- | | **Commission Implementing Regulation (EU) 2025/1569** | Catalogue of schemes for attestation of attributes | | **Implementing acts under Article 19a** | Organisational and technical measures for trust service providers | ### ETSI Standards | Standard | Topic | |----------------------------------------------------------------------------------------------| -------------------------------------------------------------- | | **[ETSI TS 119 472-1](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | General requirements for electronic attestations of attributes | | **[ETSI TS 119 472-2](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | Presentation requirements | | **[ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | Issuance requirements | | **[ETSI TS 119 411-8](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | Access Certificates | | **[ETSI TS 119 475](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)** | Registration Certificates | !!! info "Legal Disclaimer" This document reflects a systematic interpretation of the eIDAS framework and supports informed decision-making. It does not replace legal analysis for individual cases. --- ## Wallet-Relying Party Authentication ## Overview This document describes how Relying Parties (RPs) authenticate themselves to EUDI Wallets and how Wallets validate that RPs only request data within their declared intended use. The authentication requirements are derived from Article 5b of the eIDAS 2 regulation and the Implementing Acts. --- ## Core Principles The authentication architecture is based on the following principles: ### Direct Authentication RPs include certificates and attestations directly in their requests to the EUDI Wallet. This approach: - Supports both online and offline interactions - Reduces Wallet communication with Registrars - Prevents potential tracking of Wallet interactions by Registrars ### Separation of Concerns Two distinct certificates serve different purposes: | Certificate | Purpose | Standard | | ---------------------------- | ----------------------------------- |------------------------------------------------------------------------------------------| | **Access Certificate** | Authenticates the RP's identity | [ETSI TS 119 411-8](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | | **Registration Certificate** | Declares the RP's intended data use | [ETSI TS 119 475](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | This separation allows RPs to include only the attestations relevant to each specific request. ### Machine-Processable Intended Use - Wallets can automatically match the intended use against presentation requests - RPs can update their intended uses, but requests must never exceed registered scope - Over-asking (requesting more than registered) is detected and flagged to users --- ## Trust Architecture ```plantuml @startuml left to right direction skinparam rectangle { BackgroundColor White BorderColor Black } skinparam card { BackgroundColor Yellow } rectangle "Trusted List" as tl rectangle "Wallet-Relying Party Registrar" as wrp_registrar rectangle "Wallet" as wallet card "Access Certificate" as ac card "Registration Certificate" as rc rectangle "Verifiable Presentation" as vp rectangle "Wallet-Relying Party" as wrp wrp --> wrp_registrar : onboarded wrp_registrar --> tl : published wrp_registrar --> ac : issues wrp_registrar --> rc : issues ac --> wrp : issued for rc --> wrp : issued for vp --> wrp : presented to wallet --> vp : creates ac --> vp : used for authentication rc --> vp : used for intended use @enduml ``` --- ## RP Registration Process To interact with an EUDI Wallet, an RP must: 1. **Register at a national Registrar** — Provide identity information and undergo validation 2. **Obtain an Access Certificate** — For authentication with Wallets 3. **Register intended use** — Declare which attributes will be requested and for what purpose 4. **Obtain Registration Certificate(s)** — Documenting the declared intended use ### Access Certificate The Access Certificate identifies the RP and enables authentication with Wallets. Key aspects: - **Identity binding**: Contains the RP's verified legal identity - **Official identifiers**: May include EORI, LEI, VAT number, national business register number, or other official identifiers - **Key management**: RPs can request multiple certificates for key rotation - **Revocation**: Can be revoked immediately to reduce breach risk - **Retention**: Must remain available via the Registrar for 10 years For technical specifications, see **[ETSI TS 119 411-8](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)**. ### Registration Certificate The Registration Certificate documents what data the RP intends to request. Key aspects: - **Intended use declaration**: Specifies which attributes may be requested - **Purpose description**: Human-readable explanation shown to users (multi-language support) - **Service description**: Description of the RP's service - **Contact information**: How users can reach the RP - **Privacy policy**: Link to the RP's data protection information - **Status management**: Revocation capability for invalid certificates For technical specifications, see **[ETSI TS 119 475](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)**. --- ## Wallet Validation Process When receiving a presentation request, the Wallet performs the following validations: ### 1. RP Authentication - Validate the Access Certificate chain of trust - Verify the certificate is not revoked (via CRL or Status List) - Confirm the RP is registered in a recognized Registrar ### 2. Intended Use Validation (Over-Asking Check) - Verify the Registration Certificate is valid and not revoked - Compare requested attributes against the declared intended use - Flag over-asking if the request exceeds the registered scope - The request must be equal to or a subset of the registered intended use ### 3. User Information - Display RP identity and purpose to the user - Show any warnings (e.g., over-asking detected) - Obtain user consent before releasing data --- ## Interoperability ### EU-Wide Standardization (ETSI Standards) The following are standardized across the EU: | Aspect | Standard | | -------------------------------- |------------------------------------------------------------------------------------------| | Access Certificate format | [ETSI TS 119 411-8](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | | Registration Certificate format | [ETSI TS 119 475](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | | General attestation requirements | [ETSI TS 119 472-1](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | | Presentation requirements | [ETSI TS 119 472-2](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | | Issuance requirements | [ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | ### Member State Specific The following can be defined individually by each Member State: - RP Registrar onboarding procedures - Registrar API and interaction mechanisms - Additional national requirements --- ## Verifier-as-a-Service When an RP uses a hosted verification service: - The presented certificates must belong to the **RP**, not the service provider - The RP must disclose the service provider (e.g., in their privacy policy) - The service provider may use their own Access Certificate with delegation --- ## Intermediaries RPs may interact with Wallets through intermediaries. In this case: - The intermediary uses its own Access Certificate - The Registration Certificate identifies both the RP and the intermediary - The Wallet displays both entities to the user - Revocation of either party's certificate invalidates the relationship --- ## Registrar Requirements While specific APIs are not mandated, Registrars should provide: - **Free read access** to registration information - **Public lookup** of RPs by name or identifier - **Certificate history** including issuance, expiration, and revocation dates - **Security measures** such as rate limiting --- ## Protocol Integration For detailed technical guidance on how Access Certificates and Registration Certificates are used in the OpenID for Verifiable Credentials (OID4VC) protocol family, see [OID4VC Protocol Integration](../../archive/flows/OID4VC-with-WRP-attestations.md). This includes: - Sequence diagrams for issuance (OID4VCI) and presentation (OID4VP) flows - Certificate attachment mechanisms - Proximity (offline) scenarios --- ## Related Resources - [Trust Overview and Decision Guide](./decision-guide.md) — Understanding trust models - [OID4VC Protocol Integration](../../archive/flows/OID4VC-with-WRP-attestations.md) — Protocol integration - [Trust Validation Overview](./trust-validation.md) — Technical validation procedures --- ## Ecosystem Vision & Fundamentals ## Unlocking Value Creation: How the EUDI Wallet Ecosystem Benefits Public and Private Organizations This chapter aims to provide an overview of the value proposition of the EUDI Wallet ecosystem for organizations. The EUDI Wallet ecosystem offers significant value for both public and private organizations by providing a secure, interoperable and user-centric framework to utilize the standardized EUDI wallet features. By integrating the EUDI Wallet into their processes, organizations can drive efficiency, reduce fraud, and improve user experience, all while ensuring compliance with the eIDAS 2.0 regulation. The EUDI Wallet ecosystem provides the following value for public and private organizations in roles where they provide and consume attestations through the EUDI wallet ecosystem: ### Organizations that act as relying parties and consume attestations Better customer satisfaction - Higher conversion rates facilitate market reach through optimized UX - Streamline the onboarding process for customers in a recognizable way by using the wallet for multiple processes - Digitized processes simplify access to goods and services Electronic attestations Incentivize digitization of business processes - Digitize the full business process: enable Relying Parties to utilize multiple EAAs issued by public and private (Q)EAA Providers - Reduce fraud: attested data signed by a trusted authority hinder manipulation of data provided by the user - Automated processing by Relying Parties due to standardized format for the provision of EAA (schema), esp. reduce data entry errors - Opportunity to create value added services requiring secure user identification and authentication Efficiency and cost reduction - Reduce operational costs by achieving significant efficiency gains - Drive down costs for identification and ID verification - Reduce administrative burden - Reduce inconsistencies by minimizing the need for repeated data submissions Secure and trusted transactions - Reduce risks associated with cybercrime like identity theft and online fraud - Protect against unauthorized or fraudulent use - Build trust among users and service providers - Each organisation that wants to interact with an EUDI Wallet, needs to be authenticated before. Harmonization and interoperability - Guarantee availability and reach in the EU and aim for global reach - One technical interface for all wallets - Digital identities are accepted regardless of the Member State - Ensure secure transactions across borders: The EUDI Wallet is a harmonized approach to trust, security, and interoperability for electronic identification and authentication: Wallet-Relying Parties in the role of EAA Providers - Manage assets and related access rights through EAA loaded into the user wallet - Increasing the usage frequency of the wallet by issuing EAA for multiple domains triggers network effects Legal and regulatory compliance - Assure compliance with Union data protection and security laws: data minimization, purpose limitation, and data protection by design and by default - Reliable expression of will by the User - Take informed decisions on trust level according to risk level of transaction ### Organizations that act as relying parties and provide attestations Non-discriminatory, interoperable access to EUDI wallets enable EAA Providers to issue electronic attestations to all users, enhancing trust, privacy, and fraud prevention while reducing manual effort. Private EAA Providers from different business domains augment the value of the whole ecosystem, public stakeholders included. Value creation through attestation issuance - Reduce costs for issuing paper based attestations, especially with higher security requirements - Reduce costs for issuing and maintaining card based attestations, e.g. door keys, without the need to develop and maintain an own app - Minimize manual labor by automating the issuance process - The more EAA are issued and requested by relying parties the more the wallet is attractive for the users (network effect) European Digital Identity Wallets create a level playing field for EAA Providers - Legal framework guarantees non-discriminatory access to all EUDI wallets for all EAA Providers (no restrictions to specific wallets) - Interoperability assures a maximum reach to EUDI wallets for EAA Providers Registered EAA Providers establish trust for the common ecosystem - The authenticity of the EAA Provider is controlled by the EUDI wallet, assuring that only registered EAA Providers can issue attestations to the EUDI wallet - Relying Parties can assure that a certain EAA Provider is registered by a member state Relying Parties/Domains in the role of EAA Providers - Use EAA for sharing personal customer data with third parties: get explicit customer consent, avoid insecure transmission channels - Manage assets and related access rights through EAA loaded into the user wallet - Augment the usage frequency of the wallet by issuing EAA for multiple domains ### Organizations that act as EUDI wallet providers to serve citizens For Germany, the decision has been taken by the government that conditions for non-governmental providers will be created allowing them to have their own EUDI Wallets certified and recognized. In addition, the German government has taken the decision to become a Wallet Provider itself. Therefore, there might be different EUDI Wallets from the private sector competing with the wallet provided by the government. [Here](https://www.bmi.bund.de/SharedDocs/pressemitteilungen/DE/2024/09/eudi-wallet-sep.html), you can find more details about the decision that has been made. To support the development of non-governmental wallets, the German government will open-source its own wallet as a foundational implementation. Additionally, as part of the EUDI wallet ecosystem orchestration, a shared open-source EUDI wallet development will be maintained to enhance synergies, foster trust, and reduce overall costs for ecosystem actors. The major reasons for the German government to become a Wallet Provider are: - Guarantee the availability of at least one EUDI Wallet by end of 2026 / beginning of 2027 - Strengthen the digital sovereignty of the Federal Republic of Germany itself - Offering citizens an EUDI wallet without commercial interests as part of the “öffentliche Daseinsvorsorge" (service provision in the public interest) Becoming a non-government EUDI wallet provider offers e.g. the following opportunities for organizations: - Offer value added services for natural persons on top of the EUDI wallet scope - Improve/retain customer relationship by integrating EUDI Wallet functions into existing customer apps - Bundling services and maximizing synergies as a Qualified Trust Service Provider (QTSP) by offering EUDI Wallet, Qualified Electronic Signature (QES), and Qualified Electronic Attribute Attestation (QEAA) while leveraging economies of scale. --- ## German EUDI Wallet Ecosystem Governance and Operating Model Fundamentals This section presents the core principles and foundational concepts for the design and implementation of the German EUDI Wallet ecosystem governance and EUDI wallet infrastructure operating model based on the EU eIDAS 2.0 regulation adopted to the German context. This document is created iteratively and is continuously expanded and adapted. We value your feedback and suggestions and will integrate them into our FAQ and future updates. ## Empowering Citizens and Residents: Real Choices for Self-Determination with Safeguards in the Digital Realm The aim of this chapter is to provide an overview about the value proposition of the EUDI Wallet ecosystem for citizens and residents.The European Digital Identity Wallet (EUDIW) empowers users by simplifying access to services, reducing administrative burdens, and offering full control over personal data, while ensuring privacy, security, and legal recognition of electronic attestations and signatures across the EU. The EUDI Wallet ecosystem provides the following value for citizens and residents: Comfort and efficiency - Wallet as digital assistant for managing all kind of attestations in one place - Leaving physical documents at home - Good user experience - Simplified onboarding process for new services - Reduce administrative hurdles for users Better access to services - Non-discriminatory access for all actors - Access to wide range of public and private services across the European Union both online and offline - Opportunity to providing fully digitized business processes - Enable powers of representation (e.g. natural and legal persons) - Support of cross-border mobility - Interoperable e-government services Control and transparency over personal data - Exercise their rights in the digital economy/society - Decide what personal data is shared with whom (digital identity under their sole control) - Identify the Relying Party the personal data is shared with (accountability of the RP) - Identify the PID or (qualified) EAA provider from which the PID/EAA was issued - Access a summary of personal data exchanged with Relying Parties and PID/(Q)EAA providers, along with details of electronic signatures generated Enhanced privacy for sharing personal data digitally - Enable privacy preserving techniques which ensure unlinkability, where the attestation of attributes does not require the identification of the user - Relying Parties are not allowed to force the identification of users without legal basis and shall not refuse the use of pseudonyms, where the identification of the user is not required by Union or national law - Support the pseudonymous use of services:Relying parties shall not refuse the use of pseudonyms, where the identification of the user is not required by Union or national law - Data minimization: only personal data that is absolutely required for the business process is shared with Relying Parties - Compared to presenting physical documents, only data that is strictly needed is shared within the use electronic attestations - Unobservability – ensuring that neither the wallet provider nor the (qualified) EAA providers can monitor user activities. High security level - High level of security and trustworthiness - Decentralized architecture with no single eID database for all users reducing impact of data breaches (German eID/ EUDI Wallet Ecosystem) - Protection against cybersecurity risks and cybercrime, identity theft and online fraud19 - Safeguarding personal information from unauthorized or fraudulent use - Support Strong User Authentication to replace user name/password authentication Legal recognition and harmonization - The use of the EUDI Wallet is entirely voluntary, and individuals are free to choose whether or not to use it, without facing any negative consequences - Every citizen and resident has the right to get access to and to use EUDIW free of charge across all member states - Electronic attestations of attributes issued by the public sector have the same legal value as paper attestations across the Union (for PubEAA) - Empower citizens and residents to fully benefit from digitalization Free Qualified Electronic Signatures for non-professional use - Provide citizens and residents with a reliable and legally recognized means to sign documents digitally - Provide citizens and residents with free of charge qualified electronic signatures for non-professional purposes - Sign self-claimed assertions or attributes - Sign a power of attorney statement - Relying Parties will be able to sign through the EUDIW, making it easier for them to use QES ## Driving Societal Progress: The EUDI Wallet Infrastructure is a Foundational Digital Public Infrastructure for Society This chapter aims to provide an overview of the value proposition of the EUDI Wallet ecosystem for the German society and explains why the German government should investing and drive the implementation of the EUDI wallet ecosystem. The digital transformation of German Society shall empower the sovereignty of citizens and residents in a digital space that is less prone to fraud and enables the creation of economic value. To establish the underlying ecosystem a level playing field shall be created for all EUDI wallet ecosystem actors - such as public and private service providers. Enable the digital transformation of German Society - Deploy wallet ecosystem as facilitator for the digital transformation - Provide at least one wallet solution independent of commercial success criteria - Foster innovations as basis for a reliable digital infrastructure - Create a level playing field for all stakeholders in the ecosystem (fair competition) - Enable freedom of choice regarding the EUDI Wallet for citizens and residents to foster trust and innovation Improve the sovereignty of citizens and residents - Empower citizens and residents to act independently and confidently in their digital lives - Bridge the digital divide in our society through inclusive design - Avoid surveillance by design Establish an interconnected ecosystem between all EU member states - Seamless and secure digital interactions across the EU for all ecosystem participants, esp. Users, Relying Parties and EAA Providers - EU wide non-discriminatory ecosystem access to all EUDI wallets for EAA Providers and Relying Parties Improve security and trust for the digital space - Harmonized oversight and trust infrastructure - Ensure accountability of all stakeholders in the ecosystem - Reduce fraud and cybercrime - Protect users against unauthorized or fraudulent use of their digital identities Foster economic value creation - Enable public administrations and private organizations to make their processes more user friendly, transparent and efficient - Enable Relying Parties to reduce their operational costs linked to electronic identification and authentication - Promote the secure digital transformation of SMEs - Facilitate easier access to services across borders, reduce administrative burdens - Enable commercial business models on top of the infrastructure ## Splitting Responsibilities: Differentiation between a Government, Cooperative and Competitive Space for Efficient Collaboration The emergence of the German EUDI wallet ecosystem requires a division of responsibilities between government tasks (government space), public-private cooperation (cooperative space) and individual differentiation and specialization (competitive space). Figure 1 provides an overview of the conceptual framework for the three responsibility spaces. ![Responsibility Spaces.](./figures/EGOM_Figure%201_Three%20Spaces.png) *Figure 1: Mapping the responsibilities of the government, cooperative and competition space* The government domain is dedicated to establishing the essential trust infrastructure for the EUDI wallet ecosystem. It ensures regulatory oversight, certification, enforcement, and the provision of public credentials, such as the Person Identification Data (PID) or a mobile Driving License, to boost credential sharing through the EUDI wallet ecosystem. The cooperative space between diverse public and private ecosystem actors aims to generate network effects through an acceptance network by offering a variety of domain-specific credentials and integrating multiple organizational use cases. This approach ensures a broad reach and drives widespread adoption of the public-private EUDI wallet ecosystem. In this context, "public-private" means that the EUDI Wallet ecosystem extends beyond the public sector, encompassing the private sector, academia, and civil society. Furthermore, collaboration is needed to create common standards that ensure interoperability, foster ease of use and lead to a harmonized ecosystem beyond technical and organizational silos. In addition, co-creation is essential to reducing barriers through an open process aimed to develop fundamental ecosystem components that serve shared interests (e.g., the core EUDI wallet). This approach helps lower overall costs for the EUDI wallet ecosystem and its individual actors. The integration of the government and cooperative spaces within the EUDI wallet ecosystem leads to an unified governance of the EUDI wallet ecosystem, grounded in European and national legislation that establishes the rules, responsibilities, and incentives necessary for effectively orchestrating an ecosystem comprising diverse independent organizations and individuals. It ensures the effective utilization of the underlying trust infrastructure, promotes value creation for both citizens and organizations, and minimizes misuse through preventive measures and appropriate sanctions. Additionally, a key aspect of orchestration involves communicating and educating stakeholders and the broader public about the EUDI wallet ecosystem. These efforts aim to ensure that the ecosystem is visible and operates in alignment with its objectives, fostering a sustainable and trusted environment. The competition space defines the area where ecosystem actors engage in competition and differentiation, fostering choice, innovation, and resilience through multiple offerings within the EUDI wallet ecosystem. The competition space is an integral part of the overall EUDI wallet ecosystem governance, which establishes rules and incentives to ensure fair competition and public accountability. At the same time, it strives to maximize market-driven mechanisms for the participating actors. In the competition space, three key opportunities emerge for innovation in products, services, and business/operating models. Organizations can leverage all three options to develop offerings that deliver value for, through, and on top of the EUDI Wallet ecosystem: ### EUDI Wallet Providers EUDI Wallet Providers offer a EUDI Wallet solution to users, representing a product and service owned and managed by the eIDAS 2.0 certified wallet provider. This offering can be provided as a standalone product or extended beyond the certified EUDI Wallet solution that can be characterized as the Wallet Infrastructure scope. The flexibility of the chosen architecture, which complies with certification requirements and supports additional features and services beyond the core EUDI Wallet instance, allows EUDI Wallet Providers to differentiate (e.g. through UX, user related features) themselves and offers users a range of choices. Illustrating Examples: - Instead of offering a standalone app, the EUDI Wallet solution can be integrated into existing consumer-facing applications, such as insurance´s, bank’s, airline’s or platform provider branded apps. In doing so, the EUDI wallet feature scope and interfaces must be the same to fulfill the upcoming certification requirements and interoperability. To meet upcoming certification requirements and ensure interoperability, the EUDI Wallet's feature scope and interfaces must be the same, regardless of whether additional features beyond the EUDI wallet core are implemented. Features specific to the insurance, banking or airline services that extend beyond the core EUDI Wallet instance are not subject to the eIDAS EUDI wallet certification process. This approach also allows EUDI Wallet providers the flexibility to offer additional, potentially chargeable services for users on top of the certified wallet functionality. These added value services are not part of the EUDI wallet certification process but might be subject to other regulations (e.g. financial services). - An existing identity and trust service providers can transition into an EUDI Wallet Provider, benefiting from the ecosystem's reach and economic synergies with existing services, such as the provision of Qualified Electronic Signatures (QES) or Qualified Electronic Attestation of Attributes (QEAA). From the perspective of existing identity and trust services, the EUDI Wallet ecosystem serves as both a sales channel for established offerings and an opportunity to expand business activities through the EUDI wallet, particularly by engaging directly with users (2C market). ### Ecosystem (Technology) Service Providers Ecosystem (Technology) Service Providers offer products and services that help organizations comply with EUDI Wallet ecosystem requirements, ensuring active participation while maximizing value for individual stakeholders. While these providers do not hold an official role within the EUDI Wallet ecosystem, they have a critical support function by empowering organizations to effectively fulfill their roles (e.g. become a provider or relying party) within the EUDI wallet ecosystem. They provide their products and services directly to individual organizations and receive financial compensation for the value they deliver. Here, market mechanisms define the success as these actors need to convince other organizations that they provide value. Illustrating Examples: - Conformity Assessment Bodies (CABs) are accredited organizations, authorized by the German National Accreditation Body, responsible for conducting assessments that support the certification process for entities such as (possible) EUDI wallet providers. By ensuring compliance with the certification scheme, CABs enable organizations to become part of the EUDI wallet ecosystem. In return for their services, CABs are financially compensated by the organizations utilizing their service. - Technology Service Providers offer organizations products and services to ensure technical compliance and an easy and quick integration with the EUDI wallet ecosystem requirements. For example, they might offer products and services to help organisations to register and onboard in the EUDI wallet ecosystem. Each organization evaluates the value of these offerings and, if deemed beneficial, compensates the technology service provider for the products or services they utilize. - Consulting Service Providers assist organizations in strategically aligning with and leveraging the EUDI Wallet ecosystem to benefit their customers. This support may include optimizing existing business processes through the integration of EUDI Wallets and utilizing the advantages offered by the ecosystem. For their advisory and consulting services, they are compensated by their customers. ### Domain organization and governance For the functioning of the EUDI Wallet ecosystem, various attestations are of great importance. The provision of these attestations is carried out by individual organizations operating in specific domains. Domains are formed by groups of similar or industry-specific use cases. For example, e-prescriptions and health insurance applications are part of the "Health" domain, account openings and bank transfers are part of the "Banking" domain. Organizations and domains are responsible for managing their own trust frameworks. These domain-specific trust management mechanisms determine whether a domain-specific EAA provider is authorized to issue certain EAAs that are universally accepted within the domain. This includes defining the requirements for providing EAAs within the EUDI wallet ecosystem in alignment with domain-specific schemas, which may be mandated by specific disclosure policies to ensure their seamless integration and usage within the ecosystem. Domain-specific trust management may be shaped and defined by regulations specific to each domain, making compliance the responsibility of the respective domains and the organizations involved. For example, regulations such as PSD2 in the banking sector or AML requirements impose specific obligations that influence how banks interact with the EUDI Wallet ecosystem. The interplay between the cooperation and competition space highlights the need for individual organizations and domains to develop their own strategy on how to interact with the EUDI wallet ecosystem. This includes defining to aim for an active role within the ecosystem, such as acting as a Relying Party, EAA provider or an EUDI Wallet provider, or focusing more on a supporting role as e.g. an Ecosystem (Technology) Service Provider that empowers other organizations to leverage the ecosystem effectively. Furthermore, it emphasizes the critical importance of fostering a cooperative space, particularly by establishing a broad public-private acceptance network with diverse use cases. This necessitates contributions from various domains (e.g. financial services, healthcare, mobility and ecommerce) to provide (Q)EAA credentials to the ecosystem, enabling users to access and utilize them through their EUDI wallets. It also empowers relying parties to optimize existing online and offline business processes while driving the development of innovative new offerings. The responsibilities within the EUDI wallet ecosystem can be split into I) responsibilities of the ecosystem, II) domain responsibilities and III) responsibilities of individual organizations: I) Ecosystem responsibilities - Provide EUDI wallet infrastructure including trust management - Harmonize the regulatory framework to ensure the legal operation of the EUDI wallet ecosystem - Provide orchestration capabilities to develop and expand the EUDI wallet ecosystem while facilitating engagement with ecosystem stakeholders and the broader public II) Domain responsibilities - Develop domain specific strategies to interact with the EUDI wallet ecosystem - Define trust mechanisms and requirements to offer (Q)EAAs to the EUDI wallet ecosystem III) Organization responsibilities - Develop organization specific strategies how to interact with the EUDI wallet ecosystem as relying party and/or EUDI wallet provider ## Ecosystem Orchestration: A Critical Capability for Stakeholder Alignment and Continuous Testing and Development Ecosystem orchestration is a resource-intensive and critical capability for ensuring effective stakeholder alignment between the ecosystem vision, the regulatory and governance framework and the successful EUDI wallet ecosystem operationalization that steers the adoption through collaborating with public and private organizations and society. Germany has so far missed the opportunity to fully harness the potential of digital identities and credentials for the benefit of citizens, the economy, and society. The reasons are manifold, ranging from fragmentation caused by numerous initiatives and inconsistent solutions to regulatory barriers, a lack of user-centric approaches, and limited interoperable acceptance among businesses and public authorities. In summary, the current status quo is characterized by inefficiency, high costs, and minimal value generation for stakeholders from an individual and societal perspective. This is largely due to the absence of a shared vision and effective cross-sector orchestration. Addressing these challenges requires close collaboration across national and international boundaries, between public and private sectors, and among governments, public administration, businesses, civil society, and academia. Achieving this transformation demands not only coordinated efforts and collective commitment but also proactive and strategic political and operational orchestration to ensure the EUDI wallet ecosystem success. The development, piloting, and scaling of the German EUDI Wallet ecosystem are progressing simultaneously and must align with existing legal, economic, organizational and technical realities. Executing an ambitious vision for the EUDI Wallet ecosystem necessitates an iterative, small-scale, and experimental approach, integrated within a well-structured and coherent strategy. ### Key Requirements for an Ecosystem Orchestrator Organization An ecosystem orchestrator plays a pivotal role in developing the essential orchestration capabilities required for the successful implementation of the German EUDI Wallet ecosystem. This effort requires strong collaboration with political decision-makers, regulatory authorities, public and private sector organizations, as well as national and international expert communities and professional and individual stakeholders. Figure 2 provides an overview of the stakeholder ecosystem that the orchestrator must engage and collaborate with. ![EUDI Wallet Ecosystem Orchestration.](./figures/EGOM_Figure%202_Orchestration.png ) *Figure 2: Ecosystem orchestration as a key activity to align various stakeholders* Note: The blue arrows indicate that the ecosystem orchestrator must engage with a wide range of stakeholders, extending beyond the EUDI Wallet Ecosystem in Germany. ### German EUDI Wallet ecosystem orchestrator responsibilities Development and Implementation of the Ecosystem Vision, Requirements and being the Owner of the Development Roadmap: - The Ecosystem Orchestrator should collaborate with legislators, regulators, ecosystem actors, domain governance bodies, and the wider public to shape and realize the ecosystem vision for the EUDI wallet ecosystem. This involves defining the requirements for the German EUDI Wallet ecosystem, contributing to national and international regulatory and certification updates as well as standardization activities. In doing so, it should maintain a comprehensive roadmap for the ecosystem development. Public Communication and Community Engagement: - Leading communication and marketing initiatives to enhance the visibility and trust into the German EUDI wallet ecosystem. Actively involving the EUDI wallet community (e.g. in permanent working groups, various events etc.) in the ecosystem development activities to ensure participatory engagement. Education and Empowerment of Ecosystem Actors: - Educating and empowering ecosystem actors, domains, and other stakeholders to actively participate in the EUDI wallet ecosystem while ensuring interoperability across central components (e.g., national playground and sandbox testing between PID provider/EAA providers, EUDI wallets, and relying parties). Active Collaboration with Academia and Experts: - Engaging with academic institutions and experts to explore emerging technologies and assess the technological, economic, legal, and social impacts of the EUDI wallet ecosystem. This includes monitoring, experimenting, standardizing, testing, and adjusting regulatory frameworks to facilitate ecosystem adoption. Contributing to Standardization and Shaping the Technical Discourse - By actively collaborating with standardization bodies, industry experts, and technical communities, the orchestrator organization ensures interoperability, compliance, and technological advancement within the ecosystem. These efforts address challenges related to technical standards, including security, privacy, scalability, interoperability, economic implications, and user experience, while aligning with societal and regulatory requirements. Organizing Innovation Challenges and a Shared Open Wallet Development Process: - Orchestrating and maintaining a shared open wallet development approach in collaboration with other EUDI wallet providers, technology service providers, and the technical expert community, aiming to leverage synergies, foster innovation, minimize overall costs and increase trust and security of central ecosystem components. Responsibility for the Development and Operation of Continuous Testing Spaces: - This responsibility involves the design, implementation, and management of continuous testing spaces of the German EUDI wallet ecosystem. The “Wallet Innovation Lab” serves as a collaborative innovation space for regulators and innovators to explore technological advancements, use cases, and policy innovations that support ecosystem development and may later become integral to it. The “Sandbox” serves as a controlled production-ready environment where new features, updates, and integrations can be safely tested without impacting the live ecosystem. Passing it will be a mandatory step for rollout, and access to it will be integrated into the ecosystem onboarding process. Single Point of Contact for Ecosystem Actors, Regulatory Authorities and the Public: - The Ecosystem Orchestrator serves as a centralized point of contact to address siloed information and operations to mitigate national fragmentation. In collaboration with registrars and national regulatory authorities, the orchestrator ensures that issues such as complaints are effectively processed and enforced, fostering EUDI wallet ecosystem compliance and trust building. The aim of the orchestrator is to bring the relevant actors of the ecosystem together. Aggregating Ecosystem Information as a Single Source of Truth in a Public Dashboard: - The Ecosystem Orchestrator is tasked with promoting transparency by maintaining a public, machine-readable ecosystem dashboard. This dashboard delivers comprehensive, non-privacy-related ecosystem data, promoting accountability and providing valuable insights to stakeholders such as policy-makers, civil society, academia, and the broader public. It serves to enhance transparency and reinforce confidence in the ecosystem's operations. **In order to successfully fulfill the ecosystem orchestrator responsibilities, the following organizational conditions and governance requirements should be ensured:** Public Organization: - The ecosystem orchestrator should be an organization under public control to ensure public accountability and ownership of the federal government. Agile Organization: - The ecosystem orchestrator organization should operate as independently as possible from governmental structures and processes. It should maintain an autonomous budget funded through public subsidies and ecosystem revenues based on the ecosystem operating model. Furthermore, the ecosystem orchestrator should have the ability to offer competitive contracts to specialists and managers from the private market and academia, enabling it to attract top experts and talent to support its organizational mission. This requires an exemption from the principle of equal treatment known in the public sector ("Freistellung vom Gleichstellungsgebot"). In return, the ecosystem orchestrator will be responsible for organizing, strategically guiding, and driving the entrepreneurial development of the ecosystem, ensuring its effective operation. Open Organizational Governance: - The ecosystem orchestrator organization should have an organizational governance that enables broad EUDI wallet ecosystem actors and expert stakeholder participation. In addition to establishing a supervisory board, the inclusion of specialized advisory boards - such as those with scientific, regulatory or market expertise - could be a valuable option. These boards would complement the activities and formats (e.g. public working groups, community events, expert conferences) designed to fulfill the orchestrator's responsibilities. Public Tendering: - The ecosystem orchestrator should issue public tenders for all services related to the ongoing development and operation of the EUDI wallet ecosystem and its core components. It should be empowered to design and implement agile, legally compliant procurement models - such as pre-commercial procurement - to promote transparent, flexible, and sustainable partnerships. All ecosystem components developed through tenders should be licensed as open source to enhance trust, enable reuse, and encourage contributions. Ensuring the sustainable support and safeguarding of non-commercial ecosystem activities: - The ecosystem orchestrator should establish mechanisms to compensate stakeholders who actively contribute to the EUDI wallet ecosystem on a non-commercial basis. This approach aims to encourage voluntary participation and support contributions from civil society actors and academia, e.g. to review the registered intended use for RP in order to fight over identification. Furthermore, the orchestrator should provide robust support for maintainers involved in the shared open wallet development process and related activities. ## Ecosystem Onboarding: Consolidating Information, Centralizing Access, and Enhancing Transparency to Prevent Misuse The eIDAS 2.0 regulation mandates the registration of organizations interacting with the EUDI Wallet ecosystem. This requirement fosters transparency, helps prevent misuse, and serves as a mechanism for co-financing the EUDI Wallet ecosystem and the underlying digital public wallet infrastructure. The ecosystem registration concept centers on the registration of specific use cases and the declaration of intended uses. The German EUDI Wallet Ecosystem prioritizes robust governance to ensure trust, security, and accountability among all ecosystem actors. A key aspect of this governance requirement is a streamlined ecosystem onboarding process, which is essential for gaining access to the EUDI Wallet ecosystem. In line with eIDAS 2.0, a "relying party" refers to any legal or natural person intending to interact with the EUDI Wallet. This term applies universally to organizations that need to register, regardless of whether their intended use involves receiving a PID, obtaining an (Q)EAA, or issuing an (Q)EAA to the ecosystem for use by other actors on behalf of the user. The ecosystem onboarding process occurs online through a central web portal hosted by the ecosystem orchestrator. This portal will also provide a third-party API, enabling the integration of its functionalities into various user contexts by e.g. ecosystem technology service providers as part of their offerings. The ecosystem orchestrator’s website that includes the organization portal serves as the central information hub for the public, including citizens, organizations, and policymakers. The Figure 3 illustrates the concept of the EUD Wallet Ecosystem Web Portal. ![EUDI Wallet Ecosystem Webportal Functionalities.](./figures/EGOM_Figure%203_Onboarding.png) *Figure 3: Component overview of the EUDI Wallet Ecosystem Webportal and Onboarding* Note: The arrows indicate that all (potential) relying parties—such as public, private, research, and civic organizations—interacting with the EUDI Wallet Ecosystem access the EUDI Wallet Ecosystem Web Portal. This also applies to the general public, which includes a broad range of stakeholders (e.g., citizens, academia, civil society, and media), as well as entities performing regulatory roles, such as RP registrar and EUDI Wallet registrar. **The ecosystem web portal provides information and transparency through the following requirements**: - General public information on the web portal for multiple user groups (e.g. citizens, organizations, academia or media). The primary focus of the public information is to explain the EUDI wallet ecosystem, highlight its value, and provide educational content for various stakeholders. - As part of the public information available on the web portal, all intended uses of EUDI Wallet RPs must be published in an aggregated, searchable, and machine-readable format, enabling the public to identify potential misuse. - A public ecosystem dashboard collects and visualizes key performance indicators (KPIs) in a machine-readable format, ensuring transparency without negatively impacting privacy for the general public, civil society, and academic experts. A public ecosystem dashboard concept will outline the details and define the requirements in greater depth at a later project phase. - To streamline ecosystem onboarding, including declaring the intended use and other related activities, the ecosystem web portal will offer an API for third-party integration. **The ecosystem orchestrator web portal enables the EUDI wallet ecosystem onboarding through the following requirements**: - The ecosystem web portal provides the registration process and access to the German EUDI wallet ecosystem (including test enviroments) - The ecosystem web portal requires organizations the opportunity to declare their intended use when interacting with the EUDI Wallet. Organizations joining as relying parties, (Q)EAA providers or EUDI wallet providers have the possibility to open an organization account to manage their activities efficiently. The onboarding steps are defined in an later update and may include intended use declaration, payment and legal issues. **The described ecosystem onboarding process is consistent across various use cases and organizations seeking access to the EUDI Wallet ecosystem. The following examples illustrate this process:** - KYC for Financial Services: A bank seeking to receive a PID (Personal Identification Data) for a KYC (Know Your Customer) process must register as a relying party and declare its intended use as “KYC for Anti-Money Laundering,” specifying the required data attributes necessary for its operations. Once the registration process is complete, the bank receives an access certificate for the authentication and a registration certificate for the intended use. During the use case (e.g., opening a bank account), the declared intended use is displayed to the new customer through his or her EUDI Wallet. If the requested data exceeds the declared intended use, the user is alerted and the process is aborted. This mechanism not only informs users but also helps identify potential misuse by relying parties. - Pseudonym Login: An eCommerce platform requiring a pseudonymous login from the EUDI Wallet must register as a relying party to obtain an access certificate.This intended use are displayed to the users, ensuring transparency and enabling informed consent. - QES/Payment authorization: For payment authorization or qualified electronic signature (QES) providers, the process involves registering to request a transaction authorization for authorizing signing contracts or payments. These intended uses are displayed to users, ensuring transparency and enabling informed consent. - Issuing a Diploma: An educational institution, such as a university, aiming to issue a diploma to a student after graduation, must register as a relying party and declare its intended use as “Providing a University Diploma.” The issuing process must comply with the requirements defined in the institution's or domain disclosure policy. This policy specifies the credential requirements and is the responsibility of the issuing organization, often influenced by regulatory or domain-specific standards. For instance, the education sector may define harmonized issuing requirements to standardize policies across institutions. This approach applies to other credentials as well, whether they are long-term and static (e.g., diplomas) or short-term and dynamic (e.g., credit scores). The ecosystem registration process facilitates collective oversight by ecosystem actors and regulators, leveraging transparency by design. Registered participants are subject to public monitoring and enforcement processes, ensuring swift and effective responses to violations. This collective approach strengthens trust within the ecosystem and promotes broader adoption by ensuring secure and reliable ecosystem interactions. The following examples illustrate how maximizing transparency effectively balances the flexibility required for ecosystem adoption with robust safeguards against misuse: - Ecosystem orchestrator website and organization web portal as single information and ecosystem access point: A centralized public frontend for various ecosystem user groups including citizens, organizations, and regulators streamlines access to information and interaction within the EUDI wallet ecosystem. The orchestrator plays a key role in connecting these user groups while hosting central components such as the orchestrator website that includes the organization web portal. This ensures that information remains easily accessible, consistent, and trustworthy. - Use-case restriction and user warnings: The EUDI Wallet only permits relying parties to offer use cases that are explicitly registered after receiving the access and registration certificate. If a mismatch occurs, users are proactively warned. However, users retain the ability to proceed based on their individual decisions, provided they make an active and informed choice. - Public transparency through the need of declared intended uses and an ecosystem dashboard: Registered relying parties (organizations) and their declared use cases are publicly listed on an ecosystem dashboard managed by the Ecosystem Orchestrator. This machine-readable data provides critical insights for regulators, civil society, and researchers, enabling the identification of misuse, linked to registered use cases. For instance, organizations seeking access to regulated PIDs must pay a fee, increasing the threshold for potential abuse. This fee is not only tied to the organization’s registration but also scaled to reflect the value the specific use case provides within the EUDI wallet ecosystem. This approach ensures that relying parties are both identified and financially accountable for their declared use cases. Additional details about the EUDI Wallet Ecosystem Management Portal concept are available on the EUDI Wallet project’s OpenCode [website](https://gitlab.opencode.de/bmi/eudi-wallet/eidas2/-/tree/main/07_Key_Concepts/01_Ecosystem_Management_Portal). On the website you can find expanded feature definitions, a high‑level roadmap, and visualizations to clarify the idea, including initial wireframes designed to enhance clarity and understanding. Please note: This information is subject to change. ## Ecosystem Access Fees: Enabling Public-Private Co-Financing and Sustaining the EUDI Wallet Infrastructure Operating Model The operating model of the ecosystem orchestrator should prioritize public oversight, efficient management, and adequate funding that after the establishment of the organization is based on revenues from the ecosystem. Emphasis should be placed on maintaining a streamlined and straightforward structure to minimize unnecessary costs on governance and compliance processes. This approach ensures that resources are directed toward the effective delivery and operation of the ecosystem, maximizing its value and impact. The core belief of the ecosystem operating model is that the initial provision of the EUDI Wallet infrastructure that leads to the emergence of the EUDI wallet ecosystem can only be financed by the federal government, with costs being recovered through refinancing during operation after a successful launch period. To encourage adoption, it is essential to waive the ecosystem access fee initially, as many organizations must invest in compliance with the EUDI wallet ecosystem. Once the launch is successful, the access fee can be gradually introduced to support the refinancing of the EUDI wallet infrastructure. Figure 4 summarizes high-level the operating model of the ecosystem orchestrator organization. ![EUDI Wallet Ecosystem Operating Model.](./figures/EGOM_Figure%204_Operating%20Model.png) *Figure 4: Operating Model of the EUDI Wallet Ecosystem* After the initial investment and orchestrator establishment, the EUDI Wallet Infrastructure and ecosystem components need to be provisioned and operated. Since the EUDI Wallet Ecosystem creates value for multiple organizations, they are either obliged by the eIDAS 2.0 regulation or might decide to join it voluntarily. To refinance, at least the operations of the EUDI wallet infrastructure organizations that interact with the EUDI wallet ecosystem must pay an access fee as part of the onboarding process. ### Access Fees Based on the Ecosystem Onboarding Process to Enable Co-Financing and Promote Broad Ecosystem Adoption The provision of the EUDI Wallet Ecosystem and the underlying digital public wallet infrastructure generates value for various public and private ecosystem actors. Given the significant investment needed for the initial provision, the sustainable operation, and further development, it is not only fair but also recommended to share the costs between the government and the ecosystem actors that utilize the value from the offering. Therefore, a co-financing mechanism needs to be implemented, and here the ecosystem onboarding process can be leveraged to enable a simple and digital payment of an ecosystem access fee. Following the ecosystem onboarding process, in the last step, payment details for billing must therefore be filled out. The ecosystem access fee structure is designed to balance co-financing responsibilities based on the generated value for an organization (relying party) while promoting ecosystem adoption. This approach aims to trigger network effects that attract additional interactions with the EUDI Wallet ecosystem, leveraging the foundational wallet infrastructure. The more organizations interact with the EUDI wallet ecosystem, the lower the costs for an individual organization to refinance the provision and operation of the EUDI wallet ecosystem. Therefore, adoption is essential for reducing costs and ensuring a sustainable operating model. **For designing the ecosystem access fee we aim to balance and fulfill the following requirements:** - The ecosystem access fee should be simple, transparent and stimulate adoption - The more value the EUDI wallet ecosystem provides for an organization, the higher should be the financial contribution - Economically larger organizations should contribute financially more, than non-profit or smaller organizations to increase adoption - The ecosystem access fee should incentivize the provision of EAAs in the ecosystem, as these provide the foundation for demand of other organizations **The ecosystem access fee could be theoretically determined through the following building blocks:** The organization type, determined by factors such as size, status, or regulatory obligations, can influence differentiated access fees. For example, variations may apply based on whether an organization is large or small, for-profit or non-profit, or subject to specific regulatory requirements. - Challenge: How to differentiate the organizational type fairly? The value of the EUDI wallet for an organization depends on its feature set and declared intended use. For example, variations may arise depending on whether an organization consumes attestations such as a PID, provides EAAs, or utilizes functionalities like pseudonym login or payment authorization. - Challenge: How to determine which EUDI wallet feature leads to which price tag? The consumption base can be measured by the number of credentials used within a specific time period and may be calculated based on the previous year's consumption. For example, organizations with higher consumption, based on their declared intended use, incur higher costs. A key prerequisite for this model is the ability to track transactions within the ecosystem, enabling accurate measurement of consumption, which serves as the basis for pricing. - Challenge: The prerequisite for measuring consumption is the tracking of transactions, which is subject to regulatory restrictions and has privacy implications. For instance, a credential provider should not be aware of where a user is using credentials from an EUDI wallet. Similarly, an EUDI wallet provider should not be aware of which relying party a user is interacting with when utilizing the EUDI wallet. - Challenge: A transaction-based charging model would require an EU-wide scheme, which is challenging to establish and would introduce additional complexity to the EUDI Wallet ecosystem. Based on the described building blocks the ecosystem access fee could be centered around the value of the EUDI wallet for an organization as the following model in Figure 6 proposes: ![Ecosystem Access Fee Modell.](./figures/EGOM_Figure%205_Access%20Fee.png) *Figure 5: Ecosystem Access Fee Model for Organizations* The fundamental assumption of the outlined model is that an organization has multiple applications that interact with the EUDI Wallet ecosystem. These can include one or more websites or mobile applications. Once these applications have been declared, the planned interaction with the EUDI Wallet must be specified for each one. Depending on the type of interaction, different costs apply. For example, a pseudonymous login is a function that provides organizations with less direct value but is crucial for user acceptance and engagement with the EUDI Wallet. Therefore, it may be offered free of charge. However, consuming attestations—such as requesting a PID, a school certificate, or proof of membership—incurs an annual flat usage fee. To simplify value determination, this is a flat fee and allows unlimited interaction with the EUDI Wallet ecosystem. The same model applies to the use of a Qualified Electronic Signature (QES) or payment authorization. The exact fee amounts still need to be determined, balancing the need to generate revenue with minimizing adoption barriers. Therefore, ecosystem access fees should only be applied once the EUDI Wallet ecosystem demonstrates adoption and delivers tangible value to the participating organizations ("nachgelagerte Finanzierung").The EUDI Wallet ecosystem benefits when a large number of attestations are available, which can be utilized by other ecosystem participants. Organizations can reduce their interaction costs with the EUDI Wallet ecosystem through a flat incentive credit by providing attestations. Depending on the use case, organizations can lower their costs to a maximum of zero by supplying attestations for which either they or another organization has declared an intended use. The annual access fee per organization is calculated by multiplying the number of declared applications by the number of declared EUDI wallet interactions, then subtracting the total flat incentives from the total flat fees. Illustrating Examples: Organization A operates both a web portal and a mobile application that interacts with the EUDI wallet ecosystem. The organization plans to enable for both applications a pseudonym login via the EUDI, obtain a PID credential, and issue an attestation. In this scenario: - The pseudonym login is free. - The organization pays a flat fee for consuming the PID attestation. - The organization receives a flat incentive for providing an attestation. In summary, the organization has three declared interactions with the EUDI Wallet, which determine the annual access fee until a change in the organization's declaration occurs (e.g., the organization requests an additional tax ID which leads to a higher fee). The fee may be regularly adjusted based on ecosystem KPIs, the detailed concept of which will be incorporated into the EUDI Wallet Ecosystem Blueprint at a later stage. Please note: The outlined process serves as an initial model for designing the operating model, and we welcome community feedback to refine and improve it. Its effectiveness will be maximized if many—or ideally all—EU member states adopt the model and mandate that ecosystem participants contribute an access fee, thereby minimizing the risk of regulatory arbitrage. To avoid negatively impacting adoption, it is essential that the access fee be introduced only after the successful launch and initial adoption of the EUDI ecosystem—once tangible value has been demonstrated for participating organizations and early investments have been recouped. ### Avoiding Micro-Transactions and Applying an Open Data Exchange Model Reduces Complexity and Fosters European Interoperability The described ecosystem access fee adopts a value-based pricing model, chosen based on the core assumption that organizations may take on multiple roles within the ecosystem, such as EAA providers or relying parties. This approach emphasizes the collective value generated through the ecosystem while operating under an open data exchange model that connects the roles of (P)EAA providers, Wallets, and relying parties. By streamlining processes and ensuring European interoperability, it eliminates the need for complex scenarios such as roaming between the member states ecosystems and micro-transactions between the mentioned roles. Furthermore, its lower complexity reduces bureaucracy and avoids privacy concerns, such as preventing issuers from knowing where a credential is used by a relying party via the EUDI Wallet. It also addresses standardization challenges, as adopting a non-open data exchange model would necessitate uniform requirements for all actors, adding significant complexity since every ecosystem actor would need to support these functionalities. Additionally, the likelihood of some Member States opting for a single, government-provided EUDI Wallet ecosystem further complicates the scalability of a micro-transaction-based data exchange model as in such a scenario the approach only adds complexity. The EUDI Wallet can be used in situations like showing credentials to a police officer during a control check. It also works for peer-to-peer cases, such as proving age to a security guard at a club or interacting with other individuals. In these situations, charging transaction fees would be impractical, highlighting the limitations of a micro-transaction-based approach. For the ecosystem to scale, a unified and user-centric approach is crucial, resulting in two key credential-issuing scenarios: either the issuer provides credentials for free, or the user pays through a service fee as part of a business relationship (e.g., paying for an eID from the government, issued either as a physical card or a digital credential). In the latter case, issuers can adjust service fees to recover the investments needed to comply with the ecosystem requirements. At the end, offering a credential is just another channel to offer a citizen or customer e.g. an attestation. Furthermore, wallet-to-wallet transactions are not subject to any fees. In the user-centric EUDI wallet ecosystem, scenarios where a relying party pays another EAA credential provider fall outside the ecosystem's scope. For example, when a credit score provider offers its service to banks, the value lies directly with the bank, creating a business relationship outside the EUDI Wallet ecosystem. The bank, as the beneficiary of the credit score service, has no incentive to support a scenario where a user, after obtaining the credit score payed by the bank, could use the same credential for other purposes—such as opening a depot with a competing bank. Offering such credentials directly into the EUDI Wallet based on a business relationship with a user could enable users to leverage credit scores in a privacy-preserving manner without disclosing sensitive information to relying parties. Mixing user and business contexts would require managing complex economic relationships across the ecosystem, adding compliance burdens and potentially diminishing its value proposition. Furthermore, directly linking issuers and relying parties introduces privacy and unlinkability risks. Therefore, it is advisable to distinguish between user-centric relationships within the EUDI wallet ecosystem and business relationships, where a beneficiary organization pays a fee to a service provider. In such cases, the EUDI wallet may be used to facilitate user-centric use cases for the beneficiary organization. This approach mirrors how business relationships are structured today, where the bank pays for access to the valuable information e.g. credit score information and the user needs to agree either through agreeing with the terms and conditions or through using an EUDI wallet. In conclusion, the EUDI Wallet ecosystem benefits from lower complexity, enhanced European interoperability, and greater scalability and adoption potential when adopting an open data exchange model. Potential (Q)EAA Providers have the option, within the framework of their business relationship with the user, to adjust existing service fees as needed to offset potential refinancing costs associated with the EUDI wallet ecosystem compliance. The open data exchange model means that no transactions are collected for payment processing across the EUDI wallet ecosystem. ## Level-Playing Field Regulation: The Foundation for User Choice and Fair Competition Among Ecosystem Actors The EUDI Wallet ecosystem comprises multiple actors that must be aligned and interconnected. A critical factor for creating value is scaling the acceptance network within the cooperative space to expand the ecosystem's reach. Establishing this acceptance network is essential for overcoming fragmentation, which often impedes user choice, fair competition, and scalability. For instance, EUDI wallet providers face challenges in sourcing credentials from diverse providers and ensuring that relying parties effectively utilize these credentials in various business use cases. This is crucial for creating value for users who hold the credentials and for convincing them that the EUDI Wallet provider’s offering delivers tangible benefits. Therefore, alongside the technical and organizational development of the EUDI Wallet acceptance network, a regulatory cornerstone is essential: an “Level-Playing Field.” This framework ensures non-discriminatory access for all ecosystem actors, including EAA providers, EUDI Wallet providers, and relying parties. This regulatory principle enhances the acceptance reach by ensuring that all ecosystem actors benefit from each other's individual activities, which align with collective interests of the cooperative space. It also lays the groundwork for fair competition within the ecosystem by preventing any dominant player—whether the government or a powerful non-government actor—from monopolizing the acceptance network. This safeguard ensures that the EUDI Wallet ecosystem, built on the digital public wallet infrastructure and its acceptance network, cannot be exploited for private value capture at the expense of competitors and users. Therefore, it ensures the collective public interest by preventing monopolization attempts that could arise from the “winner-takes-all” dynamics of the EUDI Wallet ecosystem. These dynamics are driven by the underlying network effects and are well-known from network infrastructures (e.g. telecommunication) and digital platform markets (e.g. mobile payments) As outlined in Section 4: Splitting Responsibilities for defining the boundaries of the “Level-Playing-Field” regulation a differentiation in the ecosystem operating model and individual business models of Ecosystem Technology Service Providers and Qualified Trust Service Providers is needed. The “Level-Playing-Field” regulation applies to the ecosystem operating model, while the business relationships of Ecosystem Technology Service Providers/Qualified Trust Service Providers and actors that participate in the EU wallet ecosystem are governed by market mechanisms and fall outside the scope of the EUDI Wallet ecosystem's governance. The business model for Ecosystem Technology Service Providers and Qualified Trust Service Providers focuses on delivering products and services that enable organizations to engage with and participate in the EUDI Wallet ecosystem. These providers are compensated for their offerings by the individual organizations with whom they have established business relationships. Figure 2 illustrates these interrelationships. ![Level-Playing-Field Regulation.](./figures/EGOM_Figure%206_Equal%20Level%20Playing%20Field.png) *Figure 6: Differentiation Between Level-Playing-Field Regulation and Market Mechanisms* **Illustrating Exemples of the "Level-Playing Field" regulation** Part of the “Level-Playing Field” regulation is that all EAA providers, EUDI wallet providers and relying parties need to register to get access to the ecosystem (more details in section 7: Ecosystem Access Fees). To demonstrate the concept of the "Level-Playing Field" three illustrative examples are described: A Bank is using a PID for a KYC to enable users to open a bank account: - In this case, the “Level-Playing-Field” regulation ensures that all EUDI wallet providers have equal acceptance network reach. A bank uses a PID (Personal Information Data) for KYC (Know Your Customer) purposes to enable users to open a bank account. In the context of the EUDI Wallet ecosystem, the bank interacts with all certified EUDI Wallet providers. From an integration and user experience perspective, a "Do it with my EUD Wallet" button will be available to seamlessly initiate the process. This ensures that users have the freedom to choose their preferred wallet provider, granting them ecosystem access through the acceptance network. Unlike the current reality where banks often select a specific identity service provider as their KYC partner, the EUDI Wallet ecosystem shifts this power dynamic. Here, users bring their chosen "EUDI Wallet provider" to the bank, reflecting the user-centric approach. The bank can rely on the EUDI Wallet certification and the accompanying ecosystem governance to ensure that all providers meet the necessary regulatory requirements for KYC compliance. According to the principles of the "Level-Playing-Field" regulation, banks are prohibited from exclusively partnering with specific EUDI Wallet providers. This also helps prevent scenarios where a bank that is also an EUDI wallet provider could favor its own offering and effectively “privatize” the public ecosystem. Therefore, this restriction is vital to maintaining fair competition among wallet providers and safeguarding user choice, fostering a balanced and open ecosystem. An EAA Provider is issuing an Airline ticket or an Education diploma to enable users to hold the credential in their EUDI wallet: - In this case, the “Level-Playing-Field” regulation ensures that users can hold and manage their credentials in their EUDI Wallet, regardless of the specific wallet provider they choose. EAA Providers, such as airlines or educational institutions, are required to interact with all certified EUDI Wallet providers. They are prohibited from selecting or favoring a preferred partner, as this decision lies solely with the user. This approach prevents ecosystem fragmentation and monopolization while guaranteeing interoperability, which is essential for fostering fair competition and preserving user choice. From the user’s perspective, the “Level-Playing Field” ensures that EAAs issued by any provider can be seamlessly utilized, enabling a consistent and user-friendly experience across the ecosystem. However, as outlined in Section 7: Ecosystem Access Fees, it is the responsibility of the EAA providers to establish their issuing policies and define their business conditions for providing an EAA. An EUDI Wallet Provider needs to accept all EAAs from all providers and serve all relying parties that are part of the EUDI wallet ecosystem: - In this case, the “Level-Playing-Field” regulation ensures that users can trust their EUDI wallet provider to service all EAA Providers and Relying Parties that are part of the EUDI wallet ecosystem and the underlying acceptance network. This ensures a seamless and inclusive experience for users, regardless of the source of their credentials or the relying party they wish to interact with. This obligation prevents exclusivity and favoritism, upholds user choice and fair competition, and ensures that all ecosystem actors operate on an level-playing field. However, based on eIDAS 2.0 regulation the EUDI wallet providers only get access to the PID of the Member State they are certified in. **Implementing the “Level-Playing-Field” Regulation and Implications for EUDI Wallet Provider Business Models** The “Level-Playing-Field” Regulation is a core principle of the EUDI wallet ecosystem and all ecosystem actors (public and private) and all ecosystem roles (Provider, EUDI wallet provider, Relying Party) are obliged to the requirement. **Implication for potential providers to offer the EUDI Wallets free of charge** The eIDAS 2.0 legislation mandates that EUDI wallets must be provided free of charge to natural persons. To ensure an level-playing field while promoting differentiation and competition among EUDI wallet providers, the regulatory-defined scope of the wallet plays a pivotal role (see Section 4: Splitting Responsibilities). This scope establishes the foundational features and interoperability requirements necessary to uphold the principles of the "Level-Playing Field" regulation. While the core scope of the EUDI wallet falls under the eIDAS 2.0 requirement for free access, providers are permitted to develop additional services and features beyond this core. These value-added offerings are not subject to the eIDAS regulation and its corresponding certification and may form the basis of chargeable services, enabling providers to establish sustainable business models. From the user’s perspective, wallet applications will include the regulated core features to ensure security and privacy but may also offer enhanced functionalities and services beyond the EUDI wallet scope, tailored to specific needs and use cases. More details and examples are described in Section 4: Splitting Responsibilities. **Implication for legal relationships between ecosystem roles** The outlined "Level-Playing-Field" regulation principles necessitate defining legal relationships between roles at the ecosystem level. This ensures that legal issues are not determined on a case-by-case basis between individual organizations and roles. Instead, the EUDI wallet ecosystem will operate under a harmonized legal framework, which requires further detailed definition. **Implication for potential EUDI wallet providers to provide Qualified Electronic Signatures (QES) for non-professional use free of charge** The eIDAS 2.0 legislation mandates that EUDI wallets must provide Qualified Electronic Signatures (QES) free of charge for non-professional use. This applies to an EUDI Wallet-centric QES scenario, where the management of qualified certificates is integrated into the EUDI Wallet.The regulatory responsibility for covering the costs will lie with the EUDI Wallet providers, who will have the flexibility to determine their implementation and partnership strategy. Differentiating between professional and non-professional usage presents a challenge and requires further clarification. **Implication for smartphone manufacturers to ensure fair competition with third party EUDI wallet providers** From the perspective of EUDI wallet providers, the "Level-Playing-Field" regulation must prioritize ensuring the visibility and accessibility of wallet options for potential users. Smartphone manufacturers, who can pre-install an (EUDI) wallet offering as part of their operating system, gain a significant competitive advantage, as these wallets are readily available during the initial device setup. To uphold the "Level-Playing-Field" principle, it is crucial to prohibit exclusive bundling practices that unfairly benefit smartphone manufacturers at the expense of third-party competitors. Users must have the freedom to select their preferred EUDI wallet provider, following a model similar to the browser choice approach in the European Union. Additionally, competing EUDI wallet providers must be granted access to critical smartphone infrastructure functions and user features utilized by the incumbent EUDI wallet (e.g. double tap on iPhones). Achieving this requires proactive action from national and European regulators to establish fair competition within the EUDI wallet ecosystem. Through industry dialogue and regulatory instruments, such as the Digital Markets Act, these measures must be achieved to ensure fair competition and lay the foundation for a balanced and open ecosystem where all EUDI wallet providers have fair opportunities to compete leading to choice for citizens. --- ## Standards Below is the list of the standards and specifications used in this blueprint: ## IETF Standards | Standard | Version | Description | |----------------------------------------------------------------|----------|-------------| | __[OAuth 2.0 Attestation-Based Client Authentication](https://www.ietf.org/archive/id/draft-ietf-oauth-attestation-based-client-auth-08.html)__ | draft 08 | This specification defines an extension to the OAuth 2 protocol as defined in [RFC6749] which enables a Client Instance to include a key-bound attestation in interactions with an Authorization Server or a Resource Server. This new method enables Client Instances involved in a client deployment that is traditionally viewed as a public client, to be able to utilize this key-bound attestation to authenticate. | | __[Selective Disclosure for JWTs (SD-JWT)](https://www.rfc-editor.org/rfc/rfc9901.html)__ | RFC 9901 | This specification defines a mechanism for the selective disclosure of individual elements of a JSON data structure used as the payload of a JSON Web Signature (JWS). The primary use case is the selective disclosure of JSON Web Token (JWT) claims. | | __[SD-JWT-based Verifiable Credentials (SD-JWT VC)](https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-15.html)__ | draft 15 | This specification describes data formats as well as validation and processing rules to express Verifiable Credentials with JSON payloads with and without selective disclosure based on the SD-JWT [I-D.ietf-oauth-selective-disclosure-jwt] format. | | __[Designated Verifier Signatures for JOSE](https://www.ietf.org/archive/id/draft-bastian-jose-dvs-02.html)__ | draft 02 | This specification defines designated verifier signatures for JOSE and defines algorithms that use a combination of key agreement and MACs. | --- ## OpenID Standards | Standard | Version | Description | |----------|-----| ----------- | | __[OpenID4VC High Assurance Interoperability Profile with SD-JWT VC](https://openid.net/specs/openid4vc-high-assurance-interoperability-profile-1_0-04.html)__ | 1.0-draft 04 | This document defines a profile of OpenID for Verifiable Credentials in combination with the credential formats IETF SD-JWT VC [I-D.ietf-oauth-sd-jwt-vc] and ISO mdoc [ISO.18013-5]. The aim is to select features and to define a set of requirements for the existing specifications to enable interoperability among Issuers, Wallets and Verifiers of Credentials where a high level of security and privacy is required. The profiled specifications include OpenID for Verifiable Credential Issuance [OIDF.OID4VCI], OpenID for Verifiable Presentations [OIDF.OID4VP], Self-Issued OpenID Provider v2 [OIDF.SIOPv2], IETF SD-JWT VC [I-D.ietf-oauth-sd-jwt-vc], and ISO mdoc [ISO.18013-5]. | | __[OpenId for Verifiable Credential Issuance](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html)__ | 1.0 | This specification defines an API for the issuance of Verifiable Credentials. | | __[OpenID for Verifiable Presentations](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html)__ | 1.0 | This specification defines a protocol for requesting and presenting Credentials. | --- ## ISO Standards | Standard | Version | Description | | ----------- |:--------| ------------------------------------ | |__[ISO/IEC 18013-5](https://www.iso.org/standard/69084.html)__| 2021 | This document establishes interface specifications for the implementation of a driving licence in association with a mobile device. This document specifies the interface between the mDL and mDL reader and the interface between the mDL reader and the issuing authority infrastructure. This document also enables parties other than the issuing authority (e.g. other issuing authorities, or mDL verifiers in other countries) to:— use a machine to obtain the mDL data;— tie the mDL to the mDL holder;— authenticate the origin of the mDL data;— verify the integrity of the mDL data.The following items are out of scope for this document:— how mDL holder consent to share data is obtained;- requirements on storage of mDL data and mDL private keys. | --- ## ETSI Standards | Standard | Verion | Description | |----------|--------|-------------| | __[ETSI TR 119 001](https://www.etsi.org/deliver/etsi_tr/119000_119099/119001/01.02.01_60/tr_119001v010201p.pdf)__ | 1.2.1 | The framework for standardization of signatures: Definitions and abbreviations | | __[ETSI TS 119 152-1](https://www.etsi.org/deliver/etsi_ts/119100_119199/11915201/01.01.01_60/ts_11915201v010101p.pdf)__ | 1.1.1 | Specifies a CBOR format for AdES signatures (CB-AdES) built on CBOR Object Signing and Encryption (COSE) as specified in IETF RFC 9052 | | __[ETSI TS 119 182-1](https://www.etsi.org/deliver/etsi_ts/119100_119199/11918201/01.02.01_60/ts_11918201v010201p.pdf)__ | 1.2.1 | Specifies JSON-based advanced electronic signature formats (JAdES) for interoperable and long-term validation | | __[ETSI TS 119 411-8](https://www.etsi.org/deliver/etsi_ts/119400_119499/11941108/01.01.01_60/ts_11941108v010101p.pdf)__ | 1.1.1 | Defines Access Certificate Policy for EUDI Wallet Relying Parties . | | __[ETSI TS 119 432](https://www.etsi.org/deliver/etsi_ts/119400_119499/119432/01.03.01_60/ts_119432v010301p.pdf)__ | 1.3.1 | Defines protocols for remote digital signature creation. | | __[ETSI TS 119 461](https://www.etsi.org/deliver/etsi_ts/119400_119499/119461/02.01.01_60/ts_119461v020101p.pdf)__ | 2.1.1 | Specifies policy and security requirements for trust service components providing identity proofing of trust service subjects | | __[ETSI TS 119 471](https://www.etsi.org/deliver/etsi_ts/119400_119499/119471/01.01.01_60/ts_119471v010101p.pdf)__ | 1.1.1 | Defines Policy and Security requirements for Providers of Electronic Attestation of Attributes Services | | __[ETSI TS 119 472-1](https://www.etsi.org/deliver/etsi_ts/119400_119499/11947201/01.02.01_60/ts_11947201v010201p.pdf)__ | 1.2.1 | Specifies the general requirements and data models for Electronic Attestations of Attributes (EAA) | | __[ETSI TS 119 472-2](https://www.etsi.org/deliver/etsi_ts/119400_119499/11947202/01.02.01_60/ts_11947202v010201p.pdf)__ | 1.2.1 | Specifies profiles for EAA/PID presentations to relying parties | | __[ETSI TS 119 472-3](https://www.etsi.org/deliver/etsi_ts/119400_119499/11947203/01.01.01_60/ts_11947203v010101p.pdf)__ | 1.1.1 | Specifies profiles for issuance of EAA or PID | | __[ETSI TS 119 475](https://www.etsi.org/deliver/etsi_ts/119400_119499/119475/01.02.01_60/ts_119475v010201p.pdf)__ | 1.2.1 | Structure of registration certificates with rulebook references | | __[ETSI TS 119 478](https://www.etsi.org/deliver/etsi_ts/119400_119499/119478/01.01.01_60/ts_119478v010101p.pdf)__ | 1.1.1 | Specification of interfaces related to Authentic Sources | | __[ETSI TS 119 602](https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf)__ | 1.1.1 | Specifies the Lists of Trusted Entities (LoTE) data model | | __[ETSI TS 119 612](https://www.etsi.org/deliver/etsi_ts/119600_119699/119612/02.04.01_60/ts_119612v020401p.pdf)__ | 2.4.1 | Specifies the technical specifications for Trusted Lists | | __[ETSI EN 319 102-1](https://www.etsi.org/deliver/etsi_en/319100_319199/31910201/01.04.01_60/en_31910201v010401p.pdf)__ | 1.4.1 | Procedures for Creation and Validation of AdES Digital Signatures | | __[ETSI EN 319 122-1](https://www.etsi.org/deliver/etsi_en/319100_319199/31912201/01.03.01_60/en_31912201v010301p.pdf)__ | 1.3.1 | Specifies the CAdES (CMS Advanced Electronic Signatures) format, defining the technical requirements for advanced electronic signatures based on the Cryptographic Message Syntax (CMS) for binary data and documents | | __[ETSI EN 319 132-1](https://www.etsi.org/deliver/etsi_en/319100_319199/31913201/01.03.01_60/en_31913201v010301p.pdf)__ | 1.3.1 | Specifies the XML Advanced Electronic Signatures (XAdES) format, defining the baseline requirements for creating and validating structured digital signatures within XML documents | | __[ETSI EN 319 162](https://www.etsi.org/deliver/etsi_en/319100_319199/31916201/01.01.01_60/en_31916201v010101p.pdf)__ | 1.1.1 | Specifies the building blocks and the baseline containers of the Associated Signature Containers (ASiC) | --- ## CSC Technical Specifications | Technical Specification | Version | Description | |-------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------| | __[CSC API](https://cloudsignatureconsortium.org/wp-content/uploads/2025/11/csc-api.pdf)__ | 2.2.0.0 | Provides a standardized interface for interoperable, cloud-based digital signatures and remote signing. | | __[CSC Data Model](https://cloudsignatureconsortium.org/wp-content/uploads/2025/10/csc-dm.pdf)__ | 1.0.0 | Defines data models for (a) Requesting a signature, (b) Requesting a signing operation, (c) Authorization of a signing operation | | __[CSC Data Model Bindings](https://cloudsignatureconsortium.org/wp-content/uploads/2025/10/data-model-bindings.pdf)__ | 1.0.0 | Describes bindings of the CSC data model for use cases that are out of scope for CSC but may be used in relation with the CSC API. | --- ## CEN Standards | Standard | Version | Description | |----------|:--------|-------------| | __[CEN EN 419 241-1](https://standards.cencenelec.eu/ords/f?p=CEN:110:::::FSP_PROJECT:61293&cs=197619E59B18776EC4C4865E1AB7A0037)__ | 2108 | Specifies security requirements and recommendations for Trustworthy Systems Supporting Server Signing (TW4S) that generate digital signatures. | --- ## Further Standards - The most important cryptographic standards can be found [__here__](../ecosystem-concepts/crosscutting-concepts/security-requirements.md#cryptographic-algorithms). - An overview of all standards and specifications can be found in the [__ARF__](https://github.com/orgs/eu-digital-identity-wallet/projects/29/views/2). --- ## Ecosystem Vision & Fundamentals(Ecosystem-vision-and-fundamentals) ## EUDI Wallet Ecosystem Overview The EUDI Wallet ecosystem comprises a set of clearly defined roles and systems that together enable the secure issuance, management, and use of digital credentials data across Europe. These roles interact to deliver value to users, relying parties, and public administrations, while ensuring trust, legal certainty, and fundamental rights protection. While the ecosystem is inherently complex, not all interacting entities are part of the operational EUDI Wallet ecosystem itself. Some actors act as authoritative sources, governance bodies, or supervisory entities that enable or oversee the ecosystem without participating in credential transactions. Figure 1 provides an overview of the EUDI Wallet ecosystem roles and their interactions. Stacked boxes indicate that multiple instances of a role may exist. ![EUDI Wallet Ecosystem Overview.](./figures/Introduction_Figure%201_Ecosystem%20Overview.excalidraw.svg) *Figure 1: EUDI Wallet Ecosystem Roles and Components* !!! Scope Note This chapter focuses exclusively on defining the roles within the EUDI Wallet ecosystem and their responsibilities. Trust relationships, certification mechanisms, and interaction flows between roles are defined in dedicated chapters and are intentionally not depicted here. The following sections first describe the **individual roles** of the ecosystem. These roles are subsequently grouped into **functional categories** to provide a clearer understanding of responsibilities, governance, and oversight. --- ## Core Operational Roles This section describes the roles that directly participate in credential issuance, storage, presentation, and verification. ### PID Provider A PID Provider is a trusted entity responsible for: * verifying the identity of the user in compliance with Level of Assurance (LoA) high requirements, * issuing a Person Identification Data (PID) credential to the EUDI Wallet, and * making available, in a privacy-preserving manner, information that allows Relying Parties to verify the validity of the PID. The PID Provider ensures that person identification data—such as name and date of birth—is securely generated, validated, and made available to the wallet. The PID Provider forms part of the core infrastructure of the German EUDI Wallet ecosystem. The current ecosystem vision foresees a single PID Provider, while allowing for future evaluation of additional issuance methods that meet the defined functional and security requirements. --- ### (Q-, Pub-) EAA Provider An (Qualified, Public or domain driven) Electronic Attestation of Attributes (EAA) Provider is an entity responsible for issuing Electronic Attestations of Attributes at the user’s request. EAAs allow users to prove specific attributes in a secure, standardized, and legally recognized way. * **Qualified EAA (QEAA) Providers** meet the highest eIDAS 2.0 trust and security requirements and issue legally binding attestations recognized across borders. * **Public EAA (Pub-EAA) Providers** are trusted public entities issuing legally recognized, but non-qualified, attestations. * **EAA Providers** are trustworthy parties in the EUDI Wallet Ecosystem and providing digital attestations in their specific domain. EAA Providers may originate from various domains such as mobility, telecommunications, education, or healthcare. They are typically supervised by competent authorities within their respective domains. The EUDI Wallet ecosystem envisions multiple EAA Providers as well as QEAA- and Pub-EAA Providers. --- ### QES Provider / Qualified Trust Service Provider (QTSP) Qualified Electronic Signatures (QES) provide legally binding signatures for digital documents. QES are regulated by the eIDAS framework and recognized by all EU member states. They have the equivalent legal effect of a handwritten signature. QES are technically based on digital signatures using certificates. EUDI Wallet Providers must offer users free Qualified Electronic Signatures (QES) for **non-professional use** within a wallet-centric QES approach. To fulfil this requirement, Wallet Providers may collaborate with Qualified Trust Service Providers (QTSPs). A QTSP is a trust service provider that has received qualified status from a supervisory body in an EU Member State, allowing it to provide qualified trust services with legal effects equivalent to handwritten signatures across the EU. Beside free of charge QES there will be as well the option to use QES Services for any usecase. The EUDI Wallet ecosystem interacts with multiple QES Providers / QTSPs listed in the specific EU Trust Lists. --- ### EUDI Wallet Provider An EUDI Wallet Provider develops and operates wallet solutions that store, manage, and present credentials on behalf of users. Wallet Providers ensure the secure handling of sensitive cryptographic material (e.g. private keys) and guarantee that users retain sole control over their PID, EAAs, and other personal data. Wallet Providers deliver **certified** interfaces that enable secure data management, selective disclosure, pseudonymous authentication, payment authorizations, and qualified electronic signatures. The ecosystem vision foresees multiple EUDI Wallet Providers to foster competition and user choice. --- ### Relying Parties A Relying Party (RP) is an entity—public or private—that interacts with EUDI Wallets to verify identity data or attributes for authentication, authorization, or service access. Both public and private Relying Parties must register and declare their intended use of EUDI Wallet data to ensure compliance with eIDAS 2.0 and ecosystem rules. The ecosystem envisions multiple public, civic, and private Relying Parties. --- ## Governance & Trust Infrastructure Roles This section describes roles responsible for defining rules, onboarding participants, and establishing trust relationships. ### EUDI Wallet Ecosystem Orchestrator The EUDI Wallet Ecosystem Orchestrator is an operational coordination role responsible for enabling, structuring, and supporting the development and operation of the EUDI Wallet ecosystem. The orchestrator does not introduce new regulatory powers beyond those defined in eIDAS 2.0. Instead, it performs and coordinates ecosystem functions on the basis of mandates from competent authorities or Rule-Setters. These functions may include operating the WRP Registrar, facilitating onboarding processes, providing testing and sandbox environments, coordinating stakeholder engagement, and ensuring transparency of ecosystem activities. The orchestrator exists to bridge the gap between regulatory requirements and practical ecosystem operation and may be implemented by a public entity, a delegated body, or a consortium acting under public mandate. !!! Note eIDAS defines required roles and responsibilities but does not prescribe how Member States operationally organize ecosystem coordination. The Ecosystem Orchestrator role reflects a national implementation choice to ensure coherent onboarding, testing, and ecosystem growth without extending regulatory authority. --- ### Wallet Relying Party Registrar (WRP Registrar) The WRP Registrar is a governance function required by the EUDI Wallet ecosystem and may be operated by the Ecosystem Orchestrator or by a separate mandated entity, depending on national implementation. The Relying Party Registrar (WRP Registrar) is responsible for the registration, validation, and administration of Relying Parties and EAA Providers interacting with EUDI Wallets. It ensures that participants declare their intended uses, comply with eIDAS 2.0 requirements, and operate transparently to maintain trust and security. The EUDI Wallet ecosystem envisions a single WRP Registrar. --- ### EUDI Wallet Conformity Assessment Bodies EUDI Wallet Conformity Assessment Bodies are independent entities responsible for evaluating whether EUDI Wallets comply with the applicable security, interoperability, and regulatory requirements under eIDAS 2.0. They perform assessments and audits as part of the EUDI Wallet certification process. Initially, certification is based on national schemes and later transitions to a harmonized European certification scheme. These bodies ensure that Wallet Providers meet all required standards before being authorized for operation. --- ## Oversight & Public Control Roles This section describes entities that provide independent, ex-post oversight of the ecosystem. ### (State) Data Protection Supervisory Authorities *(outside ecosystem)* Federal and State Data Protection Supervisory Authorities supervise compliance with data protection regulations within the EUDI Wallet ecosystem. They investigate complaints, enforce corrective measures, and protect the rights of wallet users. Multiple supervisory authorities interact with the ecosystem. --- ### Consumer Protection Organizations and the Public *(outside ecosystem)* Consumer protection organizations and the general public may access information on declared Relying Party uses registered with the WRP Registrar. This information is published in machine-readable formats to ensure transparency and enable public scrutiny. --- ## External Systems & Sources ### Authentic Sources *(outside ecosystem)* Authentic Sources are public or private systems recognized or required by law that contain authoritative attributes about natural or legal persons. Examples include civil registries, education databases, licensing authorities, or company registers. Authentic Sources provide the factual basis for attribute issuance but are outside the scope of the German EUDI Wallet ecosystem. --- ### German eID Card Infrastructure *(outside ecosystem)* The German eID Card (nPA) serves as the primary source for PID issuance. It includes the eID for German citizens, the Unionsbürgerkarte for EU citizens, and the electronic residence permit for non-EU citizens. The technical architecture is specified in BSI Technical Guideline TR-03127. --- ## Ecosystem Vision & Fundamentals(3) ## What is the Wallet? The EUDI Wallet is your personal digital wallet for identity data and credentials. It works according to a simple principle: all credentials are securely stored directly on your own smartphone and are only shared by you when needed. You remain in full control at all times, as only the absolutely necessary information is disclosed. There is no central storage of your personal data — everything stays in your hands. The wallet serves as a modern complement to your existing physical documents and will be usable across Europe in the future. ### The German National EUDI Wallet The German National EUDI Wallet is **one example** for an EUDI Wallet. It's the state wallet, free of charge. For more information visit the [EUDI Wallet DE Website](https://eudi-wallet.gov.de/en) The technical implementation is described in the following document: [**Architecture Documentation of the German National EUDI Wallet**](https://bmi.usercontent.opencode.de/eudi-wallet/wallet-development-documentation-public). More, not state driven wallets will be available in the future. ### Trustworthy wallets All German EUDI Wallets have to fulfil: * eIDAS regulation * the certification defined by BSI (Bundesamt für Sicherheit in der Informationstechnik). * the trust model for as desribed in the [chapter trust](../../ecosystem-concepts/trust/) --- ## EAA Issuance with OpenID4VCI ## Basic Idea The EAA Provider issues signed credentials to the Wallet which are stored for a longer period. The Wallet can then present the credentials (including a proof of possession by signing over a wallet-held key) to the Relying Party. The flows include examples for the credential formats SD-JWT VC and mdoc, but other formats are not precluded. !!! note "Exemplary Flows" The flows described in this document are **examples** demonstrating one possible implementation approach. Applicable industry standards for their implementation are: [TS 119 472-1](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards): General requirements for electronic attestations of attributes. [TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards): Issuance requirements and signature formats. !!! note "Terminology" In the context of eIDAS, the following terminology applies: * Wallet Instance Attestation (WIA), corresponding to Wallet Attestation (WA) in OID4VC terminology. * Key Attestation (KA). Unless explicitly stated otherwise, this document uses the eIDAS terminology throughout the following flows. * Wallett Instance Attestion (WIA) and Key Attetation (KA) are different types of the Wallet Unit Attestation (WUA). TS3 provides more details. !!! note "Profile" The issuance of an Electronic Attestation of Attributes (EAA) is governed by the [ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) specification. This standard mandates the use of the OID4VC High Assurance Interoperability Profile (OID4VC-HAIP) as the underlying protocol profile. ## Cryptographic Formats Long-Term keys: - EAA Provider has long-term key pair $(ep\_pub, ep\_priv)$ which is used to sign the credential - EUDI Wallet generates device key $(device\_pub, device\_priv)$ which is used to generate proof of possession of a credential Transaction-specific keys: - EUDI Wallet generates key pair $(cre\_eph\_pub, cre\_eph\_priv)$ which is used to encrypt the credential response Artifacts: - EUDI Wallet fetches a Wallet Instance Attestation (WIA) from Wallet Provider: $wallet\_instance\_attestation$ - EUDI Wallet fetches a Key Attestation (KA) from Wallet Provider: $key\_attestation$ - Credential format specific payload signed by the issuer: $hashed\_attestation\_data$ - EAA Provider issues - **SD-JWT VC (plus Disclosures)**: $sd\_jwt := \text{sign}(\mathit{hashed\_attestation\_data}, device\_pub)_{ep\_priv}$ - **ISO mdoc**: $mdoc := \text{sign}(\mathit{hashed\_attestation\_data}, device\_pub)_{ep\_priv}$ ## Remote Issuance with Authorization Code Flow ### Sequence Diagram [User Journey: EAA Issuance - Authorization Code](../../../user_journeys/QEAA-AuthorizationCode-issuance.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title EAA Issuance over OpenID4VCI with Authorization Code Flow actor u as "User\nOpenID Holder" participant w [ EUDI Wallet Instance ---- ""Long-term Key: (//device_pub//, //device_priv//)"" ""Short-term Key: (//cre_eph_pub//, //cre_eph_priv//)"" ] participant b as "Browser App\n(same device)" participant i [ EAA Provider ---- ""Long-term Key: (//ep_pub//, //ep_priv//)"" ] alt Wallet initiated u --> w : open wallet, unlock wallet hnote over w #dfd: Screen: launch_wallet hnote over w #dfd: Screen: unlock_wallet u --> w : Select issuance of pre-configured EAA note right: Pre-configured EAAs contains credential_issuer URLs and scopes hnote over w #dfd: Screen: credential_catalog hnote over w #dfd: Screen: next_steps else Issuer initiated u -> b : Open Issuer's Website b -> i : Query website: HTTP GET / i -> b : HTTP 200\nHTML with static Credential Offer\n hnote over w #dfd: Screen: same_device_issuer_website u --> w : open wallet, unlock wallet hnote over w #dfd: Screen: launch_wallet hnote over w #dfd: Screen: unlock_wallet hnote over w #dfd: Screen: next_steps end w -> i : tls() HTTP GET ./well-known Credential Issuer Metadata i -> w : tls() HTTP 200 w -> w : Verify Signed Credential Issuer Metadata u --> w : provide consent for EAA Provider and offered attestation hnote over w #dfd: Screen: consent_provider_and_attestation group Wallet Instance Attestation w -> i : tls() HTTP POST nonce for //wallet_instance_attestation// i -> i : generate and store nonce i -> w : tls() HTTP 200 w -> w : get //wallet_instance_attestation// from Wallet Provider backend (nonce for //wallet_instance_attestation// ) w -> w : generate PoP for //wallet_instance_attestation// end w -> i : tls() PAR (code_challenge, //wallet_instance_attestation// + PoP, redirect_uri, either scope or authorization_details) i -> i : verify //wallet_instance_attestation//\ncheck wallet solution status on trust list i -> w : tls() request_uri w -> b : tls() HTTP GET b -> i : tls() HTTP GET group User Authentication b <-> i : note over i,b : the EAA Provider may perform any form of user authentication in the browser, this may be:\n- username/password\n- OpenID4VP credential presentation of PID, other EAA, etc...\n- taking a foto\n- any other mechanism enabled through the browser hnote over b #dfd: Screen: same_device_issuer_authentication end i -> b : tls() HTTP 302 redirect-uri b -> w: tls() HTTP 302 redirect-uri u --> w : user consent for receiving the EAA hnote over w #dfd: Screen: consent_add_credential w -> i : tls() HTTP POST i -> i : verify //wallet_instance_attestation// i -> i : lookup authorization code\ngenerate TokenResponse with DPoP access token\nverify PKCE challenge i -> w : tls() HTTP 200 group [optional] key binding type alt proof type //jwt// w -> w : generate cryptographic binding key pair(s) (//device_pub//, //device_priv//) and proof of possession with //c_nonce// including optional //key_attestation// note right: send proof of possession with optional key attestation else proof type //attestation// w -> w : generate //key_attestation// using the provided key pair(s) note right: send key attestation without using a proof of possession end hnote over i: Whether batch issuance is supported depends on the proof information specified in the issuer's metadata. If necessary, n key pairs are generated, followed by the creation of a key attestation covering all n key pairs.. hnote over w : Device key should be protected by platform security mechanism. oid4vci defines different proof types a.o. //jwt// and //attestation// end hnote over w #dfd: Screen: device_authenticator group credential response encryption w -> w : generate credential response encryption key pair (//cre_eph_pub//, //cre_eph_priv//) w -> w : create credential_response_encryption object with jwk containing //cre_eph_pub// end alt proof type //jwt// w -> i : tls() HTTP POST else proof type //attestation// w -> i : tls() HTTP POST end i -> i : lookup access token\n validate key proof alt #dfd SD-JWT VC EAA i -> i : generate SD-JWT VC EAA and Disclosures with attestation data and //device_pub// as cnf key, sign with //ep_priv// else #ddf mdoc EAA i -> i : generate mdoc EAA with attestation data and //device_pub// as deviceKey, sign with //ep_priv// end alt credential_response_encryption present i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i -> w : tls() HTTP 200 w -> w : decrypt credential response JWT and retrieve credential else #fff not present i -> w : tls() HTTP 200 end w -> w : store EAA hnote over w #dfd: Screen: success hnote over w #dfd: Screen: home note over w : it might be useful to have a redirect in the browser @enduml ``` ### Step-by-Step Description | No | Description | |-----|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 001 | **(Wallet initiated)** The user opens and unlocks their wallet. | | 002 | **(Wallet initiated)** The user navigates to a credential catalog of pre-configured EAA Providers and is offered credentials in the Wallet. They selects an EAA and the Wallet continues the flow with the pre-configured Credential Issuer URL and credential identifier. | | 003 | **(Issuer initiated)** User browses to the EAA Provider's website. | | 004 | **(Issuer initiated)** Browser app on the user's device opens the EAA Provider's website | | 005 | **(Issuer initiated)** EAA Provider returns an HTML page to the browser containing a Credential Offer with the following payload: - the Credential Issuer URL - an identifier to the offered credential- an optional `issuer_state parameter to bind this issuance to a pre-existing session | | 006 | **(Issuer initiated)** The user clicks on the link, the Wallet launches, and they unlock the wallet | | 007 | The Wallet fetches the Credential Issuer's metadata from the `./well-known` files of the Credential Issuer URL | | 008 | The EAA Provider (from here on named Issuer in his OpenID4VCI role) returns the Credential Issuer Metadata; containing:- technical information about the Issuer- translations and display data for the offered credentials | | 009 | The Wallet verifies the signed metadata provided by the Credential Issuer by checking the signature (should be signed with valid access certificate) & existence and validity of the embedded Relying Party Registration Certificate as defined in [ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | | 010 | The Wallet displays information about the EAA Provider and the offered EAA to the user and asks for consent | | 011 | The Wallet requests a fresh `nonce` for the `wallet instance attestation` | | 012 | The Issuer generates a fresh `nonce` linked to the issuance session | | 013 | The Issuer returns the `wallet instance attestation`´nonce` to the Wallet | | 014 | The Wallet fetches a fresh `wallet instance attestation from the Wallet Provider backend (could also happen in advance) | | 015 | The Wallet generates a `proof of possession (PoP)` for `wallet instance attestation` using the `nonce` fetched in the previous step | | 016 | The Wallet sends a `Pushed Authorization Request` (PAR) to the Issuer; containing:- the Wallet Provider's `client_id`- a `PKCE code_challenge`- the `wallet instance attestation` and associated `proof of possession`- a `redirect_uri` containing an app-link- either `scope` or an `authorization_details` parameter requesting the EAA | | 017 | The Issuer verifies the `wallet instance attestation` and validates the status of the Wallet solution through a trust list | | 018 | The Issuer stores the Authorization Request, generates a `request_uri` and sends it back to the Wallet | | 019 | The Wallet uses the `request_uri` to create an Authorization Request and send this to the Authorization endpoint of the Issuer by issuing a HTTP GET request over the system's default browser. | | 020 | The Browser sends the Authorization Request to the Issuer | | 021 | In this authentication phase, the Issuer may exchange any information over the browser to the user, as he got the "screen control". This may be, but is not limited to:- username / password- OpenID4VP credential presentation of PID, other EAA, etc..- taking a photo - any other mechanism enabled through the browser | | 022 | The Issuer finalizes the authentication phase by responding with an Authorization Response containing:- the auth code- the redirect provided by the wallet in the PAR | | 023 | The browser follows the redirect, re-launching the wallet | | 024 | The wallet provides information about the offered EAA and asks the user for consent | | 025 | The Wallet sends a Token Request to the EAA Provider containing:- the `auth code` from Authorization Response- the `PKCE code_verifier` matching the `code_challenge` from Authorization Request- the `wallet instance attestation` and `Proof of possession`- a `DPoP` proof JWT establishing possession of the client key | | 026 | The Issuer verifies the `wallet instance attestation` and `proof of possession` | | 027 | The Issuer matches the code, verifies the `PKCE code_verifier` to the previously received `code_challenge` and verifies the `wallet instance attestation`. It then generates an `access token` bound to the `DPoP key`. | | 028 | The Issuer sends a Token Response; containing- `DPoP-bound access token`- a `c_nonce`- an `authorization_details` object, if the `authorization_details` parameter was used in the Authorization Request instead of a `scope` | | 029 | **(Proof type : jwt)** The Wallet generates a key pair for the cryptographic binding of the EAA (`device_pub`, `device_priv`) and signs the `c_nonce`. A `jwt` is used for proof of possesion containing optional a `key attestation`. | | 030 | **(Proof type: attestation)** The Wallet generates a `jwt` reperesenting a `key attestion` without using a proof of possession of the cryptographic key material that is being attested. | | 031 | The Wallet may request an encrypted credential response. In order to do so, it generates a new ephemeral keypair (_cre_eph_pub_, _cre_eph_priv_). | | 032 | The Wallet creates the `credential_response_encryption` JSON object containing the following information:- a `jwk` containing the `cre_eph_pub`- the JWE alg parameter- the JWE enc parameter | | 033 | **(Proof type : jwt)** The Wallet sends the Credential Request to the Issuer; containing- the DPoP-bound access token- the credential information either through `credential_identifier` or `credential_configuration_ids` - the proof of cryptographic binding key _device_pub_ signed c_nonce- and the `credential_response_encryption` object | | 034 | **(Proof type: attestation)** The Wallet sends the Credential Request to the Issuer; containing- the DPoP-bound access token- the credential information either through `credential_identifier` or `credential_configuration_ids` - the proof of cryptographic binding key _device_pub_ signed c_nonce- and the `credential_response_encryption` object | | 035 | The Issuer validates the access_token and the proof (signed over the c_nonce) | | 036 | **(SD-JWT VC EAA)** The Issuer creates the Disclosures from attestation data and signs the SD-JWT VC with _ep_priv_ containing- attestation data and hashed Disclosures as the user claims- _device_pub_ as cnf claim He then appends the Disclosures. | | 037 | **(mdoc EAA)** The Issuer creates the hashed Releases from attestation data and signs the mdoc with _ep_priv_ containing- attestation data and hashed Releases as issuerAuth- _device_pub_ as deviceKeyInfo | | 038 | In case `credential_response_encryption` information is present, the Issuer creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the EAA credential to the payload. | | 039 | The Issuer sends the Credential Response JWT; containing:- The EAA as credential | | 040 | The Wallet decrypts the Credential Response JWT using the _cre_eph_priv_ and retrieves the credential. | | 041 | In case `credential_response_encryption` information are not present, the Issuer sends the plain Credential Response; containing:- The EAA as credential. | | 042 | The Wallet stores the EAA and the associated keys. | ## Remote Issuance Pre-Authorized Code Flow ### Sequence Diagram [User Journey: EAA Issuance - Pre-Authorized Code](../../../user_journeys/QEAA-PreauthorizedCode-issuance.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title EAA Issuance over OpenID4VCI with Pre-Authorized Code Flow actor u as "User\nOpenID Holder" participant w as "User's EUDI Wallet Instance" participant b as "Browser App" participant i [ EAA Provider ---- ""Long-term Key: (//ep_pub//, //ep_priv//)"" ] u -> b : Open Issuer's Website group User Authentication note over i,b : the EAA Provider may perform any form of user authentication prior to creating the credential offer end b -> i : Query website: HTTP GET / i -> b : HTTP 200\nHTML with dynamic Credential Offer\n alt Issuer initiated - Same Device hnote over w #dfd: Screen: same_device_issuer_website u --> w : open wallet, unlock wallet hnote over w #dfd: Screen: launch_wallet hnote over w #dfd: Screen: unlock_wallet else Issuer initiated - Cross Device hnote over w #dfd: Screen: cross_device_issuer_website u --> w : scan QR-Code hnote over w #dfd: Screen: launch_wallet hnote over w #dfd: Screen: unlock_wallet hnote over w #dfd: Screen: device_camera end w -> i : tls() HTTP GET ./well-known Credential Issuer Metadata i -> w : tls() HTTP 200 w -> w : Verify Signed Credential Issuer Metadata u --> w : provide consent for EAA Provider and offered attestation hnote over w #dfd: Screen: consent_provider_and_attestation group Wallet Instance Attestation w -> i : tls() HTTP POST nonce for //wallet_instance_attestation// i -> i : generate and store nonce i -> w : tls() HTTP 200 note over w : nonce may be provided in credential offer or reuse pre-auth code w -> w : perform and get //wallet_instance_attestation// from Wallet Provider backend (nonce for //wallet_instance_attestation//) w -> w : generate PoP for //wallet_instance_attestation// end w -> i : tls() HTTP POST group Wallet Instance Attestation i -> i : verify //wallet_instance_attestation//\ncheck wallet solution status on trust list end i -> i : lookup authorization code\ngenerate TokenResponse with DPoP access token i -> w : tls() HTTP 200 w -> w : generate cryptographic binding key pair (//device_pub//, //device_priv//) and proof of possession with c_nonce note right: Device key should be protected by platform security mechanisms hnote over w #dfd: Screen: device_authenticator alt #ffd optional credential response encryption w -> w : generate credential response encryption key pair (//cre_eph_pub//, //cre_eph_priv//) w -> w : create credential_response_encryption object with jwk containing //cre_eph_pub// end w -> i : tls() HTTP POST i -> i : lookup access token\n validate key proof alt #dfd SD-JWT VC EAA i -> i : generate SD-JWT VC EAA and Disclosures with attestation data and //device_pub// as cnf key, sign with //ep_priv// else #ddf mdoc EAA i -> i : generate mdoc EAA with attestation data and //device_pub// as deviceKey, sign with //ep_priv// end alt credential_response_encryption present i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i -> w : tls() HTTP 200 w -> w : decrypt credential response JWT and retrieve credential else #fff not present i -> w : tls() HTTP 200 end w -> w : store EAA hnote over w #dfd: Screen: success hnote over w #dfd: Screen: home note over w : it might be useful to have a redirect in the browser for same-device flow @enduml ``` ### Step-by-Step Description | No | Description | | --- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 001 | The user browses to EAA Provider's website. At this point it is assumed that the user authentication already took place before the OpenID4VCI protocols starts. This may happen through any mechanism, e.g. username/password, providing OTPs, etc.. | | 002 | Browser app on the user's device opens the EAA Provider's website | | 003 | EAA Provider returns a HTML page to the browser containing a Credential Offer with the following payload: - the Credential Issuer URL- an identifier to the offered credential- a pre-Authorized Code for authorization, linked to the identified user- the flag `tx_code` indicating whether the Wallet is expected to provide a Transaction Code in the Token Request. The Transaction Code is sent by the Issuer over a second channel, e.g., via e-mail or SMS, and helps to strengthen security by additional session binding. | | 004 | **(Same-Device)** The user clicks on the link, the Wallet launches and he unlocks the wallet | | 005 | **(Cross-Device)** The user opens and unlocks his wallet and scans the QR-Code | | 006 | The Wallet fetches the Credential Issuer's metadata from the ./well-known files of the Credential Issuer URL | | 007 | The EAA Provider (from here on named Issuer in his OpenID4VCI role) returns the Credential Issuer Metadata; containing:- technical information about the Issuer- translations and display data for the offered credentials | | 008 | The Wallet verifies the signed metadata provided by the Credential Issuer by checking the signature (should be signed with valid access certificate) & existence and validity of the embedded Relying Party Registration Certificate as defined in [ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) | | 009 | The Wallet shows information about the EAA Provider and the offered EAA to the user and asks for consent | | 010 | The Wallet requests a fresh $nonce$ for the $wallet\_instance\_attestation$ | | 011 | The Issuer generates a fresh $nonce$ linked to the issuance session | | 012 | The Issuer returns the $nonce$ for the $wallet\_instance\_attestation$ to the Wallet | | 013 | The Wallet fetches fresh $wallet\_instance\_attestation$ from the Wallet Provider backend | | 014 | The Wallet generates proof of possession $PoP$ for $wallet\_instance\_attestation$ using the $nonce$ fetched in the previous step | | 015 | The Wallet sends a Token Request to the EAA Provider; containing:- the pre-authorized code from Authorization Response- the $wallet\_instance\_attestation$ and Proof of possession $PoP$- a $DPoP$ proof JWT establishing possession of the client key - the Transaction Code that the user received over a second communication channel from the Issuer, if $\\tx\_code$ was present in the Credential Offer | | 016 | The Issuer verifies the $wallet\_instance\_attestation$ and validates the status of the Wallet solution through a trust list | | 017 | The Issuer matches the pre-authorized code and generates an access token bound to the $DPoP$ key. | | 018 | The Issuer sends a Token Response; containing- $DPoP-bound\ access\ token$- $c\_nonce$ | | 019 | The Wallet generates a key pair for the cryptographic binding of the EAA (_device_pub_, _kb_eph_priv_) and signs the c_nonce | | 020 | The Wallet may request an encrypted credential response. In order to do so, it generates a new ephemeral keypair (_cre_eph_pub_, _cre_eph_priv_). | | 021 | The Wallet creates the `credential_response_encryption` JSON object containing the following information:- a jwk containing the _cre_eph_pub_- the JWE alg parameter- the JWE enc parameter | | 022 | The Wallet sends the Credential Request to the Issuer; containing- the DPoP-bound access token - the credential information either through `credential_identifier` or `credential_configuration_ids` - the proof of cryptographic binding key _device_pub_ signed c_nonce- and the `credential_response_encryption` object | | 023 | The Issuer validates the access_token and the proof | | 024 | **(SD-JWT VC EAA)** The Issuer creates the Disclosures from attestation data and signs the SD-JWT VC with _ep_priv_ containing- attestation data and hashed Disclosures as the user claims- _device_pub_ as cnf claim He then appends the Disclosures. | | 025 | **(mdoc EAA)** The Issuer creates the hashed Releases from attestation data and signs the mdoc with _ep_priv_ containing- attestation data and hashed Releases as issuerAuth- _device_pub_ as deviceKeyInfo | | 026 | In case `credential_response_encryption` information is present, the Issuer creates an encrypted JWT (JWE) with the information and adds (among others) the EAA credential to the payload. | | 027 | The Issuer sends the Credential Response JWT; containing:- The EAA as credential | | 028 | The Wallet decrypts the Credential Response JWT using the _cre_eph_priv_ and retrieves the credential. | | 029 | In case `credential_response_encryption` information are not present, the Issuer sends the plain Credential Response; containing:- The EAA as credential. | | 030 | The Wallet stores the EAA and the associated keys. | ## Usability Considerations ### Common Considerations - EAA Provider / Credential catalog should inform users in advance of what is required for the successful issuance of the EAA and what steps follow - For reasons of transparency and to increase trust, EAA Providers should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the provider itself. - User must confirm the process with the Device Authenticator - User can have a EAA credential on several end devices at the same time ### Authorization Code Flow Considerations - User needs to authenticate successfully on EAA Provider website - If the user has to go through more than 2 context switches (issuer initiated flow), it can be confusing, might create unnecessary complexity and additional potential points of failure, and ultimately leads to friction. ### Pre-Authorized Code Flow Considerations - User is already authenticated on EAA Provider website or no authentication is required - To obtain/copy the transaction code, an additional context switch may be necessary ## Privacy Considerations - Unlinkability has to be achieved with batch issuance ## Security Considerations - EAA Providers may choose to require a wallet instance attestation and a key attestation - The security guarantees of the Pre-Authorized Code Flow, especially in the Cross-Device Flow, are not intended for higher security levels ## Attestation Data and Signature Scope The term **attestation data** refers to the attributes and claims contained in the credential that are covered by the issuer's signature. For EAA, the following clarifications apply: | Credential Format | Signed Content | Signature Format | |-------------------|-----------------------------------------------------------------------|-----------------------------| | **SD-JWT VC** | All claims (hashed disclosures) + holder binding key (`cnf`) | JWS (JSON Web Signature) | | **ISO mdoc** | All attributes in `issuerAuth` + device key binding (`deviceKeyInfo`) | COSE_Sign1 | --- ## EAA Presentation with OpenID4VP ## Basic Idea The EAA Provider issues signed credentials to the Wallet, which are stored for a longer period. The Wallet can then present the credentials (including a proof of possession by signing over a wallet-held key) to the Relying Party. !!! note "Exemplary Flows" The flows described in this document are **examples** demonstrating one possible implementation approach. According to the Implementing Act on Article 5a and [ETSI TS 119 472-1](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards), the following credential formats are supported: - **SD-JWT VC** (SD-JWT Verifiable Credentials) - **mdoc** (ISO/IEC 18013-5) Relying Parties must be able to accept and validate credentials in the formats specified by the Implementing Act on Article 5b. !!! note "Profile" The presentation of an Electronic Attestation of Attributes (EAA) is governed by the [ETSI TS 119 472-2](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) specification. This standard mandates the use of the OID4VC High Assurance Interoperability Profile (OID4VC-HAIP) as the underlying protocol profile. ## Cryptographic Formats Long-Term keys: - EAA Provider has long-term key pair $(ep\_pub, ep\_priv)$ that is used to sign the credential - RP has long-term key pair $(rp\_pub, rp\_priv)$ that is used to sign OpenID4VP Authorization Request - EUDIW generates device key $(device\_pub, device\_priv)$ which is used to generate proof of possession of a credential Transaction-specific keys: - RP has ephemeral key pair $(rp\_eph\_pub, rp\_eph\_priv)$ that is used to encrypt the response Artifacts: - $kb\_jwt := \text{sign}(nonce, audience, \text{hash}(sd\_jwt, disclosures))_{device\_priv}$ - $device\_Auth$ for mdoc ## Same Device Flow ### Sequence Diagram [User Journey: EAA Presentation - Same Device](../../../user_journeys/QEAA-SameDevice-presentation.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title EAA presentation over OpenID4VP (same device) actor u as "User\nOpenID Holder" participant b as "Browser App\n(same device)" participant v [ Relying Party ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ] participant w [ User's EUDI Wallet Instance ---- ""Device binding Key: (//device_pub//, //device_priv//)"" ] u --> b : browse to application hnote over b #dfd: Screen: same_device_relying_party_start b -> v : tls() HTTP GET v -> v : generate new browser session with session_id v -> v : generate ephemeral key pair (//rp_eph_pub//, //rp_eph_priv//) note right: //rp_eph_pub// is only used for response encryption v -> v : create OpenID4VP JWT-secured Authorization Request (JAR),\n sign with //rp_priv//,\n store under ,\n bind everything to session_id note left: JWT-secured Authorization Request (JAR) includes:\n- dcql_query\n- nonce\n- state (required only for credential presentations that do not use key binding. In all other cases, it is optional.) v -> b : tls() HTTP 200 HTML containing wallet-link openid4vp://authorize?")\nclient_id=..&request_uri=\nSet-Cookie: sid=session_id u --> b : action to start flow/launch wallet b -> w : launch with wallet-link openid4vp:// hnote over w #dfd: Screen: launch_wallet u --> w : unlock wallet hnote over w #dfd: Screen: unlock_wallet w -> v : tls() HTTP GET v -> w : tls() HTTP 200 w -> w : validate Authorization Request JWT using //rp_pub// u --> w : user consent for presenting the EAA hnote over w #dfd: Screen: consent_present_credential alt #dfd SD-JWT VC EAA w -> w : generate KB-JWT by signing over nonce, audience, and hash of SD-JWT VC and selected disclosures with //device_priv// hnote over w #dfd: Screen: device_authenticator w -> w : generate SD-JWT VC presentation according to //dcql_query// by removing unnecessary Disclosures and attaching KB-JWT else #ddf mdoc EAA w -> w : generate deviceAuth by signing over SessionTranscript with //device_priv// hnote over w #dfd: Screen: device_authenticator w -> w : generate issuerAuth according t //dcql_query// by removing unnecessary Releases and attaching deviceAuth end w -> w : create vp_token and presentation_submission w -> v : tls() HTTP POST (optionally encrypted to //rp_eph_pub//) v -> v : optionally decrypt Authorization Response with //rp_eph_pub// v -> v : look up state in existing sessions\ncreate & store response_code for session v -> w : tls() HTTP 200 w -> b : launch browser with hnote over w #dfd: Screen: success_redirect b -> v : tls() HTTP GET \nCookie: sid=session_id v -> v : look up session with session_id and match response_code alt #dfd SD-JWT VC EAA v -> v : verify contents of :\n- SD-JWT VC signature from EAA Provider\n- KB-JWT with //device_pub// from SD-JWT VC\n- nonce and audience from KB-JWT else #ddf mdoc EAA v -> v : verify contents of :\n- mdoc signature from EAA Provider\n- deviceAuth with //device_pub// from mdoc issuerAuth\n- nonce and audience from SessionTranscript end v -> b : tls() HTTP 200 hnote over b #dfd: Screen: same_device_relying_party_identified @enduml ``` ### Step-by-Step Description Note: While certain assumptions about session management of the Relaying Party are made here, the concrete implementation is considered out of scope for this document. The usual security considerations for web session management apply. | No | Description | | --- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 001 | User browses to Relying Party (RP) website | | 002 | Browser app on the user's device opens the RP website | | 003 | The RP generates a new browser session, depicted `session_id` | | 004 | The RP generates a key pair to be used for ECDH key agreement for response encryption | | 005 | The RP generates an OpenID4VP JWT-secured Authorization Request (JAR), binding it internally to the `session_id` and stores it under a `request_uri` (e.g., `https://rp.example.com/oidc/request/1234`);- The request is bound to the user's browser session- It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id- It contains the presentation_definition containing the information about the requested EAAs- It contains RP's nonce and state- It contains the purpose given by the RP | | 006 | The RP returns a HTML page to the browser containing a link to the wallet app (e.g., `openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234`). It also sets a Cookie with the `session_id`. | | 007 | The user clicks on the link | | 008 | The wallet app is launched with the custom URI scheme | | 009 | The user unlocks the wallet app (see notes below) | | 010 | The wallet app retrieves the Authorization Request from the RP website (e.g., `https://rp.example.com/oidc/request/1234`) | | 011 | The wallet app receives the Authorization Request | | 012 | The wallet app validates the Authorization Request using the RP's public key- Was the signature valid and the key bound to the RP's metadata?- **Security:** This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP. | | 013 | The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the EAA. | | 014 | **(SD-JWT VC EAA)** The Wallet generates a KB-JWT by signing over nonce,audience, and hash of SD-JWT VC and selected disclosures with _device_priv_ | | 015 | **(SD-JWT VC EAA)** The Wallet creates the presentation according to presentation_definition by cutting out the unnecessary Disclosures and appending the KB-JWT | | 016 | **(mdoc EAA)** The Wallet generates an mdoc deviceAuth by signing over SessionTranscript with _device_priv_ | | 017 | **(mdoc EAA)** The Wallet creates the presentation according to presentation_definition by cutting out the unnecessary Releases assembling the issuerAuth with deviceAuth | | 018 | The wallet app creates a VP token | | 019 | The wallet app sends the VP token to the RP (encrypted to the RP's public key _rp_eph_pub_). | | 020 | The RP optionally decrypts the Authorization Response with _rp_eph_pub_ received in the Authorization Request. | | 021 | The RP finds a session with the state, generates a response_code and stores the received vp_token | | 022 | The RP responds with a redirect inluding the generated response_code. | | 023 | The wallet launches the browser with the redirect_uri and response_code. | | 024 | The browser receives the redirect_uri and response_code and sends an HTTP GET request to the RP frontend, this request contains the Cookie set in the beginning of the protocol. | | 025 | The RP matches the session_id from the Cookie and matches the response_code to find the received vp_token. | | 026 | **(SD-JWT VC EAA)** The RP verifies the content of the vp_token. In case of SD-JWT VC it validates the Issuer signature from the EAA Provider, verifies the KB-JWT matching to the cnf claim and validates that the KB-JWT is fresh and matches to its own client_id and nonce. | | 027 | **(mdoc EAA)** The RP verifies the content of the vp_token. In case of mdoc it validates the Issuer signature from the EAA Provider, verifies the deviceAuth matching to the deviceKey and validates that the SessionTranscript is fresh and matches to its own client_id and nonce. | | 028 | The RP considers the user to be identified in the session context and continues the UX flow. | ## Cross Device Flow ### Sequence Diagram [User Journey: EAA Presentation - Cross Device](../../../user_journeys/QEAA-CrossDevice-presentation.png) ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title EAA presentation over OpenID4VP (cross device) actor u as "User\nOpenID Holder" participant b as "Browser App\n(other device)" participant v [ Relying Party ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ] participant w [ User's EUDI Wallet Instance ---- ""Device binding Key: (//device_pub//, //device_priv//)"" ] u --> b : browse to application hnote over b #dfd: Screen: cross_device_relying_party_start b -> v : tls() HTTP GET v -> v : generate new browser session with session_id v -> v : generate ephemeral key pair (//rp_eph_pub//, //rp_eph_priv//) note right: //rp_eph_pub// is only used for response encryption v -> v : create OpenID4VP JWT-secured Authorization Request (JAR),\n sign with //rp_priv//,\n store under ,\nbind everything to session_id note left: JWT-secured Authorization Request (JAR) includes:\n- dcql_query\n- nonce\n- state (required only for credential presentations that do not use key binding. In all other cases, it is optional.) v -> b : tls() HTTP 200 HTML containing wallet-link openid4vp://authorize?")\nclient_id=..&request_uri=\nSet-Cookie: sid=session_id u --> w : launch wallet hnote over w #dfd: Screen: launch_wallet u --> w : unlock wallet hnote over w #dfd: Screen: unlock_wallet b -> w : scan QR-Code with "openid4vp://..." hnote over w #dfd: Screen: device_camera w -> v : tls() HTTP GET v -> w : tls() HTTP 200 w -> w : validate Authorization Request JWT using //rp_pub// u --> w : user consent for presenting the EAA hnote over w #dfd: Screen: consent_present_credential alt #dfd SD-JWT VC EAA w -> w : generate KB-JWT by signing over nonce, audience, and hash of SD-JWT VC and selected disclosures with //device_priv// hnote over w #dfd: Screen: device_authenticator w -> w : generate SD-JWT VC presentation according to by removing unnecessary Disclosures and attaching KB-JWT else #ddf mdoc EAA w -> w : generate deviceAuth by signing over SessionTranscript with //device_priv// hnote over w #dfd: Screen: device_authenticator w -> w : generate issuerAuth according to by removing unnecessary Releases and attaching deviceAuth end w -> w : create vp_token and presentation_submission w -> v : tls() HTTP POST (optionally encrypted to //rp_eph_pub//) v -> v : optionally decrypt Authorization Response with //rp_eph_pub// v -> v : look up state in existing sessions and match session alt #dfd SD-JWT VC EAA v -> v : verify contents of :\n- SD-JWT VC signature from EAA Provider\n- KB-JWT with //device_pub// from SD-JWT VC\n- nonce and audience from KB-JWT else #ddf mdoc EAA v -> v : verify contents of :\n- mdoc signature from EAA Provider\n- deviceAuth with //device_pub// from mdoc issuerAuth\n- nonce and audience from SessionTranscript end v -> w : tls() HTTP 200 note right: in cross device flow the redirect is omitted here hnote over w #dfd: Screen: success note over b,v : The Browser may refresh the RP website with polling or the RP website may send a signal, e.g. with previuosly established websocket b -> v : tls() HTTP GET \nCookie: sid=session_id v -> v : look up session with session_id and match verification result v -> b : tls() HTTP 200 hnote over b #dfd: Screen: cross_device_relying_party_identified @enduml ``` ### Step-by-Step Description Note: While certain assumptions about session management of the Relaying Party are made here, the concrete implementation is considered out of scope for this document. The usual security considerations for web session management apply. | No | Description | | --- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 001 | The user browses to Relying Party (RP) website | | 002 | Browser app on the user's device opens the RP website | | 003 | The RP generates a new browser session, depicted `session_id` | | 004 | The RP generates a key pair to be used for ECDH key agreement for response encryption | | 005 | The RP generates an OpenID4VP JWT-secured Authorization Request (JAR), binding it internally to the `session_id` and stores it under a `request_uri` (e.g., `https://rp.example.com/oidc/request/1234`); - The request is bound to the user's browser session- It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id- It contains the presentation_definition containing the information about the requested EAAs- It contains RP's nonce and state- It contains the purpose given by the RP | | 006 | RP returns a HTML page to the browser containing a QR-Code to the wallet app (e.g., `openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234`). It also sets a Cookie with the `session_id`. | | 007 | The user launches the wallet app. | | 008 | The user unlocks the wallet app (see notes below) | | 009 | The user scans the QR-Code from the RP's website. The wallet decodes the Authorization Request and starts the OpenID4VP Flow. | | 010 | The wallet app retrieves the Authorization Request from the RP website (e.g., `https://rp.example.com/oidc/request/1234`) | | 011 | The wallet app receives the Authorization Request | | 012 | The wallet app validates the Authorization Request using the RP's public key - Was the signature valid and the key bound to the RP's metadata?- **Security:** This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP. | | 013 | The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the EAA. | | 014 | **(SD-JWT VC EAA)** The Wallet generates a KB-JWT by signing over nonce,audience, and hash of SD-JWT VC and selected disclosures with _device_priv_ | | 015 | **(SD-JWT VC EAA)** The Wallet creates the presentation according to presentation_definition by cutting out the unnecessary Disclosures and appending the KB-JWT | | 016 | **(mdoc EAA)** The Wallet generates an mdoc deviceAuth by signing over SessionTranscript with _device_priv_ | | 017 | **(mdoc EAA)** The Wallet creates the presentation according to presentation_definition by cutting out the unnecessary Releases assembling the issuerAuth with deviceAuth | | 018 | The wallet app creates a VP token | | 019 | The wallet app sends the VP token to the RP (encrypted to the RP's public key _rp_eph_pub_). | | 020 | The RP optionally decrypts the Authorization Response with _rp_eph_pub_ received in the Authorization Request. | | 021 | The RP matches the browser session with the state parameter. | | 022 | **(SD-JWT VC EAA)** The RP verifies the content of the vp_token. In case of SD-JWT VC it validates the Issuer signature from the EAA Provider, verifies the KB-JWT matching to the cnf claim and validates that the KB-JWT is fresh and matches to its own client_id and nonce. | | 023 | **(mdoc EAA)** The RP verifies the content of the vp_token. In case of mdoc it validates the Issuer signature from the EAA Provider, verifies the deviceAuth matching to the deviceKey and validates that the SessionTranscript is fresh and matches to its own client_id and nonce. | | 024 | The RP responds with HTTP 200 and acknowledges the received vp_token. | | 025 | The browser refreshes the RP's website, either by polling regularly or by receiving a signal from the RP, e.g. through websockets. It sends a HTTP GET request using the Cookie set in the beginning of the protocol. | | 026 | The RP matches the session_id from the Cookie and matches this with the verification result. | | 027 | The RP considers the user to be identified in the session context and continues the UX flow. | ## Usability Considerations ### Common Considerations - Relying Party should inform users in advance of what is required for the process to be completed successfully and what steps to follow - For reasons of transparency and to increase trust, Relying Parties should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the relying party itself, privacy and data retention - The user's data values for the requested attributes can be displayed on the consent screen - The user only needs to confirm the EAA presentation with the Device Authenticator ### Same Device Considerations - It needs to be clarified whether the wallet app needs to be unlocked in this flow, as the device authenticator is requested again directly after the consent screen. This might create friction and feel redundant to users - It must be ensured that users are returned to the correct tab in the correct browser in order to continue the process or users know how to get there manually, if necessary (especially for iOS devices, if the process was not started in the default browser) ### Cross Device Considerations - It needs to be clarified whether the wallet app needs to be unlocked in this flow and how this should be implemented. - User can then continue with the process on the RP page on the second device (page must be updated accordingly by the RP) ## Privacy Considerations - Selective Disclosure is achieved by ensuring that the presentation contains only those data items (claims) that are requested by the RP. The selective disclosure features of SD-JWT VC are used to this end. - Unlinkability has to be achieved with batch issuance - In Presentation Step 5, a malicious app may spoof the wallet app; an attacker may - **on his own device:** Capture the request and replay it to a victim on another device, thus having the victim identify itself in a context of the attacker (**Relaying Attack breaking Identification Context**); or - **on the victim's device:** Capture the request and spoof the whole identification process or parts of it (**Wallet App Spoofing**). - In Presentation Step 5: An attacker acting as an RP can forward a request from a different RP. - As long as the request remains unchanged, we're in the **Relaying Attack breaking Identification Context** - If the attacker changes anything in the request, this will break the signature. The attacker could otherwise attempt to - insert his own ephemeral key, leading to an SD-JWT VC artifact that could be used in a different flow between the attacker and some other RP. - modify state or nonce or other data. **Q:** Any useful attacks resulting from this? - In Presentation Step 14: The RP must not consider the user identified at this point; it is important to have the browser redirect in the later steps. ## Requirements for EAA Presentation and Validation When validating presented EAA credentials, Relying Parties must verify the issuer's digital signature. ### Supported Signature Formats The digital signature for EAA must fulfill one of the following signature formats: | Signature Format | ETSI Standard | Typical Use Case | | ---------------- | ----------------- | ---------------------------------------- | | **CAdES** | ETSI EN 319 122 | Binary data, CMS-based signatures | | **CBAdEs**. | ETSI TS 119 152-1 | CBOR data signatures (mdoc deviceAuth) | | **XAdES** | ETSI EN 319 132 | XML-based signatures | | **ASiC** | ETSI EN 319 162 | Container format for multiple signatures | | **JAdES** | ETSI TS 119 182-1 | JSON/JWT-based signatures (SD-JWT VC) | !!! info "Credential Format to Signature Format Mapping" The choice of signature format depends on the credential format: - **SD-JWT VC**: JAdES (ETSI TS 119 182-1) - JSON Web Signature based - **mdoc**: CBAdEs or COSE signatures per ISO/IEC 18013-5 ### Relying Party Validation Requirements Relying Parties verifying EAA must: 1. **Verify the issuer signature** using one of the supported signature formats 2. **Verify the holder binding** (KB-JWT for SD-JWT VC, deviceAuth for mdoc) 3. **Check credential validity** including expiration and revocation status ### References - **ETSI TS 119 472-1**: General requirements for electronic attestations of attributes - **ETSI TS 119 472-2**: Presentation requirements - **Implementing Act on Article 5a/5b**: Credential formats for issuance and presentation --- ## Catalogue of Attestations ## Overview The EUDI Wallet ecosystem requires mechanisms for relying parties to discover available credential types, understand their structure, and verify issuers. The **catalogue of attestations** addresses these requirements by providing a registry of attestation types with their schema definitions and trust anchors. Each attestation type entry in the catalogue consists of two parts: - **SchemaMeta** (machine-readable): Defines schema URIs, supported formats, trust anchors, and binding requirements - **Attestation Rulebook** (human-readable): Documents governance rules, compliance requirements, and issuance policies These mechanisms are specified in TS 11 of the Architecture Reference Framework (ARF) and enable interoperability across the ecosystem. --- ## Purpose and Key Challenges When a relying party wants to request a presentation, two fundamental questions must be answered: 1. **What is the structure of the attestation?** — The relying party must know the exact schema and attribute identifiers to construct valid requests. Different credential formats (e.g., mdoc vs. SD-JWT VC) may encode the same logical data differently. 2. **Who is authorized to issue this credential?** — Anyone can create a digital signature, but the relying party must verify that the issuer was authorized to issue this specific attestation type. Attestation rulebooks and catalogues solve these challenges: | Challenge | Solution | | ------------------------------------------------------------------------------ | ----------------------------------------------- | | **Discovery:** How do relying parties find relevant credential types? | Catalogue provides searchable registry | | **Interoperability:** How do different systems understand the same credential? | SchemaMeta defines canonical schemas per format | | **Trust:** How do relying parties know which issuers to accept? | SchemaMeta references authoritative trust lists | | **Verification:** How should credentials be validated? | Rulebooks specify verification rules | --- ## SchemaMeta Structure Each attestation type entry combines human-readable governance documentation with machine-readable schema definitions. The human-readable **Attestation Rulebook** document defines governance, rules, and compliance requirements. The machine-readable **SchemaMeta** object contains the schema references and trust anchors. TS 11 version 1.0.1 defines the `SchemaMeta` main class with the following components: ### Core Identification | Field | Description | | --------------- |-------------------------------------------------------------------------------------------------------------------------------------------| | **id** | Unique identifier (UUID) assigned by the catalogue provider | | **version** | Version of the schema following SemVer | | **rulebookURI** | URI to the human-readable Attestation Rulebook document. May include `#integrity` suffix with W3C SRI metadata for integrity verification | ### Schema References The `schemaURIs` array contains `Schema` objects linking schema definitions for each supported credential format. Since different formats (e.g., mdoc, SD-JWT VC) encode attributes differently, each schema reference includes: | Field | Description | | -------------------- |------------------------------------------------------------------------------------------| | **formatIdentifier** | Credential format: `dc+sd-jwt`, `mso_mdoc`, `jwt_vc_json`, `jwt_vc_json-ld`, or `ldp_vc` | | **uri** | Persistent schema URI assigned by the catalogue. May include `#integrity` suffix | ### Trust Anchors The `trustedAuthorities` array contains `TrustAuthority` objects specifying which entities are authorized to issue this credential type. Each entry resolves to the applicable trust framework: | Field | Description | |-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **frameworkType** | Type of trust framework: `aki` (X.509 Authority Key Identifier), `etsi_tl` (ETSI Trusted List), or `openid_federation` | | **value** | base64url for `aki`, or URI for `etsi_tl` / `openid_federation` | | **isLoTE** | Boolean indicating if the trusted list is a List of Trusted Entities ([ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)) rather than [ETSI TS 119 612](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards). Only used with `etsi_tl` type | For QEAAs and PubEAAs, trust is resolved via the EU List of Trusted Lists ([ETSI TS 119 612](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)). For EAAs, the List of Trusted Entities (LoTE) approach per [ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) is recommended. OpenID Federation may only be used for EAAs. The `trustedAuthorities` attribute is optional only for attestations without any trust model (i.e., self-signed attestations). ### Additional Metadata | Field | Description | | -------------------- | ------------------------------------------------------------------------------------------------------------------------ | | **attestationLoS** | Level of security for issuance: `iso_18045_high`, `iso_18045_moderate`, `iso_18045_enhanced-basic`, or `iso_18045_basic` | | **bindingType** | Cryptographic binding: `claim` (to presented claim), `key` (to user's key), `biometric` (to biometrics), or `none` | | **supportedFormats** | Array of supported formats: `dc+sd-jwt`, `mso_mdoc` | --- ## Schema References Each EU member state maintains a national catalogue of schemes for attestation of attributes. Schema references enable relying parties to construct valid credential requests and issuers to validate credentials before issuance. Without knowing the exact attribute identifiers, a relying party cannot request specific data. For example, the PID encodes the date of birth differently depending on format: - **mdoc:** `birth_date` - **SD-JWT VC:** `birthdate` Similarly, country of residence is encoded as: - **mdoc:** `resident_country` - **SD-JWT VC:** `address.country` The wallet performs exact matching when processing presentation requests. If a relying party requests an attribute using an incorrect identifier, the wallet will indicate that no matching credential is available. It does not attempt to guess the intended attribute. ### Schema Structure Schemas are defined using JSON Schema and include: ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://catalogue.example.de/schemas/membership-card-sd-jwt.json", "title": "Membership Card (SD-JWT VC)", "type": "object", "properties": { "vct": { "type": "string", "const": "https://example.de/attestations/membership-card" }, "memberName": { "type": "string", "maxLength": 256 }, "membershipTier": { "type": "string", "enum": ["Basic", "Standard", "Premium"] }, "nbf": { "type": "number", "description": "Valid from (Unix timestamp)" }, "exp": { "type": "number", "description": "Valid until (Unix timestamp)" } }, "required": ["vct", "memberName", "membershipTier", "nbf", "exp"] } ``` ### Benefits Schema references provide value to multiple actors: - **Relying parties:** Can construct valid DCQL queries with correct attribute identifiers - **Issuers:** Can validate credentials against the schema during issuance, catching errors before credentials are issued - **Tooling:** Machine-readable schemas enable automated configuration and validation tools --- ## Issuer Authorization ### The Challenge Digital signatures alone do not establish trust. Any entity can create a signed credential, but relying parties must verify that the issuer was authorized to issue that specific attestation type. The trust anchor for verification must be obtained out-of-band via a trusted channel, not from the wallet interaction itself. The wallet is controlled by the holder, and relying parties are responsible for verifying issuer authorization independently. ### Verification Approach For different attestation types, issuer authorization is verified differently: | Attestation Type | Authorization Source | | ---------------- | ---------------------------------------------------------- | | **PubEAA** | EU Trusted List links issuer identity to attestation type | | **QEAA** | EU Trusted List | | **EAA** | Attestation rulebook with trust list of authorized issuers | For EAAs and QEAAs, the verification flow involves: 1. Wallet fetches issuer metadata during issuance 2. Issuer metadata includes a registration certificate (per [ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)) 3. Registration certificate references the applicable rulebook (per [ETSI TS 119 475](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards)) 4. Rulebook contains the trust list with authorized issuers > It is not clear at this point if a QEAA provider needs to be authorized to issue a specific QEAA (i.e., if there needs to be an entry present for authorized issuers in the rulebook). ### Trust List Management Trust lists following [ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) can be hosted and managed by the rulebook publisher. The trust list is a signed JWT, allowing issuers to be added or removed without modifying the rulebook itself. This enables scenarios such as: - A ministry of education publishing a rulebook for diplomas while maintaining a trust list of authorized educational institutions - Multiple member states sharing a common schema while maintaining separate national trust lists --- ## Catalogue of Attestations ### Concept The catalogue of attestations is a registry where attestation rulebooks are published and can be discovered. While a central EU catalogue is envisioned, member states can also operate their own catalogues—similar to how multiple DNS services enable internet browsing. This federated approach allows national governance while maintaining interoperability through consistent rulebook structures. ### Legal Framework Per [EU Implementing Act 2025/1569](https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=OJ:L_202501569), Article 8, the Commission **shall** establish and publish a catalogue of schemes for the attestation of attributes. !!! info "Catalogue of Schemes vs. Catalogue of Attributes" The Implementing Act defines two distinct catalogues: - **Catalogue of Schemes** (Art. 8) — Registry of attestation rulebooks defining credential types, schemas, and trust anchors. This is the focus of this document. - **Catalogue of Attributes** (Art. 7) — Registry of individual attributes that may be attested, particularly those from authentic sources. Within the EUDI Wallet ecosystem, registration in the catalogue of schemes is required for QEAA and PubEAA to ensure interoperability and trust validation. ### National and EU Catalogues Member States maintain **national catalogues** of attestation schemes alongside the EU-level catalogue. This two-tier structure enables: - **National governance:** Member States can register schemes relevant to their jurisdiction and begin ecosystem operations before the EU catalogue is available - **EU interoperability:** The EU catalogue provides automatic EU-wide recognition and harmonized trust validation | Aspect | National Catalogue | EU Catalogue | |------------------------------| ------------------ | ------------------------ | | **Establishment** | Member State responsibility | Commission SHALL establish (Art. 8) | | **Publication** | Member State manages | Commission manages | | **Cross-border recognition** | Bilateral/multilateral agreements | Automatic EU-wide | | **Trust level** | Member State | EU-wide interoperability | Cross-border recognition from a national catalogue is possible through bilateral or multilateral agreements between Member States. The EU catalogue provides *automatic* EU-wide recognition without requiring such agreements. ### Transition from National to EU Catalogue Member States may begin with national catalogues before the EU catalogue is operational. When the EU catalogue becomes available: 1. **Existing schemes remain valid** — Schemes in national catalogues continue to function domestically 2. **Registration in EU catalogue** — For automatic EU-wide recognition, schemes should be registered in the EU catalogue 3. **Synchronization** — Schemes may appear in both catalogues; national catalogues can reference or mirror EU catalogue entries !!! info "Phased rollout" Starting with a national catalogue enables early ecosystem adoption while the EU infrastructure matures. The transition to the EU catalogue should be planned to ensure continuity for existing credentials and relying parties. ### Publication Requirements The publication of attestation rulebooks in the catalogue is required for certain attestation types by eIDAS regulation: | Attestation Type | Publication Requirement | | ---------------- | ----------------------- | | **QEAA** | SHALL register | | **PubEAA** | SHALL register | | **EAA** | MAY register | The European Commission's [Attestation Rulebooks Catalogue](https://github.com/eu-digital-identity-wallet/eudi-doc-attestation-rulebooks-catalog) is the designated repository for publishing Attestation Rulebooks and their schemas. All QEAA and PubEAA providers should publish their rulebooks in this catalogue. !!! info "Publishing EAAs" Publication is necessary only when parties outside a closed ecosystem should be able to consume or issue the attestation. For EAAs within a closed ecosystem where all participants are known, catalogue publication may not be required. ### Publisher Authentication Rulebook publication requires authentication but not authorization by the catalogue provider. This approach enables ecosystem growth while maintaining accountability: - **Authentication:** Publishers sign rulebooks using their Access Certificate (the x.509 certificate required for interaction with EUDI Wallets per eIDAS) - **Trust anchor:** The Access Certificate Authority of the member state - **Accountability:** Publishers can be identified through the Know Your Customer process required for Access Certificate issuance Any authenticated publisher can submit rulebooks. The catalogue operator does not perform authorization checks or content review—this enables permissionless innovation while maintaining identity accountability. However, the catalog provider retains the ability to remove entries in cases of malicious behavior, policy violations, or other legitimate concerns, ensuring ecosystem integrity while maintaining the permissionless publication model. !!! warning "Catalogue presence does not imply trust" The catalogue is a **discovery mechanism, not a trust endorsement**. Any authenticated entity can publish a rulebook, which means the catalogue may contain entries of varying quality and legitimacy. Relying parties must **independently evaluate** whether to accept a given attestation type by examining the referenced trust anchors and governance rules—not by assuming that catalogue inclusion signals trustworthiness. For example, a fictional entity could publish a rulebook for a "Professional Engineer License" attestation. The entry would appear in the catalogue alongside legitimate entries. A relying party accepting this attestation must verify that the issuer appears on a trust list they recognize (e.g., an ETSI Trusted List maintained by a national engineering authority). Without this verification step, accepting the credential based on catalogue presence alone would be insecure. In practice, relying parties should: - Only accept attestation types whose trust anchors chain to authorities they recognize - Verify that the trust list referenced in the rulebook is operated by a known and reputable entity - Treat the catalogue as a source of **schema and format information**, not as a guarantee of issuer legitimacy ### Security Considerations Even if a catalogue provider is compromised, attackers can only delete rulebooks—not modify them. Only the holder of the Access Certificate that published a rulebook can provide updates, as the signature verification would fail otherwise. --- ## Using Attestation Rulebooks ### For Issuers 1. **Publish an attestation rulebook** defining your credential type 2. **Provide (or reference existing) schema definitions** for each supported credential format 3. **Manage your trust list** of authorized issuers (can be updated independently) 4. **Validate credentials against the schema** during issuance to catch errors 5. **Version your rulebook** when schemas change ### For Relying Parties 1. **Discover credential types** via catalogue search 2. **Retrieve schemas** to construct valid presentation requests with correct attribute identifiers 3. **Configure trust anchors** from the rulebook to verify issuer authorization 4. **Validate credentials** using the verification rules specified in the rulebook ### For Wallet Providers 1. **Verify issuer authorization** by checking the rulebook-defined trust list during issuance 2. **Display credential information** using schema metadata 3. **Enable credential discovery** (see below) --- ## Discovery Mechanisms The catalogue enables discovery functionality that benefits both relying parties and wallet holders. ### Relying Party Discovery Relying parties can query the catalogue to understand: - Which credential types exist in the ecosystem - What attributes each credential type contains - Which issuers are authorized for each credential type - How to construct valid presentation requests ### Wallet-Based Discovery With access to the catalogue, wallets can provide enhanced user experiences: **Issuance during presentation:** When a relying party requests a credential the user does not possess, the wallet can use the catalogue to determine how and where to obtain it. This enables on-demand credential acquisition without requiring the relying party to provide issuance instructions. **Proactive suggestions:** The wallet can scan the catalogue for relevant credential types based on the user's existing attestations and preferences, suggesting credentials that may be useful. This processing can occur entirely on-device to preserve privacy. --- ## Ecosystem Visibility The catalogue of attestations combined with registrar data (where relying parties declare their intended credential requests) provides visibility into ecosystem supply and demand. These metrics can be monitored in a privacy-preserving way without revealing actual credential usage patterns: - **Supply:** Which attestation types are available and who can issue them - **Demand:** Which attestation types relying parties intend to request This visibility helps ecosystem participants understand adoption and identify gaps without requiring centralized transaction monitoring. --- ## Reference Implementation A proof-of-concept implementation demonstrating these data models is available at [github.com/cre8/catalog-of-attestations](https://github.com/cre8/catalog-of-attestations). The repository provides: - **`catalog.schema.json`** — JSON Schema for the `SchemaMeta` data model - **Example attestation** — Gym Membership Card as SD-JWT VC - **Format-specific schemas** — Claimset schemas for credential validation - **ETSI LoTE trust list** — Working example of issuer authorization - **Human-readable rulebook** — Governance documentation template The implementation also includes practical extensions addressing integrity verification (SRI hashes for schemas and rulebooks) and trust list signing for private ecosystems that don't chain to the EU List of Trusted Lists. --- ## Ongoing Standardization The technical specifications for attestation rulebooks and catalogues are actively being developed within ETSI. Key specifications include: - **[ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards):** List of Trusted Entities (LoTE) for trust list management - **[ETSI TS 119 472-3](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards):** Embedding registration certificates in issuance requests - **[ETSI TS 119 47](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards):** Structure of registration certificates with rulebook references --- ## References - **ARF TS 11:** Specification of interfaces and formats for the catalogue of attributes and the catalogue of attestations (v1.0.1) - **[ETSI TS 119 478](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards):** Specification of interfaces related to Authentic Sources - **[ETSI TS 119 612](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards):** Trusted Lists - **[ETSI TS 119 602](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards):** List of Trusted Entities (LoTE) data model - **Attestation Rulebooks Catalogue:** [GitHub Repository](https://github.com/eu-digital-identity-wallet/eudi-doc-attestation-rulebooks-catalog) - **Reference Implementation:** [Catalogue of Attestations POC](https://github.com/cre8/catalog-of-attestations) - **CIR for EAAs:** Commission Implementing Regulation (EU) 2025/1569 --- ## Anatomy of a Credential ## Overview All credentials in the EUDI ecosystem—regardless of their legal classification (PID, EAA, QEAA, PubEAA)—share common technical mechanisms. Understanding these mechanisms is essential for designing interoperable and secure credentials. This page describes the building blocks that every well-designed credential should incorporate. --- ## Credential Structure A credential consists of several layers: ```plantuml @startuml skinparam rectangle { BackgroundColor White BorderColor Black RoundCorner 5 } skinparam defaultTextAlignment left rectangle "**Credential**" as cred { rectangle "**Metadata**\n • Credential type identifier\n • Issuer identifier\n • Issuance date\n • Validity period\n • Revocation/status information" as meta rectangle "**Claims (Attributes)**\n • Mandatory attributes\n • Optional attributes\n • Selective disclosure markers" as claims rectangle "**Holder Binding**\n • Key reference / biometric / claim-based" as binding rectangle "**Issuer Signature**\n • Cryptographic proof of authenticity" as sig } meta -[hidden]down- claims claims -[hidden]down- binding binding -[hidden]down- sig @enduml ``` ### Metadata Metadata provides context about the credential itself: | Field | Purpose | | --------------------- | --------------------------------------------------------------------------- | | **Credential type** | Identifies what kind of credential this is (e.g., diploma, membership card) | | **Issuer identifier** | Uniquely identifies the issuing organization | | **Issuance date** | When the credential was created | | **Validity period** | How long the credential remains valid | | **Schema reference** | Points to the attribute schema definition | | **Rulebook URI** | References the governing rulebook (for EAAs) | ### Claims (Attributes) Claims are the actual data the credential attests to. They should be: - **Precisely typed:** Use appropriate data types (string, number, date, image) - **Standards-aligned:** Follow existing standards where available - **Regulation-aligned:** Use terminology from applicable regulations - **Minimized:** Include only necessary data (data minimization principle) - **Harmonized:** Use consistent structure across issuers of the same credential type --- ## Signature Mechanisms Every credential must be cryptographically signed by its issuer. The signature provides: - **Authenticity:** Proof that the credential was issued by the claimed issuer - **Integrity:** Assurance that the credential has not been tampered with ### Signature Formats by Credential Type | Credential Format | Recommended Signature Format | | ----------------- | ------------------------------------------- | | SD-JWT VC | JAdES (JSON Advanced Electronic Signature) | | ISO mDoc | CBAdES (CBOR Advanced Electronic Signature) | ### Signature Requirements For all EAAs: - Use certificates linked to the referenced trust anchor - Follow BSI/ENISA cryptographic recommendations - Consider post-quantum algorithm readiness For high-trust EAAs (where document-equivalent evidentiary value is desired): - Use Qualified Electronic Signatures (QES) or Qualified Electronic Seals (QSeal) - Ensure long-term validation capability if long-term storage is required !!! warning "Certificate vs. Credential Revocation" Never revoke signing certificates to invalidate individual credentials—this is too coarse-grained and affects all credentials signed with that certificate. Use credential-level revocation mechanisms instead. --- ## Holder Binding Holder binding ensures that a credential can only be used by its legitimate holder. Three binding mechanisms exist: ### Wallet Binding (Recommended for EUDI Ecosystem) The credential is cryptographically bound to a key held in the user's wallet. - **Mechanism:** Credential contains a reference to a public key; the wallet proves possession of the corresponding private key during presentation - **Verification:** Relying party verifies the key proof - **Advantages:** Strong binding, privacy-preserving, works across all verification contexts - **Best for:** Native EUDI ecosystem usage ### Claim Binding The credential contains identifying claims (e.g., name, date of birth) that the relying party matches against another identity source. - **Mechanism:** Verifier identifies the user separately (e.g., via PID presentation) and matches claims - **Verification:** Relying party compares credential claims with verified identity - **Advantages:** Works across different media/systems, useful for migration scenarios - **Best for:** Cross-media usage, interoperability with non-wallet systems ### Biometric Binding The credential contains biometric data (face image, fingerprint template) that the verifier matches against the presenting person. - **Mechanism:** Credential includes biometric template; verifier captures live biometric and compares - **Verification:** On-site biometric matching - **Advantages:** Strong physical binding, does not require device interaction - **Best for:** High-security on-site verification, border control scenarios --- ## Revocation Mechanisms Revocation allows an issuer to invalidate a credential before its natural expiry. This is necessary when: - Underlying attributes have changed - The credential was issued in error - Misuse has been detected or is suspected - The holder requests invalidation ### When Revocation Is Required | Scenario | Revocation Needed? | | ------------------------------------------------- | -------------------- | | Very short-lived credentials (hours/days) | Usually not | | Attributes that may change during validity period | Yes | | Credentials where misuse poses significant risk | Yes | | High-trust credentials (QEAA, PubEAA) | Yes, within 24 hours | ### Revocation Mechanisms The preferred approach for the EUDI ecosystem is **status lists**: - Issuer publishes a cryptographically signed list of revoked credential identifiers - Relying party downloads the list periodically and checks locally - No per-verification call to the issuer (privacy-preserving) !!! danger "Anti-pattern: OCSP-style lookups" Do not use Online Certificate Status Protocol (OCSP) style mechanisms where the relying party queries the issuer for each verification. This allows the issuer to track where and when credentials are used. ### Status List Updates - Status lists should be updated at regular intervals - For high-trust credentials: at least every 24 hours - Lists should be cached by relying parties to ensure availability --- ## Anti-Tracking Measures To prevent correlation of credential usage across different verifiers, implement these measures: ### Validity Period Variation Issue credentials with slightly varied validity periods rather than uniform timestamps: - Round timestamps to hours or days rather than exact seconds - Add small random offsets to expiry dates - This prevents using the exact validity period as a tracking identifier ### Batch Issuance Issue multiple interchangeable credentials to the same holder: - Each credential has a different identifier but contains the same attributes - Wallet can rotate which credential is presented - Prevents correlation via credential identifier ### Selective Disclosure Reveal only the minimum necessary attributes for each presentation: - Both SD-JWT VC and ISO mDoc support selective disclosure natively - Configure credentials to allow fine-grained disclosure - Relying parties should request only what they need For more details on privacy requirements, see [Privacy Requirements](../../ecosystem-concepts/crosscutting-concepts/privacy-requirements.md). --- ## Supported Credential Formats EAAs in the German EUDI Wallet ecosystem may be issued in two formats: ### SD-JWT VC (Selective Disclosure JWT Verifiable Credential) - **Based on:** IETF SD-JWT VC specification - **Encoding:** JSON - **Optimized for:** Online/remote presentation - **Selective disclosure:** Native support via salted hash claims - **Developer experience:** Familiar JSON/JWT tooling ### ISO mDoc (ISO/IEC 18013-5) - **Based on:** ISO/IEC 18013-5 (mobile driving license standard) - **Encoding:** CBOR - **Optimized for:** Proximity presentation (NFC, BLE) - **Selective disclosure:** Built-in via namespace structure - **Ecosystem alignment:** Anchor format for PID ### Choosing a Format | Use Case | Recommended Format | | -------------------------------------------- | -------------------------------- | | Primarily online/remote verification | SD-JWT VC | | Primarily in-person/proximity verification | ISO mDoc | | Cross-border interoperability required | ISO mDoc (if PID-aligned) | | Integration with existing web infrastructure | SD-JWT VC | | Both online and proximity use cases | Consider issuing in both formats | --- ## Designing Well-Made EAAs ## Overview While signature and revocation mechanisms are not legally mandated for EAAs, a well-designed EAA should incorporate them. This page provides recommendations for creating EAAs that are secure, interoperable, and trustworthy. !!! tip "Design principle" A well-made EAA should look like a QEAA in its technical implementation, even if it does not carry the legal weight of one. --- ## The Rulebook Concept Every EAA provider must provide a **rulebook** (also called a credential scheme) that defines how the credential works. The rulebook serves as: - A **technical specification** for the credential's design - A **trust framework** for relying parties to evaluate the credential - A **governance document** defining issuer responsibilities ### Mandatory Rulebook Contents | Element | Description | | -------------------- | -------------------------------------------------------- | | `id` | Unique identifier for the rulebook | | `version` | Version number for change tracking | | `rulebookURI` | Canonical URL where the rulebook is published | | `supportedFormats` | Which credential formats are supported (SD-JWT VC, mDoc) | | `schemaURIs` | References to attribute schema definitions | | `trustedAuthorities` | Trust anchors for issuer verification | | `attestationLoA` | Level of assurance for the credential | | `bindingType` | How the credential is bound to the holder | ### Optional Rulebook Contents - Applicable regulations and legal basis - Issuer requirements and qualifications - Verification procedures for relying parties - Revocation policies and update frequencies - Contact information and support channels --- ## Validity Period Design The validity period balances security against usability: | Longer Validity | Shorter Validity | | --------------------------------- | --------------------------------- | | ✅ Better user experience | ✅ Lower risk of stale data | | ✅ Fewer reissuance interactions | ✅ Faster response to changes | | ❌ Higher risk of outdated data | ❌ More frequent user interaction | | ❌ Longer exposure if compromised | ❌ Higher operational load | ### Recommendations - **Maximum validity:** Typically ≤ 36 months - **Match underlying evidence:** If the source document has a validity period, align with it - **Enable updates:** Issuers should retain underlying data to support credential refresh - **Automate where possible:** Implement automated update processes to reduce user burden !!! info "Mental model" Treat EAAs as **credible digital copies** rather than permanent originals, unless you specifically implement long-term storage and validation capabilities. --- ## User Identification Requirements How strongly must the issuer identify the user before issuance? This depends on the credential's purpose and risk profile. ### Identification Levels | Level | Description | Use Cases | | ------------------ | ----------------------------------------- | -------------------------------------------- | | **None** | No identity verification required | Low-value credentials, loyalty cards | | **Account-based** | User has existing account with 2FA | Membership cards, subscriptions | | **High-assurance** | PID presentation or eIDAS Art. 24 process | Official documents, professional credentials | ### Documentation Requirements The rulebook must specify: - Which identification method is required - The trust level achieved by that method - Whether prior identification may be reused (and under what conditions) - How identification evidence is stored (if at all) --- ## Attribute Verification How does the issuer know the attributes are correct? ### Verification Approaches | Approach | Description | Trust Level | | -------------------- | ------------------------------------------------- | ----------- | | **Self-attested** | User provides information without verification | Low | | **Document-based** | User presents documents, issuer verifies | Medium | | **Authentic source** | Issuer retrieves data from authoritative registry | High | | **Issuer is source** | Issuer generated the data themselves | High | ### Recommendations for High-Trust EAAs - Use **authentic source verification** aligned with eIDAS-secure procedures - Document the verification method in the rulebook - Record the date of verification if reusing prior verification - Specify the trust level achieved --- ## Issuer Requirements Who may issue this EAA? The rulebook must define issuer qualifications. ### Possible Issuer Qualifications - Public authority status - Professional chamber membership - Industry license or certification - Contractual relationship with scheme operator - Technical certification (e.g., security audit) ### Trust Anchor Definition The rulebook must specify how relying parties verify the issuer: **Option A: Trust List** - Scheme operator maintains a list of authorized issuers - Relying parties check the list during verification - Dynamic: issuers can be added/removed **Option B: Root Certificate** - Scheme defines a root certificate - Issuer certificates chain to this root - Relying parties verify the certificate chain - More static, requires certificate lifecycle management --- ## Applicable Regulations The rulebook should reference specific regulations that influence the credential—but only where they add value. ### Include - Industry-specific regulations affecting issuance or use - Sector regulations defining required trust levels - Legal requirements for specific attribute types ### Exclude Generic regulations that apply universally: - GDPR (applies to all personal data processing) - NIS2 (applies to all relevant organizations) - eIDAS baseline (provides the ecosystem framework) These provide no additional guidance for the specific credential design. --- ## Signature Recommendations ### For Standard EAAs - Use certificates linked to the trust anchor defined in the rulebook - Follow current BSI/ENISA cryptographic recommendations - Use JAdES for SD-JWT VC credentials - Use CBAdES for ISO mDoc credentials ### For High-Trust EAAs - Use Qualified Electronic Signatures (QES) or Qualified Electronic Seals - This provides the same technical assurance as QEAA without the regulatory overhead - Relying parties gain confidence even without EU Trusted List inclusion ### Post-Quantum Considerations - Monitor NIST/BSI guidance on post-quantum algorithms - Plan migration paths for long-lived credentials - Consider hybrid approaches during transition period --- ## Revocation Recommendations ### When to Implement Revocation | Credential Characteristic | Revocation Needed? | | ----------------------------------- | ------------------ | | Validity < 7 days | Usually not | | Attributes may change | Yes | | Misuse risk is significant | Yes | | Credential represents access rights | Yes | ### Implementation Guidelines - Use **status lists** (not OCSP) to prevent usage tracking - Update lists at least daily for high-trust credentials - Provide clear revocation policies in the rulebook - Implement revocation within 24 hours for high-trust credentials !!! danger "Never revoke signing certificates" Revoking a signing certificate invalidates all credentials signed with it. Always use credential-level revocation. --- ## Checklist: Well-Made EAA Use this checklist to evaluate your EAA design: - [ ] Rulebook published with all mandatory fields - [ ] Credential format chosen based on use case (SD-JWT VC / mDoc) - [ ] Validity period appropriate for attribute volatility - [ ] User identification level matches credential risk - [ ] Attribute verification method documented - [ ] Issuer requirements clearly defined - [ ] Trust anchor specified (trust list or root certificate) - [ ] Signature follows BSI/ENISA recommendations - [ ] Revocation mechanism implemented (if applicable) - [ ] Anti-tracking measures considered (batch issuance, validity variation) - [ ] Selective disclosure enabled - [ ] Schema registered in attribute catalogue --- ## Electronic Attestations of Attributes (EAA) ## Overview Electronic Attestations of Attributes (EAA) are verifiable digital credentials that attest to attributes of a person or entity. Unlike the Personal Identification Data (PID), which is tightly regulated and issued only by designated government authorities, **EAAs can be issued by anyone**—public bodies, private companies, associations, or any organization with relevant data. This openness is by design: the EUDI Wallet ecosystem aims to enable a broad range of use cases, from government-issued qualifications to loyalty cards, membership credentials, and professional certifications. !!! warning "Issuance vs. acceptance" While anyone can technically issue an EAA, **relying parties decide which issuers they trust**. This decision is based on trust lists that authorize specific issuers for specific credential types. An EAA from an unauthorized issuer will be rejected during verification. For qualified EAAs (QEAAs), issuers must be listed on the EU Trusted List. For EAAs, scheme-specific trust lists define authorized issuers. See [Catalogue of Attestations](./catalog-of-attestations.md) for how credential types reference their trust anchors. !!! info "Key principle" EAAs are technically identical in structure. What distinguishes them is their **legal standing**, not their technical implementation. --- ## Examples of EAAs EAAs can represent virtually any verifiable attribute. Common categories include: | Category | Examples | | ------------------------ | --------------------------------------------------------------- | | **Professional** | Medical license, bar admission, pilot certificate, teacher ID | | **Educational** | University diploma, professional certification, training badge | | **Membership** | Club membership, association card, library card | | **Employment** | Employee badge, contractor credential, corporate access card | | **Health** | Vaccination record, organ donor status, disability attestation | | **Financial** | Bank account ownership, credit status, insurance coverage | | **Access & Entitlement** | Public transit pass, event ticket, building access credential | | **Commercial** | Loyalty card, subscription status, age verification for retail | --- ## Credentials Are Technically Uniform All credentials in the EUDI ecosystem—whether PID, EAA, QEAA, or PubEAA—share the same fundamental structure: | Component | Description | | --------------- | ------------------------------------------------------------- | | **Claims** | The actual attribute data (name, status, qualification, etc.) | | **Metadata** | Credential type, issuer identifier, validity period | | **Signature** | Cryptographic proof of issuer authenticity and data integrity | | **Key binding** | Mechanism linking the credential to the holder | The differences between credential types lie in: - **Who may issue** (anyone vs. qualified trust service providers vs. public authorities) - **Legal effect** (contractual vs. document-equivalent evidentiary value) - **Liability regime** (scheme-based vs. statutory) - **Trust anchor** (scheme governance vs. EU Trusted List) For guidance on choosing the appropriate credential type, see the [Trust Decision Guide](../../ecosystem-concepts/trust/decision-guide.md). --- ## eIDAS Is One Framework Among Others The eIDAS 2.0 regulation provides a comprehensive legal framework for digital credentials in Europe. However, it is not the only framework: - **ISO/IEC 18013-5** defines the mobile driving license (mDL) independently of eIDAS, with its own trust model based on VICAL (Vehicle Identification Certificate Authority List) - **W3C Verifiable Credentials** provide a format specification without prescribing a specific legal framework - **Domain-specific schemes** (banking, healthcare, education) may define their own trust rules The German EUDI Wallet ecosystem acknowledges this reality: - Credentials can be technically valid without being eIDAS-regulated - The mDL is a prime example: fully functional, legally recognized for driving purposes, but operating under ISO governance rather than eIDAS qualified status - Relying parties may accept credentials based on scheme trust rather than eIDAS trust lists !!! tip "Practical implication" When designing an EAA, first determine whether eIDAS qualification is actually required for your use case. For many scenarios, a well-designed EAA provides sufficient trust at lower cost and complexity. --- ## Section Overview This section provides comprehensive guidance for designing and implementing EAAs: | Document | Purpose | |-------------------------------------------------------| ------------------------------------------------------ | | [Credential Anatomy](./credential-anatomy.md) | Common mechanisms: signatures, revocation, key binding | | [Design Recommendations](./design-recommendations.md) | Best practices for well-made EAAs | | [Attribute Catalogues](./catalog-of-attestations.md) | Registry and discovery of credential types | For trust-related aspects (who to trust, which attestation type to use), see the [Trust section](../../ecosystem-concepts/trust/index.md). For technical protocol flows (OID4VCI, OID4VP), see the [Appendix: (Q)EAA Issuance and Presentation](../../archive/01-qeaa-issuance-and-presentation/index.md). --- ## Ecosystem Architecture(PID) ## Person Identification Data (PID) ### Design Decisions The PID is an attestation of person identification data and an electronic identity as defined in eIDAS. It can be used by a user to identify themselves at a Relying Party. This section discusses options to present a PID in a remote transaction (incl. authentication). The PID is an attestation of person identity data and an electronic identity as defined in eIDAS. It can be used by a user to identify themselves at a Relying Party. This section discusses options to present a PID in a remote transaction (incl. authentication). The following additional requirements apply to the PID solutions: - the PID and its complete lifecycle, including its issuance and presentation processes, shall fulfill the requirements defined for ==Level of Assurance High== - the PIDs in the German Wallet implementation and their use as an electronic identity shall be based on the German eID --- ## German PID Rulebook (PID-DE) Version 1.0.0 – Draft for Consultation ARF PID Rulebook Version used for this document: 1.6 This rulebook is defining requirements. The current status of implementation is described in the [Developer Guide](https://bmi.usercontent.opencode.de/eudi-wallet/developer-guide/rp/reference/pid_reference/). ## Introduction ### Purpose This Rulebook specifies how the [ARF PID Rulebook](https://github.com/eu-digital-identity-wallet/eudi-doc-attestation-rulebooks-catalog/blob/main/rulebooks/pid/pid-rulebook.md) and [PID Definition in CIR 2026/1731](https://eur-lex.europa.eu/legal-content/EN/ALL/?uri=CELEX%3A32026R1731) are applied within the German EUDI Wallet ecosystem. It defines national specifications required by German legislation, system architecture, and operational constraints. The document ensures full interoperability with the EU EUDI ecosystem while reflecting the decisions made within the German ecosystem: - There will be just one PID Provider in Germany. - The PID Provider is a backend service that translates from the German national eID scheme into the eIDAS/EUDI Wallet scheme by issuing a PID in the mdoc and in SD-JWT VC formats, suitable for eIDAS Level of Assurance (LoA) High. The Wallet receives issued credentials from the PID Provider and presents them to a Relying Party. ### What is the PID? In the context of the EUDI Wallet, Person Identification Data (PID) refers to the set of identity attributes that uniquely identify a natural person, such as the person's name, date of birth, and other identifying information. These attributes are issued by the PID Provider (PP) as a verifiable credential, encoded in a supported credential format such as ISO/IEC 18013-5 mdoc or SD-JWT VC. While the term PID is commonly used as shorthand for both the identity data and the issued credential, the term PID credential is technically more precise whenever referring to issuance, storage, presentation, or verification of the credential itself. ### Relationship to CIR 2026/1731 and ARF The [CIR 2026/1731](https://eur-lex.europa.eu/legal-content/EN/ALL/?uri=CELEX%3A32026R1731) remains the baseline reference. The ARF is adding more explanation referenced in this rulebook, but isn't a regulatory reference. This document provides German national specializations. In case of conflict, German national specializations prevail. ### Scope Applies to: - the German PID Provider, - German Wallet Providers, - Relying Parties in Germany, - Trust and governance entities. ## Attributes and Metadata !!! info "Important for Relying Parties." All string values in eIDs are stored uppercase, following [ICAO Doc 9303](https://www.icao.int/sites/default/files/publications/DocSeries/9303_p3_cons_en.pdf) for machine readable travel documents. It uses ISO/IEC 8859-1, following [BSI TR-03110 Part 3 D.2.1.4](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/BSI_TR-03110_Part-3-V2_2.pdf?__blob=publicationFile&v=1). This also means that letters like "Ö" (ISO/IEC 8859-1 0xD6) are used and not replaced by "OE". One main component of the PID Provider is the connection to an eID-Server according to [BSI TR-03130](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/Technische-Richtlinien/TR-nach-Thema-sortiert/tr03130/TR-03130_node.html) that manages an eID authorization certificate that is allowed to request the relevant attributes according to the PID specification of eIDAS. The eID-Client reads the identity data from the German eID Card or the German electronic Residence Permit, sends it to the eID-Server that validates the data. The second main component of the PID Provider is a service that creates the credential in mdoc or SD-JWT format. This includes the creation of a digital signature over the identity data read by the eID-Server. The signature recognized as the PID attestation under eIDAS by Relying Parties and must fulfill eIDAS LoA high. Hence, the respective key material and access to the key material must be stored and managed in a way to resist attackers with high attack potential. ### Mandatory attributes as specified in CIR 2026/1731 The full list of mandatory attributes specified in [CIR 2026/1731 Annex 1 Table 1](https://eur-lex.europa.eu/legal-content/EN/ALL/?uri=CELEX%3A32026R1731) is supported (apart from the portrait initially). German eIDs issued before November 2019 do not contain any information on nationality, so nationality is therefore assigned automatically as "DE" in case of a german eID Card. | Annex 1, Table 1 Data Identifier | BSI TR-03130 eID attribute | PID-Format: SD-JWT VC / ISO 18013-5 mdoc | | ------------------------------------------ | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | family_name | FamilyNames | string / tstr | | given_name | GivenNames | string / tstr | | birth_date | DateOfBirth | string, ISO 8601-1, YYYY-MM-DD format / full-date - year always set - eID values 00 for month as well as day are possible - they become converted to the maximum possible value which replace the 00, e.g. 31st of December, to fulfil RFC 3339 - if just month or day are 00, they are set to the maximum, e.g. 31 in January, or 12 for 00 month - base format is casted | | birth_place | PlaceOfBirth | JSON object / place_of_birth | | nationality | Nationality | array of strings / [+ tstr] - German PID contains just one item - ISO 3166-1 country code as alpha-2 string - "QU" when nationality is unknown - "QS" when person does not hold a nationality - see [German mapping rules for country codes](#german-mapping-rules-for-country-codes) | | portrait | | currently not included in the German PID | ### Optional attributes as specified in CIR 2026/1731 | Annex 1, Table 2 Data Identifier | BSI TR-03130 eID attribute | PID-Format: SD-JWT VC / ISO 18013-5 mdoc | | ------------------------------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------- | | resident_address | not available | not included in the German PID | | resident_country | PlaceOfResidence.Country | string / tstr | | resident_state | PlaceOfResidence.State | string / tstr | | resident_city | PlaceOfResidence.City | string / tstr | | resident_postal_code | PlaceOfResidence.ZipCode | string / tstr | | resident_street | PlaceOfResidence.Street | string / tstr | | personal_administrative_number | not available | not included in the German PID | | family_name_birth | not available | not included in the German PID | | given_name_birth | not available | not included in the German PID | | sex | not available | not included in the German PID | | email_address | not available | not included in the German PID | | mobile_phone_number | not available | not included in the German PID | The German eID may contain a field NoPlaceInfo in case the issuing authority could not verify the address. The attributes resident_country, resident_state, resident_city, resident_postal_code and resident_street will be an empty string in this case. ### Additional national attributes of German PID Included in the national namespace section "eu.europa.ec.eudi.pid.de.1" for ISO mdoc. !!! note "Info" The following attributes MAY remain unpopulated. If an attribute is not populated and of type string/tstr, the corresponding claim SHALL be an empty string. | Data identifier | BSI TR-03130 eID attribute | PID-Format: SD-JWT VC / ISO 18013-5 mdoc | |-----------------------------------------------------------------------|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | source_document_type | DocumentType | string / tstr; "ID" = german eID, can also be "AR", "AS" or "AF" for Residence Permit | | age_equal_or_over.NN (sd-jwt), age_over_NN (mdoc) | AgeVerificationRequestType | Array of key-value-pairs, values are boolean / bool - NN is defined as age group. - Age groups are 12, 14, 16, 18, 21 and 65 - Example: age_equal_or_over.12 (sd-jwt) or age_over_12 (mdoc) | | academic_title | AcademicTitle | string / tstr | | birth_name | BirthName | string / tstr - field is used as the base document may contain given name or familiy name at birth or a combination of both with any marker to divide - see [BSI TR 03130-1 Chapter 5.5.6](https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03130/TR-03130_TR-eID-Server_Part1.pdf?__blob=publicationFile&v=3) | | raw_eid_birth_date | DateOfBirth | string / tstr - containing the birth-date from the eID in the format yyyy-mm-dd, may contain 00 values if set in the eID for month, day or both - purpose is to clarify if there is a difference between the interoperable and the eID birth date | The age is calculated at the moment the PID-credential is issued. Usage of the age_equal_or_over.NN/age_over_NN groups shall reflect this fact. These claims only guarantee that the holder of the PID is above a certain age. If a claim is false, it can not be deducted that the holder is below a certain age. Wallet users shall request the issuance of a new batch of PIDs, when their age has changed regarding these age-groups. ### Metadata as specified in CIR 2026/1731 | Annex 1, Table 5 Data Identifier | BSI TR-03130 eID attribute | Presence | PID-Format: SD-JWT VC / ISO 18013-5 mdoc | |----------------------------------|--------------------------------------|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | issuing_authority | not available, fixed value "DE" used | mandatory | string / tstr | | issuing_country | IssuingState, always "DE" | mandatory | string / tstr | | expiry_date | not used | optional | not included in the German PID | | document_number | not available | optional | not included in the German PID | | issuing_jurisdiction | not available | optional | not included in the German PID | | issuance_date | not available | optional | not included in the German PID | | status | not available | mandatory | Reference to Token Status List in format of ([IETF OAuth TSL](https://datatracker.ietf.org/doc/draft-ietf-oauth-status-list/))Shards and sizes are depending on the change frequency of status. Always included in the German PID | Note that expiry_date as defined in the CIR is the administrative validity period (e.g., validity of the underlying eID), not the technical validity period of the PID. The technical validity period of the PID is expressed via credential format specific attributes (nbf, exp for SD-JWT VC and validFrom, validUntil for mdoc). ## Formatting, encoding and mapping rules ### Formatting Format follows CIR 2026/1731, [Annex 1](https://eur-lex.europa.eu/eli/reg_impl/2026/1731/oj/eng#anx_1) which defines the two possible formats of a PID based on ISO/IEC 18013-5 (Personal identification — ISO-compliant driving licence — Part5) as well as SD-JWT VC. #### German format specializations for ISO/IEC 18013-5 / mdoc | Attribute identifier | Encodingformat ISO mdoc | Comments | | -------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | birth_date | full-date (rfc3339) | zero values in German eID for month and day are mapped to the possible maximum (e.g. 12 for month).see [Mandatory attributes as specified in CIR 2026/1731](#mandatory-attributes-as-specified-in-cir-20261731) | | place_of_birth | CBOR Major Type 5 (map) / tobject | Just locality can be present. Can be an address string. If value in eID is "NoPlaceInfo", locality will be empty string this case, but shall be set. | | nationality | [+ tstr] (rfc8610) | one or more alpha-2 country codes as specified in ISO 3166-1, mapped from eID field with pattern "[A-Z]{1,3}"see [German mapping rules for country codes](#german-mapping-rules-for-country-codes) | | resident_country | tstr (rfc8610) | alpha-2 country codes as specified in ISO 3166-1, mapped from eID field with pattern "[A-Z]{1,3}" see [German mapping rules for country codes](#german-mapping-rules-for-country-codes) | #### German format specializations for SD-JWT VC-based encoding | Attribute identifier | Encodingformat SD-JWT VC | Comments | | -------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | | birthdate | string, ISO 8601-1 [ISO8601‑1] YYYY-MM-DD format | zero values in German eID for month and day are mapped to the maximum possible value in context | | place_of_birth | JSON object | Section 4.1 of [EKYC]; Just locality will be present. If FreetextPlace comes from eID, this is placed as locality. If value in eID is "NoPlaceInfo", locality will be empty, but shall be set. | | nationalities | array of strings | Section 4.1 of [EKYC]; using alpha-2 country codes as defined in Section 2.2, mapped from eID field with pattern "[A-Z]{1,3}"see [German mapping rules for country codes](#german-mapping-rules-for-country-codes) | | address.country | string | alpha-2 country codes as specified in ISO 3166-1, mapped from eID field with pattern "[A-Z]{1,3}"see [German mapping rules for country codes](#german-mapping-rules-for-country-codes) | Note that the claims vct, vct#integrity, cnf and metadata cannot be issued as selectively disclosable claims. ### Encoding Encoding shall be UTF-8, full unicode range in both cases, ISO/IEC mdoc and SD-JWT VC. Regarding [CIR 2026/1731 Annex 1, Chapter 4.1](https://eur-lex.europa.eu/legal-content/EN/ALL/?uri=CELEX%3A32026R1731) tstr should have a maximum length of 150 characters. With this rulebook it is requested, that all strings shall have a maximum length of 150 characters in any format, ISO/IEC mdoc as well as SD-JWT VC. ### Mapping As there are mappings between data identifiers following CIR 2026/1731, ISO/IEC 18013-5 and SD-JWT VC the table below highlights and explains these mapping. | CIR 2026/1731 data identifier | ISO/IEC 18013-5 attribute identifier | SD-JWT VC attribute identifier | | ----------------------------- | ------------------------------------ | ------------------------------ | | family_name | family_name | family_name | | given_name | given_name | given_name | | birth_date | birth_date | birthdate | | birth_place | place_of_birth | place_of_birth | | nationality | nationality | nationalities | | resident_country | resident_country | address.country | | resident_state | resident_state | address.region | | resident_city | resident_city | address.locality | | resident_postal_code | resident_postal_code | address.postal_code | | resident_street | resident_street | address.street_address | | issuing_authority | issuing_authority | issuing_authority | | issuing_country | issuing_country | issuing_country | | | age_over_NN | age_equal_or_over | #### German mapping rules for country codes German eIDs may contain country or nationality codes that are reserved for national use and are therefore not defined by ISO 3166. These user-defined codes are permitted within the German eID ecosystem and can be returned by an eID server compliant with BSI TR-03110 during the authentication process. Applications consuming eID data should therefore not assume that all returned country codes are valid ISO values. For example, the code XK is used to represent Kosovo, although it is not officially assigned in ISO 3166-1. The German [XRepository country code list](https://www.xrepository.de/details/urn:xoev-de:kosit:codeliste:country-codes_8#version) extends the ISO code set with these nationally defined codes and should be used to correctly interpret such values. #### German mapping rules for ISO/IEC 18013-5 / mdoc Mapping of German eID data into mdoc compatible values | Attribute identifier | mdoc format | eID format | Mapping | | -------------------- | --------------------------------------------------------- | ---------------------------------------------------------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | birth_date | tdate (rfc8610) or full-date (rfc3339) format: YYYY-MM-DD | DateOfBirth string: pattern [0-9-]{10}, format: yyyy-mm-dd | date conversion, see [Mandatory attributes as specified in CIR 2026/1731](#mandatory-attributes-as-specified-in-cir-20261731) | | place_of_birth | CBOR Major Type 5 (map) / tobject | PlaceOfBirth (sequence) | string conversion from sequence elements of eID to string which will be placed as attribute locality. If value in eID is "NoPlaceInfo", locality will be empty string this case. | | nationality | [+ tstr] (rfc8610) | Nationality (string) pattern: [A-Z]{1,3} | Mapping from ICAO Country codes to alpha-2 country codes as specified in ISO 3166-1. - "QU" when nationality is unknown - "QS" when person does not hold a nationality. - see [German mapping rules for country codes](#german-mapping-rules-for-country-codes) | | resident_country | tstr (rfc8610) pattern: [A-Z]{2} | PlaceOfResidence.Country (string: pattern [A-Z ]{1,3}) | Mapping from ICAO Country codes to alpha-2 country codes as specified in ISO 3166-1. - ISO 3166-1 country code as alpha-2 string - see [German mapping rules for country codes](#german-mapping-rules-for-country-codes) | | issuing_country | tstr (rfc8610) pattern: [A-Z]{2} | IssuingState (string: pattern [A-Z]{1,3}) | Always "DE" for German PID | #### German mapping rules for SD-JWT VC Mapping of German eID data into SD-JWT VC compatible values | Attribute identifier | SD-JWT VC format | eID format | Mapping | |----------------------|--------------------------------------------------|------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | birthdate | string, ISO 8601-1 [ISO8601‑1] format YYYY-MM-DD | DateOfBirth string: pattern [0-9-]{10}, format: yyyy-mm-dd | date conversion, see [Mandatory attributes as specified in CIR 2026/1731](#mandatory-attributes-as-specified-in-cir-20261731) | | place_of_birth | JSON object | PlaceOfBirth (sequence) | string conversion from sequence elements of eID to string which will be placed as attribute locality. If value in eID is "NoPlaceInfo", locality will be empty string this case. | | nationalities | array of strings | Nationality (string) pattern: [A-Z]{1,3} | Mapping from ICAO Country codes to alpha-2 country codes as specified in ISO 3166-1. Codes beginning with X, e.g. XK for Kosovo, are not officially recognized. However, they are unofficial codes in ISO 3166-1. See [German mapping rules for country codes](#german-mapping-rules-for-country-codes). | | address.country | string | PlaceOfResidence.Country (string: pattern [A-Z]{1,3}) | Mapping from ICAO Country codes to alpha-2 country codes as specified in ISO 3166-1. Codes beginning with X, e.g. XK for Kosovo, are not officially recognized. However, they are unofficial codes in ISO 3166-1. See [German mapping rules for country codes](#german-mapping-rules-for-country-codes). | | issuing_country | string | IssuingState (string: pattern [A-Z]{1,3}} | Mapping from ICAO Country codes to alpha-2 country codes as specified in ISO 3166-1 | ### Namespaces #### ISO/IEC 18013-5 / mdoc In accordance with CIR 2026/1731, Annex 1 the mdoc-based German PID uses the DocType “eu.europa.ec.eudi.pid.1” and the two NameSpace data elements “eu.europa.ec.eudi.pid.1” and “eu.europa.ec.eudi.pid.de.1”. Specific German attributes are contained in the namespace “eu.europa.ec.eudi.pid.de.1”. #### SD-JWT VC In accordance with CIR 2026/1731, Annex 1 the SD-JWT VC based German PID uses the namespace urn:eudi:pid:de:1, compact serialized format is used. ## Examples Note that the following examples are non-normative and are missing some metadata/technical values like the status entries. ### ISO/IEC mdoc ```yaml { "DocType": "eu.europa.ec.eudi.pid.1", # metadata that would define this as a PID (namespace "eu.europa.ec.eudi.pid.1"), includes data of the "eu.europa.ec.eudi.pid.de.1" namespace too "issuerSigned": { "NameSpaces": { "eu.europa.ec.eudi.pid.1": { ## Mandatory attributes specified in CIR 2026/1731 "family_name": { "digestID": 0, "random": "h'1A2B3C4D5E6F708192A3B4C5D6E7F809'", "elementIdentifier": "family_name", "elementValue": "MUSTERMANN" }, "given_name": { "digestID": 1, "random": "h'2B3C4D5E6F708192A3B4C5D6E7F8091A'", "elementIdentifier": "given_name", "elementValue": "ERIKA" }, "birth_date": { "digestID": 2, "random": "h'3C4D5E6F708192A3B4C5D6E7F8091A2B'", "elementIdentifier": "birth_date", "elementValue": "1983-08-12" }, "place_of_birth": { "digestID": 3, "random": "h'4D5E6F708192A3B4C5D6E7F8091A2B3C'", "elementIdentifier": "place_of_birth", "elementValue": { "locality": "BERLIN" } }, "nationality": { "digestID": 4, "random": "h'5E6F708192A3B4C5D6E7F8091A2B3C4D'", "elementIdentifier": "nationality", "elementValue": ["DE"] # "DE" for german eID cards issued before Nov. 2019, otherwise eID based data }, ## Optional attributes specified in CIR 2026/1731 "resident_country": { "digestID": 5, "random": "h'6408192A3B4C5D6C87F8091A2B3C4D5E'", "elementIdentifier": "resident_country", "elementValue": "DE" }, "resident_state": { "digestID": 6, "random": "h'6FC408192A3B4C5D6E7F8091A2B3C4F3'", "elementIdentifier": "resident_state", "elementValue": "NORDRHEIN-WESTFALEN" }, "resident_city": { "digestID": 7, "random": "h'7472A3B4C5D6E7F8091A2B3C4D5E6B3A'", "elementIdentifier": "resident_city", "elementValue": "KÖLN" }, "resident_postal_code": { "digestID": 8, "random": "h'7522A3B4C5D6E7F8091A2B3C46B3AD5E'", "elementIdentifier": "resident_postal_code", "elementValue": "51147" }, "resident_street":{ "digestID": 9, "random": "h'6E7F7472A3B4C5D8091D5E6B3AA2B3C4'", "elementIdentifier": "resident_street", "elementValue": "HEIDESTRASSE 17" # CIR 2026/1731 now offically request the house number as part of the street }, "issuing_authority": { "digestID": 12, "random": "h'A0B3C4D5E6F708192A3B4C5D6E7F8091'", "elementIdentifier": "issuing_authority", "elementValue": "DE" # value to expect in German PID }, "issuing_country": { "digestID": 13, "random": "h'B0C4D5E6F708192A3B4C5D6E7F8091A2'", "elementIdentifier": "issuing_country", "elementValue": "DE" # ISO 3166-1 alpha-2 country code derived from ICAO country code used for eID Card } }, "eu.europa.ec.eudi.pid.de.1": { ## Additional attributes "birth_name": { "digestID": 14, "random": "h'E1D5E6F708192A3B4C5D6E7AA091A2B3'", "elementIdentifier": "birth_name", "elementValue": "GABLER" # may contain both, given and family name at birth, see notes at "Additional national attributes of German PID" }, "source_document_type": { "digestID": 15, "random": "h'C0D5E6F708192A3B4C5D6E7F8091A2B3'", "elementIdentifier": "source_document_type", "elementValue": "ID" # "ID" = german eID, can also be "AR", "AS" or "AF" for Residence Permit }, "age_over_12": { "digestID": 16, "random": "h'D0E6F708192A3B4C5D6E7F8091A2B3C4'", "elementIdentifier": "age_over_12", "elementValue": true }, "age_over_14": { "digestID": 17, "random": "h'A3F1C8D209B4E6F7812D3C5A9E0F47B2'", "elementIdentifier": "age_over_14", "elementValue": true }, "age_over_16": { "digestID": 18, "random": "h'5D8E0A91B2C3F4E60718A9BC3D4F5E60'", "elementIdentifier": "age_over_16", "elementValue": true }, "age_over_18": { "digestID": 19, "random": "h'9B0E7C4A12F3D568A1C2E4F907B8D6E3'", "elementIdentifier": "age_over_18", "elementValue": true }, "age_over_21": { "digestID": 20, "random": "h'C4A1F9037E5B2D8C190AF6E4B3D27589'", "elementIdentifier": "age_over_21", "elementValue": true }, "age_over_65": { "digestID": 21, "random": "h'F7D2A9C403B1E6D5809C4E1F2A7B3D65'", "elementIdentifier": "age_over_65", "elementValue": false }, "academic_title": { "digestID": 22, "random": "h'4f3be788e225ab8a323b18efd4b1449e'", "elementIdentifier": "academic_title", "elementValue": "" }, "raw_eid_birth_date": { "digestID": 23, "random": "h'81e95c0ba1158ea2b651f797db158b7b'", "elementIdentifier": "raw_eid_birth_date", "elementValue": "1983-08-12" } } }, "issuerAuth": {} }, "deviceSigned": {} } ``` ### SD-JWT VC ```yaml { ## Base data (SD-JWT VC DM) "vct": "urn:eudi:pid:de:1", ## Mandatory attributes specified in CIR 2026/1731 "family_name": "MUSTERMANN", "given_name": "ERIKA", "birthdate": "1983-08-12", "place_of_birth": { "locality": "BERLIN" }, # may be containing a full address when separate values are not available "nationalities": ["DE"], # "DE" for german eID cards issued before Nov. 2019, otherwise eID based data ## Optional attributes specified in CIR 2026/1731 "address": { "country": "DE", # ISO 3166-1 alpha-2 country code derived from ICAO country code of eID Card "region": "NORDRHEIN-WESTFALEN", # State "locality": "KÖLN", # City "postal_code": "51147", # ZipCode "street_address": "HEIDESTRASSE 17" # Street and house number }, "issuing_authority": "DE", # not available in german eID card but mandatory, that's why the value out of issuing country is used (DE) "issuing_country": "DE", # ISO 3166-1 alpha-2 country code derived from ICAO country code used for eID Card ## Additional attributes "birth_name": "GABLER", # may be empty, may contain both, given and family name at birth "source_document_type": "ID", # "ID" = german eID, can also be "AR", "AS" or "AF" for Residence Permit "age_equal_or_over": { "12": true, "14": true, "16": true, "18": true, "21": true, "65": false }, # see notes at the end of chapter "Additional national attributes of German PID" "academic_title": "", "raw_eid_birth_date": "1983-08-12", # example for key binding (SD-JWT VC DM) "cnf": { "jwk": { "kty": "EC", "crv": "P-256", "x": "52aDI_ur05n1f_p3jiYGUU82oKZr3m4LsAErM536crQ", "y": "ckhZ-KQ5aXNL91R8Eufg1aOf8Z5pZJnIvuCzNGfdnzo" } } } ``` ## Operational notes ### Issuance PID issuance in Germany will be based on eID card. The issuance will be executed by only one PID provider in Germany. PIDs will be issued in batches of separate PIDs within one credential issuance request and every PID is used only once to avoid linkability. When the PIDs have run out (or before, to allow for offline cases), a new batch is issued based on the [Refresh Token](./runtime-views.md#issuance-of-a-refresh-token-used-as-a-seed-credential) used as seed credential. See also [German National EUDI Wallet Architecture Documentation on Refresh Token](https://bmi.usercontent.opencode.de/eudi-wallet/wallet-development-documentation-public/latest/architecture-concept/03-data-flows/22-pid-presentation.html?pk_vid=18295cebac426cfe178551147641b4a0#batch-credential-refresh). The lifetime of the Refresh Token is 2 years. The lifetime of PIDs is 2 months, after this period new PIDs have to be requested with a valid Refresh Token. To obtain a newly issued Refresh Token, the eID shall be presented again after the period corresponding to (**`Refresh Token` lifetime − `PID` lifetime**) has elapsed. For example, if the Refresh Token lifetime is 2 years and the PID lifetime is 2 months, the eID shall be presented again after 22 months. ### Renewal The PID must be renewed by the owners themselves in the event of changes to the eID, e.g., name change or new eID. Following 10a (4) PAuswG PID shall not be used furthermore in case that data has changed. There is no automatic renewal. ### Revocation Revocation is done by [IETF Token Status Lists](../../../ecosystem-concepts/trust/status-management/#status-list). ## Legal and regulatory references - International: [ICAO 9303](https://www2023.icao.int/publications/Documents/9303_p3_cons_en.pdf) - EU: [eIDAS](https://eur-lex.europa.eu/eli/reg/2024/1183/oj/eng), [ARF PID Rulebook version 1.6](https://github.com/eu-digital-identity-wallet/eudi-doc-attestation-rulebooks-catalog/blob/main/rulebooks/pid/pid-rulebook.md), [CIR 2026/1731](https://eur-lex.europa.eu/eli/reg_impl/2026/1731/oj/eng) and Implementing Acts. - Germany: Relevant BSI technical guidelines ([TR-03130](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/Technische-Richtlinien/TR-nach-Thema-sortiert/tr03130/TR-03130_node.html), [TR-03110](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/Technische-Richtlinien/TR-nach-Thema-sortiert/tr03110/TR-03110_node.html)) and may be upcoming BSI Regulations regarding the EUDI Wallet Implementation in Germany. --- ## Ecosystem Architecture(7) ## Person Identification Data (PID) ### Runtime Views #### Basic Idea In this flow, long-lived, digitally signed PID credentials in ISO mdoc and IETF SD-JWT VC formats are issued to the Wallet Instance utilizing the OpenID4VCI protocol. During the issuance, the user is authenticated using the eID card, so when these PID credentials are presented to the Relying Parties over OpenID4VP protocol, there is no need for the user to use physical eID card. This flow trusts using Wallet Backend to manage keys on behalf of the Wallet Instance, under the assumption that keys managed on the mobile device cannot be secured in a way that is appropriate for Level of Assurance High (unlike [Option C](https://bmi.usercontent.opencode.de/eudi-wallet/eidas-2.0-architekturkonzept/content/archive/flows/PID-IssuerSigned/)). To improve user experience and prevent the users from tapping an eID card every time a batch of Credentials needs to be refreshed and tapping an eID card as many times as there are Credentials in a batch, a **concept of Seed Credential** is introduced. A Seed Credential is used to acquire a set of single-use Batch Credentials from the Provider. The Wallet can then present these Batch Credentials to the Relying Parties. The user only needs to present the physical ID card once - to acquire the Seed Credential - instead of every presentation. Such Seed Credential is issued by a PID Provider to the Wallet as a **signed DPoP-bound refresh token** and can be stored for a longer period. The key from the wallet backend, that the refresh token is bound to, is stored and managed by an HSM in the wallet backend (WSCD) instead of the wallet device itself. Wallet Attestation PoP and DPoP Proof are bound to the keys managed by a wallet backend, but since they contain session specific information (audience and a nonce/session id) that should be known only to the wallet instance from a privacy perspective, to generate a signature, the wallet instance sends only a ready-to-be-signed hash to the wallet backend. Wallet Attestation PoP and DPoP Proof require key attestation for the keys that they are bound to. #### Cryptographic Keys ##### Prefixes | Prefix | Meaning | | --- | --- | | `wb_` | Wallet Backend | | `pp_` | PID Provider | | Prefix | Meaning | | --- | --- | | `rp_` | Relying Party | | `device_` | Wallet Instance | ##### Long-Term keys | Key | Meaning | | ------------------------------------- | -------------- | | $device\_pub, device\_priv$ | Wallet Instance generates locally managed key pair which is used to bind the PIN proof to the device. | | $pin\_salt$ | Wallet Instance generates AES key which is used to derive the `pin_derived_eph_priv` used as PoP of Wallet PIN. | | $wb\_attestation\_pub_wa, wb\_attestation\_priv_wa$$wb\_attestation\_pub_kbp, wb\_attestation\_priv_kbp$$wb\_attestation\_pub_ks, wb\_attestation\_priv_ks$$wb\_attestation\_pub_kd, wb\_attestation\_priv_kd$ | Wallet Backend has key pairs with postfixes which are each used: - to sign wallet instance's wallet attestations: `_wa` - to sign key attestation for the key that a PID is bound to: `_kbp`- to sign key attestation for the key that a seed credential is bound to: `_ks`- to sign key attestation for the key that a DPoP Proof is bound to: `_kd`. | | $wb\_device\_pub, wb\_device\_priv$ | Wallet Backend generates the key pair which is used to sign proof of possession of wallet attestation. | | $wb\_dpop\_pub, wb\_dpop\_priv$ | Wallet Backend generates the HSM bound key pair which is used to generate DPoP proof (a key to which refresh token used as a seed credential is bound to). | | $pp\_pub, pp\_priv$ | PID Provider has the HSM bound long-term key pair to sign over the issued Credential and to sign over the Refresh Token JWT. | | $pp\_data$ | PID Provider has this symmetric long-term key which is used to encrypt eID data inside the refresh token. | | $rp\_pub, rp\_priv$ | Relying Party has this long-term key pair which is used to sign over the authorization request, authenticating its contents. | !!! info "Note (not normative for Wallet implementations)" The following sequence diagrams include, among other things, user interactions with the Wallet. These interactions are not normative; only the depicted data flows are normative. #### Issuance of a Refresh Token used as a Seed Credential ##### Sequence Diagram [-> Visual Example of the User Journey: PID Issuance - Issuer Signed - Cloud](./figures/PID-IssuerSigned-cloud-issuance.png) ```plantuml @startuml 'color for screen reference !define GREEN #dfd !define TLSGREEN #118888 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 'legend skinparam legend { backgroundColor #GhostWhite entrySeparator #GhostWhite } autonumber "(000)" participant u order 1[ **PID Holder** ---- ""PIN: (//user_pin//)"" ] participant w order 3[ **User's EUDI Wallet Instance\** (eID-Client) ---- ""Device Key: (//device_pub//, //device_priv//)"" ""Wallet Attestation bound to //wb_device_pub//"" ""PIN Salt: //pin_salt//"" ] participant wb order 2[ **User's EUDI Wallet Backend** ---- ""Long-term Key: (//wb_device_pub//, //wb_device_priv//)"" ] participant i order 4[ **PID Provider** (eService+eID Server) ---- ""Long-term Key: (//pp_pub//, //pp_priv//)"" ""eID data encryption Key: (//pp_data//)"" ] u --> w : open wallet, unlock wallet hnote over w GREEN: Screen: launch_wallet hnote over w GREEN: Screen: unlock_wallet u --> w : request issuance of PID hnote over w GREEN: Screen: credential_catalog note over w,i: PID Issuer and EUDI Wallet have inherent trust relationship, metadata may be pre-configured or retrieved w -> i : tls() HTTP POST pid_issuer_session_id i -> i : generate and store pid_issuer_session_id i -> w : tls() HTTP 200 hnote over w GREEN: Screen: consent_add_credential group check pin w -> wb: tls() HTTP POST wallet_backend_session_id wb -> wb : generate and store wallet_backend_session_id wb -> w : tls() HTTP 200 u --> w: enter Wallet PIN hnote over w GREEN: Screen: wallet_pin w -> w : derive key pair (//pin_derived_eph_pub//, //pin_derived_eph_priv//) from KDF(Wallet PIN, encrypt_AES(//pin_salt//, Wallet PIN)) w -> w : generate PoP for pin derived ephemeral key - sign(wallet_backend_session_id | //device_pub//)//pin_derived_eph_priv// w -> w : generate PoP for wallet app's key - sign(wallet_backend_session_id | //pin_derived_eph_pub//)//device_priv// note right: proof must be built from both the device key and the key derived from the user PIN, might require new proof type group Remote HSM w -> w: prepare wallet attestation POP with audience, expiration time and pid_issuer_session_id w -> w: hash wallet attestation PoP w -> wb : tls() HTTP POST wb -> wb: load instance information for UUID note left: Instance Information: retry counter, //pin_derived_eph_pub//, //device_pub//, security relevant device attributes wb -> wb: check user pin retry note right: request would be refused in case of locked pin wb -> wb: check security of device against Vulnerability Management information note left: PIN will not be validated if device is known to be insecure wb -> wb: check signatures note right: user pin retry counter would be increased in case of failed pin signature check, user pin would be locked after threshold is exeeded wb -> wb: sign hash of wallet attestation PoP with //wb_device_priv// wb -> w : tls() HTTP 200 end w -> w : assemble wallet attestation PoP end w -> i : tls() HTTP POST PAR (PKCE code_challenge, Wallet Attestation + PoP, client_id) i -> i : verify wallet attestation & PoP \ncheck Wallet Provider solution status on trust list i -> w : tls() HTTP 200 request_uri note right : Attestation guarantees with high certainty that Wallet is trustworthy and not manipulated w -> i : tls() HTTP GET hnote over w GREEN: Screen: eid_start group Read eID or Smart eID acc. to BSI TR-03130 i --> w : tls() HTTP 200 starting the eID Process w <-> i : eID Process u <--> w : hnote over w GREEN: Screen: eid_pin w <-> i : eID Process w -> i : tls() HTTP GET finishing the eID process with refreshUrl hnote over w GREEN: Screen: eid_nfc_data end i -> w : tls() HTTP 302 group Generate initial DPoP nonce w -> w : generate placeholder DPoP proof with generic (not HSM-bound) key pair w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> w : tls() HTTP 400 note left : The Wallet should check at this point, whether the Token Endpoint delivered the expected error and nonce. If not, this needs to be handled (retry or abort gracefully). w -> w: store dpop_nonce end 'generate DPoP proof with dev key and key attestation for that key group Remote HSM w -> w: prepare DPoP-proof JWT for HSM bound key incl. dpop_nonce w -> w: hash(DPoP-proof JWT for HSM bound key) w -> wb: tls() HTTP POST wb -> wb: check wallet_backend_session_id wb -> wb: sign hash of PoP with //wb_dpop_priv// (associated with UUID & Issuer_ID) wb -> w: tls() HTTP 200 w -> w: assemble DPoP-proof JWT for HSM bound key with signature end w -> i : tls() HTTP POST i -> i : lookup authorization code\n verify PKCE challenge\n verify DPoP proof\n verify key attestation for DPoP proof i -> i : create refresh token bound to //wb_dpop_priv// in JWT format with\n eID data symmetrically encrypted with //pp_data// and its expiration date\n and sign the refresh token JWT with //pp_priv// i -> i: generate and store dpop_nonce i -> i : generate Token Response with access and refresh token DPoP bound to //wb_dpop_priv// and fresh dpop_nonce i -> w : tls() HTTP 200 note left: The access token and the refresh token are both bound to the same key. w -> w : store DPoP bound access and refresh token w -> w: store dpop_nonce hnote over w GREEN: Screen: success hnote over w GREEN: Screen: home legend left <#GhostWhite,#GhostWhite>| |= __Legend__ | || Visual Example of the User Journey reference| || TLS (Transport Layer Security)| endlegend @enduml ``` ##### Step-by-Step Description | No | Description | | --- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 001 | The user opens and unlocks the Wallet. | | 002 | The user browses through the pre-configured credential catalogue and chooses to request a PID. | | 003 | The Wallet requests a fresh pid_issuer_session_id from the PID Provider. | | 004 | The PID Provider generates a fresh pid_issuer_session_id linked to the issuance session. | | 005 | The PID Provider returns the pid_issuer_session_id to the Wallet. | | 006 | The Wallet obtains fresh wallet_backend_session_id from the Wallet Backend's session endpoint. | | 007 | Part of the above-mentioned module. | | 008 | Part of the above-mentioned module. | | 009 | The User enters the Wallet PIN. | | 010 | The Wallet proves possession of the Wallet PIN {See "Wallet proving possession of the PIN" module for a detailed description of the steps). | | 011 | Part of the above-mentioned module. | | 012 | Part of the above-mentioned module. | | 013 | The Wallet prepares a Wallet Attestation PoP containing audience, expiration time and pid_issuer_session_id | | 014 | The Wallet hashes the prepared Wallet Attestation PoP. | | 015 | The Wallet sends a request to the Wallet Backend containing UUID & Issuer_ID, PoP for *pin_derived_eph_priv*, PoP for *device_priv* and hash of the Wallet Attestation PoP | | 016 | The Wallet Backend checks Wallet Instance. | | 017 | Part of the above-mentioned module. | | 018 | Part of the above-mentioned module. | | 019 | The Wallet Backend validates the PoP for *pin_derived_eph_pub* and *device_pub*. | | 020 | The Wallet Backend signs the hash of Wallet Attestation PoP with *wb_device_priv*. | | 021 | The Wallet Backend returns the request to the Wallet containing signed hash of Wallet Attestation PoP. | | 022 | The Wallet assembles the Wallet Attestation PoP using the signature received in a previous step. | | 023 | The Wallet sends the Pushed Authorization Request to the PID Provider, containing the Wallet Provider's client_id, authorization_details for PID, a PKCE code_challenge and a wallet attestation and proof of possession. | | 024 | The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list. | | 025 | The PID Provider returns a `request_uri` that is bound to the Pushed Authorization Request. | | 026 | The Wallet sends the Authorization Request; containing the PAR `request_uri`. | | 027 | The PID Provider responds with the first step to start the eID process with the Wallet, e.g. the tcToken, to authenticate the user. | | 028 | Further communication is exchanged to perform the eID process. | | 029 | The user provides the eID PIN to the Wallet. | | 030 | Further communication is exchanged to perform the eID process. | | 031 | The eID process is finished and as a final step the Wallet sends a request to the PID Provider calling the refreshURL. From now on Wallet and PID Provider are using the TLS-PSK channel generated by the eID flow. | | 032 | The PID Provider responds to the Wallet with an Authorization Response containing the authorization code. | | 033 | The Wallet generates (and stores) a placeholder DPoP proof with a generic (not HSM-bound) keypair to trigger an error response from the Token endpoint necessary to retrieve the `dpop_nonce`. | | 034 | The Wallet sends a Token Request to the PID Provider; containing the placeholder DPoP proof. | | 035 | The PID Provider generates and stores a `dpop_nonce`. | | 036 | The PID Provider responds with the expected error "use_dpop_nonce" containing the `dpop_nonce` to be used from now in the DPoP nonce header. | | 037 | The Wallet extracts and stores the `dpop_nonce`. | | 038 | The Wallet now prepares the actual DPoP-proof JWT for the HSM-bound `wb_dpop_pub` including the `dpop_nonce` and `iat`. | | 039 | The Wallet hashes the DPoP proof. | | 040 | The Wallet sends a request to the Wallet Backend to sign the hash of the DPoP-proof for the HSM bound key containing the hash of the PoP for the HSM bound key and the `wallet_backend_session_id`. | | 041 | The Wallet Backend validates the `wallet_backend_session_id` and loads session context. | | 042 | The Wallet Backend signs the hash of the PoP for the HSM bound key with *wb_dpop_priv* (associated with UUID & Issuer_ID) from the HSM. | | 043 | The Wallet Backend returns the signed hash of the PoP for the HSM bound key to the Wallet. | | 044 | The Wallet assembles the DPoP-proof for the HSM bound key using the signature received in a previous step. | | 045 | The Wallet sends a Token Request to the PID Provider containing a DPoP Header with the DPoP-proof JWT incl. `wb_dpop_pub`, the authorization code from Authorization Response, the PKCE code_verifier matching the code_challenge from Authorization Request and the.key attestation for `wb_dpop_pub`. | | 046 | The PID Provider matches the code, verifies the PKCE `code_verifier` to the previously received `code_challenge` and verifies the DPoP proof. | | 047 | The PID Provider then generates an access token and a refresh token bound to the DPoP key *wb_dpop_priv* in JWT format, signed with *pp_priv* containing the eID data encrypted with *pp_data* and the expiration date of the refresh token. | | 048 | The PID Provider generates and stores a fresh `dpop_nonce`. | | 049 | The PID Provider generates a Token Response containing the DPoP-bound access token (bound to *wb_dpop_priv*), the DPoP-bound refresh token (bound to *wb_dpop_priv*), a c_nonce and a fresh `dpop_nonce` in the DPoP nonce header. | | 050 | The PID Provider sends the Token Response to the Wallet. | | 051 | The Wallet stores the access and the refresh token. | | 052 | The wallet stores the `dpop_nonce`. | #### Issuance of a Batch of PIDs ##### Sequence Diagram ```plantuml @startuml 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" participant u order 1[ **PID Holder** ---- ""PIN: (//user_pin//)"" ] participant w order 3[ **User's EUDI Wallet Instance\ (eID-Client)** ---- ""Device Key: (//device_pub//, //device_priv//)"" ""Wallet Attestation bound to //wb_device_pub//"" ""PIN Salt: //pin_salt//"" ] participant wb order 2[ **User's EUDI Wallet Backend** ---- ""Long-term Key: (//wb_attestation_pub//, //wb_attestation_priv//)"" ""Long-term Key: (//wb_device_pub//, //wb_device_priv//)"" ] participant i order 4[ **PID Provider (eService+eID Server)** ---- ""Long-term Key: (//pp_pub//, //pp_priv//)"" ""eID data encryption Key: (//pp_data//)"" ] u --> w : open wallet, unlock wallet u --> w : request issuance of PID Batch Credentials group check pin and generate batch keys w -> i : tls() HTTP POST pid_issuer_session_id i -> i : generate and store pid_issuer_session_id i -> w : tls() HTTP 200 w -> wb: tls() HTTP POST wallet_backend_session_id wb -> wb : generate and store wallet_backend_session_id wb -> w : tls() HTTP 200 u --> w: enter Wallet PIN w -> w : derive key pair (//pin_derived_eph_pub//, //pin_derived_eph_priv//) from KDF(Wallet PIN, encrypt_AES(//pin_salt//, Wallet PIN)) w -> w : generate PoP for pin derived ephemeral key - sign(wallet_backend_session_id | //device_pub//)//pin_derived_eph_priv// w -> w : generate PoP for wallet app's key - sign(wallet_backend_session_id | //pin_derived_eph_pub//)//device_priv// note left: proof must be built from both the device key and the key derived from the user PIN, might require new proof type w -> wb : tls() HTTP POST wb -> wb: load instance information for UUID note left: Instance Information: retry counter, //pin_derived_eph_pub//, //device_pub//, security relevant device attributes wb -> wb: check user pin retry note right: request would be refused in case of locked pin wb -> wb: check security of device against Vulnerability Management information note left: PIN will not be validated if device is known to be insecure wb -> wb: check signatures note right: user pin retry counter would be increased in case of failed pin signature check, user pin would be locked after threshold is exeeded wb -> wb : generate cryptographic seed (c_seed) for batch credentials and associate with issuer_ID wb -> wb : derive X key pairs (incl. key IDs) (keyIDx, (//batch_kb_X_pub//, //batch_kb_X_priv//)) deterministically from c_seed wb -> wb : assemble CloudWalletBatchKey claim with X tuples (keyIDx, //batch_kb_X_pub//) and sign with //wb_attestation_priv// wb -> w : tls() HTTP 200 group Remote HSM w -> w: generate wallet attestation POP with audience, expiration time, CloudWalletBatchKey and pid_issuer_session_id w -> w: hash wallet attestation PoP w -> wb : tls() HTTP POST wb -> wb: validate wallet_backend_session_id and load session context wb -> wb: sign hash of wallet attestation PoP with //wb_device_priv// wb -> w : tls() HTTP 200 w -> w : assemble wallet attestation PoP with signature end end group PID batch issuance alt No //or// stale DPoP nonce w -> w : generate placeholder DPoP proof with generic (not HSM-bound) keypair w -> i : tls() HTTP POST i -> i: generate and store dpop_nonce i -> w : tls() HTTP 400 w -> w: store dpop_nonce end group Remote HSM 'generate DPoP proof with dev key w -> w: prepare DPoP-proof JWT for HSM bound key incl. dpop_nonce w -> w: hash(DPoP-proof JWT for HSM bound key) w -> wb: tls() HTTP POST wb -> wb: check wallet_backend_session_id wb -> wb: sign hash of PoP with //wb_dpop_priv// (associated with UUID & Issuer_ID) wb -> w: tls() HTTP 200 w -> w: assemble DPoP-proof JWT for HSM bound key with signature end w -> i : tls() HTTP POST note left:wallet attestation Header includes Wallet attestation and PoP. DPoP Header includes DPoP proof JWT. refresh_token contains the eID data encrypted with //pp_pub// i -> i : verify wallet attestation & PoP \ncheck Wallet Provider solution status on trust list i -> i : verify the validity of the refresh token (incl. DPoP-binding) i -> i : decrypt refresh token contents with //pp_data// and store user data in session i -> i : generate and store dpop_nonce i -> i : generate Token Response with DPoP-bound access_token i -> w : tls() HTTP 200 w -> w : prepare X batch credential key PoPs (incl. audience, //batch_kb_X_pub//, c_nonce) and hash them w -> wb : tls() HTTP POST wb -> wb: validate wallet_backend_session_id and load session context wb -> wb : sign hashed PoPs X with //batch_kb_X_priv// wb -> w : tls() HTTP 200 w -> w: assemble X CredentialRequests with signed batch credential key PoPs 'generate DPoP proof with dev key group Remote HSM w -> w: prepare DPoP-proof JWT for HSM bound key incl. dpop_nonce w -> w: hash(DPoP-proof JWT for HSM bound key) w -> wb: tls() HTTP POST wb -> wb: check wallet_backend_session_id wb -> wb: sign hash of PoP with //wb_device_priv// (associated with UUID & Issuer_ID) wb -> w: tls() HTTP 200 w -> w: assemble DPoP-proof JWT for HSM bound key with signature end w -> w : generate credential response encryption key pair (//cre_eph_pub//, //cre_eph_priv//) w -> w : create credential_response_encryption object with jwk containing //cre_eph_pub// w -> i : tls() HTTP POST i -> i : validate DPoP-bound access_token and check signatures of the CredentialRequest proofs note left: ensure that the //batch_kb_X_pub// from the CredentialRequests match to the public keys in the CloudWalletBatchKey claim from the wallet attestation PoP alt #ddf ISO mdoc i -> i : create mdoc with eID data and //batch_kb_X_pub//, signed by //pp_priv//, and matching NameSpaceBytes i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i -> i : generate and store dpop_nonce i -> w : tls() HTTP 200 mdoc))> else #dfd SD-JWT VC i -> i : create SD-JWT VC with eID data and //batch_kb_X_pub//, signed by //pp_priv//, and matching Disclosures i -> i : generate encrypted credential response JWT using the values received in the credential_response_encryption object i -> i : generate and store dpop_nonce i -> w : tls() HTTP 200 SD-JWT VC, Disclosures))> end w -> w : decrypt batch credential response JWT and retrieve PID w -> w: match keyIDx from CloudWalletBatchKey claim to SD-JWT/mdoc Credentials by their respective public key (//batch_kb_X_pub//) and store as tuple in BatchCredentialStore with issuer_ID w -> w: store dpop_nonce end @enduml ``` ##### Step-by-Step Description | No | Description | | --- | ----------- | | 001 | The user opens and unlocks the Wallet. | | 002 | The Wallet requests issuance of PID Batch Credentials. | | 003 | The Wallet requests fresh wallet_backend_session_id. | | 004 | The Wallet Backend generates and links it to the session. | | 005 | The Wallet Backend returns the wallet_backend_session_id to the Wallet. | | 006 | The Wallet requests a fresh pid_issuer_session_id from the Wallet Backend | | 007 | The Wallet Backend generates a fresh wallet_backend_session_id linked to the session. | | 008 | The Wallet Backend returns the pid_issuer_session_id to the Wallet. | | 009 | The user enters the Wallet PIN. | | 010 | The Wallet proves possession of the Wallet PIN. See "Wallet proving possession of the PIN" module for a detailed description of the steps. | | 011 | Part of the above-mentioned module. | | 012 | Part of the above-mentioned module. | | 013 | The Wallet sends a Credential Request to the Wallet Backend containing the UUID & the Issuer_ID, the PoP for `pin_derived_eph_priv` and the PoP for `device_priv`. | | 014 | The Wallet Backend checks Wallet Instance. See [Issuance of Wallet Instance Attestation (WIA)¶](https://bmi.usercontent.opencode.de/eudi-wallet/wallet-development-documentation-public/latest/architecture-concept/flows/02-wallet-attestation/) for a detailed description of the steps. | | 015 | Part of the above-mentioned module. | | 016 | Part of the above-mentioned module. | | 017 | The Wallet Backend validates the PoP for *pin_derived_eph_pub* and *device_pub*. | | 018 | The Wallet Backend generates a cryptographic seed (c_seed) for the batch credential keys and associates it with Issuer_ID. Each batch of credentials uses it's own c_seed, previous c_seeds are discarded when a new batch of credentials for a specific Issuer are requested. | | 019 | The Wallet Backend deterministically derives the required number of key pairs incl. key IDs from c_seed. A mechanism for key derivation will be defined later. | | 020 | The Wallet Backend assembles a claim called CloudWalletBatchKey containing the public part of the just generated key pairs and the respective key IDs and signs the claim with *wb_attestation_priv*. | | 021 | The Wallet Backend returns the request to the Wallet; containing the signed CloudWalletBatchKey. | | 022 | The Wallet prepares a Wallet Attestation PoP containing the audience, the signed CloudWalletBatchKey claim and the pid_issuer_session_id. | | 023 | The Wallet hashes the Wallet Attestation PoP. | | 024 | The Wallet sends a signing request to the Wallet Backend containing the hash of the Wallet Attestation PoP and the wallet_backend_session_id. | | 025 | The Wallet Backend validates the wallet_backend_session_id and loads the session context. | | 026 | The Wallet Backend signs the hash of the Wallet Attestation PoP with the respective *wb_device_priv*. | | 027 | The Wallet Backend returns the request to the Wallet incl. the signed hash of the Wallet Attestation PoP. | | 028 | The Wallet assembles the Wallet Attestation PoP using the signature received in a previous step. | | 029 | The Wallet generates (and stores) a placeholder DPoP proof with a generic (not HSM-bound) keypair to trigger an error response from the Token endpoint necessary to retrieve the `dpop_nonce`. | | 030 | The Wallet sends a Token Request to the PID Provider; containing the placeholder DPoP proof. | | 031 | The PID Provider generates and stores a `dpop_nonce`. | | 032 | The PID Provider responds with the expected error "use_dpop_nonce" containing the `dpop_nonce` to be used from now in the DPoP nonce header. | | 033 | The Wallet extracts and stores the `dpop_nonce`. | | 034 | The Wallet prepares the DPoP-proof JWT for the HSM-bound `wb_attestation_pub` including the `dpop_nonce` and `iat`. | | 035 | The Wallet hashes the DPoP proof. | | 036 | The Wallet sends a request to the Wallet Backend to sign the hash of the DPoP-proof for the HSM bound key containing a hash of the PoP for the HSM bound key. | | 037 | The Wallet Backend validates the wallet_backend_session_id and loads the session context. | | 038 | The Wallet Backend signs the hash of the PoP for the HSM bound key with *wb_device_priv* (associated with UUID & Issuer_ID) from the HSM. | | 039 | The Wallet Backend returns the signed hash of the PoP for the HSM bound key to the Wallet. | | 040 | The Wallet assembles the DPoP-proof for the HSM bound key using the signature received in a previous step. | | 041 | The Wallet sends a Token Request to the PID Provider containing the Wallet Attestation + PoP in the wallet attestation Header, the DPoP-proof JWT over `wb_attestation_pub`, the grant_type "refresh_token" and the DPoP-bound refresh token. | | 042 | The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list. | | 043 | The PID Provider verifies the validity of the refresh token (incl. DPoP-binding). | | 044 | The PID Provider decrypts the refresh token contents with //pp_data// and stores the users identity attributes in the session. | | 045 | The PID Provider generates and stores a `dpop_nonce`. | | 046 | The PID Provider generates a Token Response with a DPop bound access token. | | 047 | The PID Provider returns a Token Response to the Wallet containing the DPoP bound access_token, the c_nonce and a fresh `dpop_nonce` in the DPoP nonce header. | | 048 | The Wallet prepares the required number of PoP (incl. audience and respective public key) for the batch credential keys and hashes them. | | 049 | The Wallet sends a BatchSigningRequest to the Wallet Backend containing the required number of hashed batch credential key PoPs and the wallet_backend_session_id. | | 050 | The Wallet Backend validates the wallet_backend_session_id and loads the session context. | | 051 | The Wallet Backend signs the hashed batch credential key PoPs with the respective *batch_kb_X_priv*. | | 052 | The Wallet Backend returns the request to the Wallet incl. the signed hashes of the batch credential key PoPs. | | 053 | The Wallet assembles the required amount of CredentialRequests containing the signed batch credential key PoPs. | | 054 | The Wallet prepares the DPoP-proof JWT for the HSM-bound //dev// key including the `dpop_nonce` and `iat`. | | 055 | The Wallet hashes the DPoP proof. | | 056 | The Wallet sends a request to the Wallet Backend to sign the hash of the DPoP-proof for the HSM bound key containing a hash of the PoP for the HSM bound key and the wallet_backend_session_id. | | 057 | The Wallet Backend validates the wallet_backend_session_id and loads the session context. | | 058 | The Wallet Backend signs the hash of the PoP for the HSM bound key with *wb_dpop_priv* (associated with UUID & Issuer_ID) from the HSM. | | 059 | The Wallet Backend returns the signed hash of the PoP for the HSM bound key to the Wallet. | | 060 | The Wallet assembles the DPoP-proof for the HSM bound key using the signature received in a previous step. | | 061 | The Wallet generates a new ephemeral keypair (*cre_eph_pub*, *cre_eph_priv*). | | 062 | The Wallet creates the `credential_response_encryption` JSON object containing a jwk containing the *cre_eph_pub*, the JWE alg parameter and the JWE enc parameter. | | 063 | The Wallet sends a BatchCredentialRequest to the PID Provider containing the DPoP proof JWT, the required amount of CredentialRequests, the `credential_response_encryption` object and the DPoP bound access_token. | | 064 | The PID Provider validates the DPoP bound access_token and checks the signatures of the CredentialRequests. The PID Provider has to ensure that the *batch_kb_X_pub* from the CredentialRequests match to the public keys in the CloudWalletBatchKey claim from the Wallet Attestation PoP. | | 065 | **(mdoc)** The PID Provider creates the mdoc containing the issuerAuth with the *batch_kb_X_pub* as deviceKey and hashes of the eID data, the eID data as NameSpaceBytes and the status management information. | | 066 | **(mdoc)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID credential to the payload. | | 067 | The PID Provider generates and stores a fresh `dpop_nonce`. | | 068 | **(mdoc)** The PID Provider sends the Credential Response JWT containing the required amount of PID credentials as mdoc. | | 069 | **(SD-JWT)** The PID Provider creates SD-JWT VC containing the SD-JWT with the *batch_kb_X_pub* as confirmation claim and hashes of the eID data, the eID data as Disclosures and the status management information. | | 070 | **(SD-JWT)** The PID Provider creates an encrypted JWT (JWE) using the values received in the `credential_response_encryption` object and adds (among others) the PID credential to the payload. | | 071 | The PID Provider generates and stores a fresh `dpop_nonce`. | | 072 | **(SD-JWT)** The PID Provider sends the Credential Response JWT containing the required amount of PID credentials as SD-JWT VC. | | 073 | The Wallet decrypts the Credential Response JWT using the *cre_eph_priv*. | | 074 | The Wallet matches the key IDs (from the CloudWalletBatchKey claim) to the public keys in the Credential Response by their respective public keys and stores them as tuple in a BatchCredentialStore with the issuer_ID. | | 075 | The Wallet extracts and stores the `dpop_nonce`. | #### Credential Presentation ##### Sequence Diagram [-> Visual Example of the User Journey: PID Presentation - Issuer Signed - Cloud](./figures/PID-IssuerSigned-cloud-presentation.png) ```plantuml @startuml 'color for screen reference !define GREEN #dfd !define TLSGREEN #118888 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [TLS] block !function tls() !return "[TLS]" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" participant u order 1[ **PID Holder** ---- ""PIN: (//user_pin//)"" ] participant b order 2 [ **Browser App** (same device) ] participant v order 3[ **Relying Party** ---- ""Long-term Key: (//rp_pub//, //rp_priv//)"" ] participant w order 4[ **User's EUDI Wallet Instance\ (eID-Client)** ---- ""Device Key: (//device_pub//, //device_priv//)"" ""Wallet Attestation bound to //wb_device_pub//"" ""PIN Salt: //pin_salt//"" ] participant wb order 5[ **User's EUDI Wallet Backend** ---- ""Long-term Key: (//wb_attestation_pub//, //wb_attestation_priv//)"" ""Long-term Key: (//wb_device_pub//, //wb_device_priv//)"" ] u --> b : browse to application hnote over b #dfd: Screen: same_device_relying_party_start b -> v : tls() HTTP GET v -> v : generate ephemeral key pair (//rp_eph_pub//, //rp_eph_priv//) v -> v : create OpenID4VP Authorization Request,\n sign with //rp_priv//,\n store under note left: Authorization Request includes:\n- presentation_definition\n- purpose\n- state\n- nonce\n- //rp_eph_pub// \n- response_uri v -> v : generate new browser session sessionId and bind the authorization request to it v --> b : tls() HTTP 200 HTML containing wallet-link openid4vp://authorize?")\nclient_id=..&request_uri=\nSet-Cookie: sid=sessionId u --> b : action to start flow/launch wallet b -> w : launch with wallet-link openid4vp:// note right #fc7: Potential security risk: Wallet app may be spoofed by malicious app hnote over w #dfd: Screen: launch_wallet u --> w : unlock wallet note right: may be moved to later point in flow or removed, see notes. hnote over w #dfd: Screen: unlock_wallet w -> v : tls() HTTP GET note right #fc7: Potential privacy risk: RP learns existance of wallet app and potentially identifying information (e.g., headers) v --> w : tls() HTTP 200 w -> w : validate Authorization Request JWT using //rp_pub// u <--> w : user consent to present PID to Relying Party for given purpose hnote over w #dfd: Screen: consent_present_credential w -> w: pick batch credential tuple (Credential, keyIDx) from batch credential store alt #ddf ISO mdoc w -> w : prepare mdoc presentation according to by removing unnecessary NameSpaceBytes w -> w : calculate SessionTranscript (mDocGeneratedNonce, client_id, responseUri, nonce) and generate deviceAuth payload and hash else #dfd SD-JWT VC w -> w: prepare SD-JWT presentation according to by removing unnecessary Disclosures w <-> w : generate KB-JWT payload (nonce, audience, hash of SD-JWT and disclosures) and hash end group check pin & sign in remote HSM w -> wb: tls() HTTP POST wallet_backend_session_id wb -> wb : generate and store wallet_backend_session_id wb -> w : tls() HTTP 200 u <--> w : input Wallet PIN hnote over w #dfd: Screen: wallet_pin w -> w : generate key pair (//pin_derived_eph_pub//, //pin_derived_eph_priv//) from KDF(Wallet PIN, encrypt_AES(//pin_salt//, Wallet PIN)) w -> w : generate PoP for pin derived ephemeral key - sign(wallet_backend_session_id | //device_pub//)//pin_derived_eph_priv// w -> w : generate PoP for wallet app's key - sign(wallet_backend_session_id | //pin_derived_eph_pub//)//device_priv// w -> wb : tls() HTTP POST wb -> wb: load instance information for UUID note left: Instance Information: retry counter, //pin_derived_eph_pub//, //device_pub//, security relevant device attributes wb -> wb: check user pin retry note right: request would be refused in case of locked pin wb -> wb: check security of device against Vulnerability Management information note left: PIN will not be validated if device is known to be insecure wb -> wb: check signatures note right: user pin retry counter would be increased in case of failed pin signature check, user pin would be locked after threshold is exeeded wb -> wb: identify c_seed with issuer_ID and load wb -> wb: deterministically regenerate (//batch_kb_X_pub//, //batch_kb_X_priv//) from c_seed and keyIDx wb -> wb: sign hash of KB-JWT/deviceAuth hash with //batch_kb_X_priv// wb -> w : tls() HTTP 200 end alt #ddf ISO mdoc w -> w : assemble deviceAuth and build presentation with issuerSigned and deviceSigned(deviceAuth) else #dfd SD-JWT VC w -> w : assemble KB-JWT and build presentation with SD-JWT, selected Disclosures and KB-JWT end w -> w : create vp_token and presentation_definition w -> w : add optionally other presentations according to the presentation_definition w -> w: delete used batch credential and matching keyIDx w -> v : tls() HTTP POST v -> v : look up state in existing sessions\ncreate & store response_code for session v --> w : tls() HTTP 200 w -> b : launch browser with hnote over w #dfd: Screen: success_redirect b -> v : tls() HTTP GET \nCookie: sid=sessionId v -> v : look up session with sessionId and match response_code alt #ddf ISO mdoc v -> v : verify contents of :\n- verify mdoc issuerAuth PID\n- verify deviceAuth with //batch_kb_X_pub// from issuerAuth\n- calculate and validate correct SessionTranscript else #dfd SD-JWT VC v -> v : verify contents of :\n- verify SD-JWT PID\n- verify KB-JWT with //batch_kb_X_pub// from SD-JWT\n- validate nonce and audience from KB-JWT end v -> b : tls() HTTP 200 hnote over b #dfd: Screen: same_device_relying_party_identified legend left <#GhostWhite,#GhostWhite>| |= __Legend__ | || Visual Example of the User Journey reference| || TLS (Transport Layer Security)| endlegend @enduml ``` ##### Step-by-Step Description Note: While certain assumptions about session management of the Relaying Party are made here, the concrete implementation is considered out of scope for this document. The usual security considerations for web session management apply. | No | Description | | --- | ----------- | | 001 | The user browses to Relying Party (RP) website. | | 002 | Browser app on the user's device opens the RP website. | | 003 | RP generates an ephemeral key pair (e.g., `rp_eph_pub`, `rp_eph_priv`). | | 004 | RP generates an OpenID4VP Authorization Request and stores it under a `request_uri` (e.g., `https://rp.example.com/oidc/request/1234`). The request is bound to the user's browser session, it is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id. It contains the ephemeral key for response encryption. It contains RP's nonce and state. It contains the RP's response_uri endpoint for sending the Authorization Response over POST. | | 005 | RP generates a new browser session and binds the generated Authorization Request to it. | | 006 | RP returns a HTML page to the browser containing a link to the Wallet (e.g., `openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234`) and a cookie with the browser sessionId is set. | | 007 | The user clicks on the link. | | 008 | The RP website navigates to the custom scheme link to launch the Wallet. | | 009 | The user unlocks the Wallet (see notes below). | | 010 | The Wallet sends a GET request to the RP's Authorization Request endpoint (e.g., `https://rp.example.com/oidc/request/1234`). | | 011 | The Wallet retrieves the Authorization Request from the RP website. | | 012 | The Wallet validates the Authorization Request using the RP's public key. Was the signature valid and the key bound to the RP's metadata? **Security:** This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP. | | 013 | The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the PID. | | 014 | The Wallet picks a batch credential tuple (Credential incl. possible disclosures, keyID) from the batch credential store. | | 015 | **(mdoc)** The Wallet prepares an mdoc presentation according to the presentation_definition by removing NameSpaceBytes of not disclosed attributes. | | 016 | **(mdoc)** The Wallet calculates the SessionTranscript according to ISO 18013-7 Annex B.4.4 from mDocGeneratedNonce, client_id, responseUri, nonce and generates the deviceAuthentication structure from SessionTranscript and NameSpaceBytes for signing and hashes the deviceAuthentication structure. | | 017 | **(SD-JWT)** The Wallet generates an SD-JWT VC presentation according to the presentation_definition by removing Disclosures of not disclosed attributes. | | 018 | **(SD-JWT)** The Wallet creates the header and payload for the KB-JWT from audience, nonce, hash of issuer-signed JWT and Disclosures for signing and hashes the payload. | | 019 | The Wallet requests a fresh wallet_backend_session_id from the Wallet Backend. | | 020 | The Wallet Backend generates a fresh wallet_backend_session_id linked to the session. | | 021 | The Wallet Backend returns the wallet_backend_session_id to the Wallet. | | 022 | The User enters the Wallet PIN. | | 023 | The Wallet proves possession of the Wallet PIN. See "Wallet proving possession of the PIN" module for a detailed description of the steps. | | 024 | The Wallet signs over the wallet_backend_session_id and the device-bound public key *device_pub* using the key *pin_derived_eph_priv*. | | 025 | The Wallet signs over the wallet_backend_session_id and the Wallet PIN derived public key *pin_derived_eph_pub* using the key *device_priv*. | | 026 | The Wallet sends a signing request to the Wallet Backend containing UUID & issuer_ID, PoP for pin_derived_eph_priv, PoP for device_priv, the hash of KB-JWT/deviceAuth and keyID (of the respective key that should be used to sign). | | 027 | The Wallet Backend checks Wallet Instance. See [Issuance of Wallet Instance Attestation (WIA)](https://bmi.usercontent.opencode.de/eudi-wallet/wallet-development-documentation-public/latest/architecture-concept/flows/02-wallet-attestation/) for a detailed description of the steps. | | 028 | Part of the above-mentioned module. | | 029 | Part of the above-mentioned module. | | 030 | The Wallet Backend validates the PoP for *pin_derived_eph_pub* and *device_pub*. | | 031 | The Wallet Backend loads the c_seed associated with the issuer_ID. | | 032 | The Wallet Backend deterministically regenerates (*batch_kb_X_pub*, *batch_kb_X_priv*) from c_seed and keyIDx - A mechanism for key derivation will be defined later. | | 033 | The Wallet Backend signs the hash of KB-JWT/deviceAuth with the respective *batch_kb_X_priv*. | | 034 | The Wallet Backend returns the signed hashes of KB-JWT/deviceAuth to the Wallet. | | 035 | **(mdoc)** The Wallet assembles the deviceAuth from header, payload and signature and builds the presentation from deviceAuth and issuerSigned. | | 036 | **(SD-JWT)** The Wallet assembles the KB-JWT from header, payload and signature and builds the SD-JWT VC presentation from issuer-signed JWT, Disclosures and KB-JWT. | | 037 | The Wallet creates a VP token and a presentation submission from the received credential. | | 038 | Optional: The Wallet can add further presentations. | | 039 | The Wallet deletes the used batch credential tuple (credential, keyID). | | 040 | The Wallet sends the VP token and presentation submission to the RP (encrypted to the RP's public key *rp_eph_pub*). | | 041 | The RP finds a session with the state and generates a response_code for this session. | | 042 | The RP returns the redirect_uri with the response_code to the Wallet. | | 043 | The Wallet launches the browser with the redirect_uri and response_code. | | 044 | The browser sends the redirect_uri and response code to the RP, attaching the browser sessionId as a cookie. | | 045 | The RP looks up whether there exists a session with the sessionId from the cookie and a matching response_code. | | 046 | **(mdoc)** The RP verifies the PID in the VP token and verifies the SessionTranscript calculated from nonce, mDocGeneratedNonce, client_id, response_uri. | | 047 | **(SD-JWT)** The RP verifies the SD-JWT PID in the VP token, verifies the KB-JWT using the *batch\_kb\_X\_pub* in the SD-JWT, and verifies the nonce and audience in the KB-JWT. | | 048 | The RP considers the user to be identified in the session context and continues the UX flow. | #### Wallet proving possession of the PIN ##### Generation of a Proof of Knowledge of the Wallet PIN A PIN-derived ephemeral public key that is needed to validate the signature on this JWT must be included in the `jwk` header parameter. There must be a JWT header parameter `typ` with the value being `pin_derived_eph_pub_pop`. The JWT payload must contain an `aud` claim whose value is equal to the Wallet backend's Identifier. wallet_backend_session_id must be included in a `wallet_backend_session_id` parameter. Below is a non-normative example of a JWT generated as a PoP for pin derived ephemeral key: ```json { "alg": "...", "typ": "pin_derived_eph_key_pop", "jwk": { "kty": "EC", "crv": "P-256", "x": "bPP7f...gW_ao", "y": "38_Lg...VUCfW" } }. { "wallet_backend_session_id": "123456", "aud": "https://pid-issuer.example.com", "device_key": { "jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." } } }.[signature by the pin derived ephemeral pub key] ``` The `jwk` claim contains the public key of a PIN-derived ephemeral key pair. --- ## Glossary This document uses the following terms and abbreviations: | Term | Definition | Reference | | ---- | ---------- | --------- | | **Two Factor Authentication (2FA):** | *2FA is a security system that requires two distinct forms of identification in order to access something.* | | | **European Digital Identity Wallet Architecture and Reference Framework (ARF):** | *A toolbox including a technical Architecture and Reference Framework (ARF), a set of common standards and technical specifications, and a set of common guidelines and best practices.* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **Authentication:** | *The process of verifying that the claimed identity is valid. It involves proving that the user is indeed who they claim to be.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) | | **Authorization:** | *The process of granting or denying specific permissions or access rights to resources, systems, or data based on the authenticated identity of a user or entity. It determines what an authenticated user or entity is allowed to do.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) | | **brainpool:** | *A set of elliptic curve domain parameters over finite prime fields that are recommended for use in cryptographic applications.* | [RFC5639](https://datatracker.ietf.org/doc/html/rfc5639) | | **OAuth 2.0 Demonstrating Proof of Possession (DPoP):** | *DPoP binds a token to the client that requested it to protect against misuse.* | [DPoP](https://datatracker.ietf.org/doc/draft-ietf-oauth-dpop/) | | **Electronic Attestation of Attributes (EAA):** | *‘Electronic Attestation of Attributes’ means an attestation in electronic form that allows the authentication of attributes.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) Article 3 (44) | | **Elliptic-curve Diffie–Hellman (ECDH):** | *Elliptic-curve Diffie–Hellman (ECDH) is a key agreement protocol that allows two parties, each having an elliptic-curve public–private key pair, to establish a shared secret over an insecure channel. This shared secret may be directly used as a key, or to derive another key.* | [RFC6090](https://datatracker.ietf.org/doc/html/rfc6090) | | **German eID system (eID):** | *Architecture for the German electronic Identity Card and electronic Resident Permit is specified in the BSI Technical Guideline TR-03127.* | [BSI TR-03127](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/Technische-Richtlinien/TR-nach-Thema-sortiert/tr03127/TR-03127_node.html) | | **eID-Server (eID-Server):** | *eID-Server for Online-Authentication based on Extended Access Control Version 2 (EAC2) between an eService and an eIDAS token, e.g. the German National Identity Card, the German electronic Residence Permit, the eID-Card for Union Citizens or an EAC-compatible mobile eID based on secure storage on a mobile device, that was derived from one of the former documents.* | [BSI TR-03130](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/Technische-Richtlinien/TR-nach-Thema-sortiert/tr03130/TR-03130_node.html) | | **eIDAS regulation version 2 (eIDAS):** | *Regulation of the European Parliament and of the Council amending Regulation (EU) No 910/2014 as regards establishing a framework for a European Digital Identity.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) | | **European Digital Identity Wallet (EUDIW):** | *‘European Digital Identity Wallet’ means an electronic identification, which allows the user to securely store, manage and validate identity data and electronic attestations of attributes, to provide them to relying parties and to other users of European Digital Identity Wallets, and to sign by means of qualified electronic signatures or to seal by means of qualified electronic seals.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) | | **(European Digital Identity) Wallet Provider (EUDIW Provider, Wallet Provider):** | *The obligation to provide an EUDIW arises from the eIDAS Regulation. The MS determines whether it provides the EUDIW itself, mandates the provider(s) or recognizes one or more Wallet Provider(s) by another organization.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) | | **embedded UICC (eUICC):** | *A removable or non-removable UICC which enables the secure remote and/or local management of Profiles.* | [GSMA](https://www.gsma.com/get-involved/working-groups/sim-working-group/embedded-sim) | | **Hash-based message authentication code (HMAC):** | *HMAC is a specific type of message authentication code involving a cryptographic hash function and a secret cryptographic key.* | [RFC6234](https://datatracker.ietf.org/doc/html/rfc6234) | | **Identity Owner (Holder):** | *The entity, such as a natural person, a legal person, or a device, which is subject of verifiable credentials from credential issuers and being in control of the reception, storage, and sharing of such credentials with relying parties.* [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | | **Hardware Security Module (HSM):** | *A HSM is a device for providing cryptographic functionalities whereas the life cycle of cryptographic keys and the performance of cryptographic functions is managed within a highly protected hardware environment.* | | | **Identification:** | *The process of claiming or recognizing an identity. It involves presenting an identifier that represents an individual or entity.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) | | **Internet Engineering Task Force (IETF):** | *The Internet Engineering Task Force is a standards organization for the Internet and is responsible for the technical standards that make up the Internet protocol suite. It has no formal membership roster or requirements and all its participants are volunteers.* | | | **International Organization for Standardization (ISO):** | *The International Organization for Standardization is an independent, non-governmental, international standard development organization composed of representatives from the national standards organizations of member countries.* | | | **PID presentation format (ISO mdoc):** | | | | **Issuer:** | *An entity that issues credentials to a Holder. Sometimes referred to as Provider.* | [OpenID4VCI](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html) | | **JSON Web Token (JWT):** | *JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.* | [RFC7519](https://datatracker.ietf.org/doc/html/rfc7519) | | **Level of Assurance (LoA):** | | [eIDAS Levels of Assurance (LoA)](https://ec.europa.eu/digital-building-blocks/sites/display/DIGITAL/eIDAS+Levels+of+Assurance), [BSI TR-03107](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/Technische-Richtlinien/TR-nach-Thema-sortiert/tr03107/TR-03107_node.html) | | **Message Authentication Code (MAC):** | *The result of a HMAC performance.* | [RFC8446](https://datatracker.ietf.org/doc/html/rfc8446) | | **OpenID for Verifiable Credential Issuance (OpenID4VCI):** | *OAuth protected API for the issuance of Verifiable Credentials.* | [OpenID4VCI](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html) | | **OpenID for Verifiable Presentations (OpenID4VP):** | *A mechanism on top of OAuth 2.0 [RFC6749](https://datatracker.ietf.org/doc/html/rfc6749) that enables presentation of Verifiable Credentials as Verifiable Presentations.* | [OpenID4VP](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html) | | **Person Identification Data (PID):** | *‘Person Identification Data’ means a set of data, issued in accordance with Union or national law, enabling the identity of a natural or legal person, or of a natural person representing a natural or legal person, to be established.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) | | **overasking** | *A situation where a Relying Party requests more information than is necessary for the specific purpose of the transaction, potentially violating the GDPR.* | | | **Person Identification Data Issuer (PID Provider (PI)):** | *A Member State or other legal entity issuing Person Identification Data to Users for later use.* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **Person Identification Data Provider (PID Provider (PP)):** | *A Member State or other legal entity providing Person Identification Data to Users.* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **Public Key Infrastructure (PKI):** | *Systems, software, and communication protocols that are used by EUDI Wallet ecosystem components to distribute, manage, and control public keys. A PKI publishes public keys and establishes trust within an environment by validating and verifying the public keys mapping to an entity.* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **Proof of Possession (PoP):** | *Evidence provided by the Wallet regarding the possession of the respective key material.* | | | **Qualified Electronic Attestation of Attributes (QEAA):** | *‘Qualified Electronic Attestation of Attributes’ means an electronic attestation of attributes, which is issued by a qualified trust service provider and meets the requirements laid down in Annex V.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) Article 3 (45) | | **Qualified Electronic Signature (QES):** | *‘Qualified Electronic Signature’ means an advanced electronic signature that is created by a qualified electronic signature creation device, and which is based on a qualified certificate for electronic signatures.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) | | **Qualified Trust Service Provider (QTSP):** | *A Trust Service Provider who provides one or more Qualified Trust Services and is granted the qualified status by the supervisory body.* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **Relying Party (RP):** | *‘Relying Party’ means a natural or legal person that relies upon an electronic identification, European Digital Identity Wallets or other electronic identification means, or a trust service.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) Article 3 (6) | | **Selective Disclosure for JWT (SD-JWT):** | *A composite structure, consisting of an Issuer-signed JWT (JWS, [RFC7515](https://datatracker.ietf.org/doc/html/rfc7515)), Disclosures and optionally a Key Binding JWT that supports selective disclosure.* | [SD-JWT](https://datatracker.ietf.org/doc/rfc9901/) | | **SD-JWT-based Verifiable Credentials (SD-JWT VC):** | *Verifiable Credentials with JSON payloads with and without selective disclosure based on the SD-JWT format.* | [SD-JWT VC](https://datatracker.ietf.org/doc/draft-ietf-oauth-sd-jwt-vc/) | | **Secure Element (SE):** | *Secure Elements are physical components in electronic devices that securely store and protect sensitive data and applications and may provide certain secure cryptographic operations.* | [Secure Elements for mobile platforms](https://www.bsi.bund.de/EN/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/Secure-Elements/secure-elements_node.html) | | **Seed Credential:** | *A credential derived from the electronic Identity Card. It is used to request a fresh PID credential created on-demand from the PID Provider.* | | | **Smart-eID (Smart-eID):** | *The smart eID enables citizens to store their electronic proof of identity directly in their smartphones.* | [Smart-eID Act](http://www.bgbl.de/xaver/bgbl/start.xav?startbk=Bundesanzeiger_BGBl&jumpTo=bgbl121s2281.pdf) | | **Trusted List (Trusted List):** | *Repository of information about authoritative entities in a particular legal or contractual context which provides information about their current and historical status.* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **Trust Service Provider (TSP):** | *A natural or a legal person who provides one or more Trust Services, either as a qualified or as a non-qualified Trust Service Provider.* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **Interacting entity (User):** | *A natural or legal person using an EUDI Wallet. Also referred to as Holder.* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **User Experience / User Interface (UX/UI):** | *The user interaction work flow (UX) and the user interaction functional and visual elements (UI) of a software and/or hardware application.* | [Wikipedia User experience design](https://en.wikipedia.org/wiki/User_experience_design) | | **Verifiable Credential (VC):** | *A credential created by an Issuer in a way that the integrity and authenticity of the credential can be cryptographically verified.* | [OpenID4VCI](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html) | | **Wallet Secure Cryptographic Device (WSCD):** | *Hardware-backed secure environment for creating, storing, and/or managing cryptographic keys and data. Examples include Secure Elements (SE), Trusted Execution Environments (TEEs), and (remote or local) Hardware Security Module (HSM).* | [ARF 1.2.0](https://github.com/eu-digital-identity-wallet/eudi-doc-architecture-and-reference-framework/tree/v1.2.0) | | **Wallet-Relying Party (WRP):** | *wallet-relying party means a relying party that intends to rely upon wallet units for the provision of public or private services by means of digital interaction.* | [eIDAS 2](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0117_EN.html) Article 5b | --- ## Upcoming Features !!! info "Disclaimer" The contents of this section are not relevant for the current development phase but will be important for further develpment phases. --- ## Wallet Function: Qualified Electronic Signature (QES) ## Introduction Qualified Electronic Signatures (QES) provide legally binding signatures for digital documents. QES are regulated by the eIDAS 2 framework and recognized by all EU member states. They have the equivalent legal effect of a handwritten signature. QES are technically based on digital signatures using certificates. Because of their legal value, there are additional requirements to a qualified signature: - QES are based on **qualified signing certificates** issued to a natural person. - Qualified signing certificates must be issued by certified Qualified Trust Service Providers (**QTSP**) after verifying the identity of the person. - A QES has to be created by a **Qualified Signature Creation Device (QSCD)** that protects the private signing key associated with the signature certificate. ## References Qualified electronic signatures and their creation using the EUDI Wallet are covered by a number of regulations, standards and informative references: - [eIDAS Regulation No 910/2014 + amendments](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A02014R0910-20241018) - [eIDAS implementing acts](https://www.eid.as/implementing-acts/) - [European Digital Identity Wallet Architecture and Reference Framework (ARF)](https://eu-digital-identity-Wallet.github.io/eudi-doc-architecture-and-reference-framework/latest/architecture-and-reference-framework-main/) - [Cloud Signature Consortium CSC API](../../ecosystem-vision-and-fundamentals/standards.md#csc-technical-specifications) - [Cloud Signature Consortium CSC Data Model](../../ecosystem-vision-and-fundamentals/standards.md#csc-technical-specifications) - [Cloud Signature Consortium CSC Data Model Bindings](../../ecosystem-vision-and-fundamentals/standards.md#csc-technical-specifications) - [ETSI EN 319 102-1](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards): "Electronic Signatures and Trust Infrastructures (ESI); Procedures for Creation and Validation of AdES Digital Signatures; Part 1: Creation and Validation" - [CEN EN 419 241-1](../../ecosystem-vision-and-fundamentals/standards.md#cen-standards): Trustworthy Systems Supporting Server Signing – Part 1: General System Security Requirements ## Glossary of QES-related terminology The following signature-specific terms and abbreviations are extensions to the [main glossary](../../glossary.md) and based on definitions given in [ETSI TR 119 001](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards), [ETSI EN 319 102-1](../../ecosystem-vision-and-fundamentals/standards.md#etsi-standards) and [CEN EN 419 241-1](../../ecosystem-vision-and-fundamentals/standards.md#cen-standards). - **Signer’s Original Document (SOD):** original document before any formatting. - **Signer’s Original Document Representation (SODR):** calculated from the *Signer’s Original Document (SOD)* using a cryptographic hash function. - **Signer's Document (SD):** document upon which the signature is generated and to which it is associated. In some cases, a *Signer's Document Representation (SDR)* of the SD can be presented to the signature processes instead of the complete SD. The SD may be a processed version of the *Signer's Original Document (SOD)*. - **Signer's Document Representation (SDR):** used in the calculation of the signature as a representation of the SD. It is calculated from the SD using a cryptographic hash function. - **Data To Be Signed (DTBS):** constructed from the information objects that are to be covered by the signature. These are the SD or the SDR and the signature attributes selected to be signed together with the SD. - **Data To Be Signed Representation (DTBSR):** computed from the formatted *DTBS* by means of a cryptographic hash function and is used to compute the *Digital Signature Value (DSV)*. - **Signed Data Object (SDO):** composed of a digital signature value and signed attributes, may additionally contain the *SD / SDR*. - **Driving Application (DA):** uses a signature creation system to create a signature. The DA provides the *Signer Document (SD)* or the *Signer Document Representation (SDR)* to the *Signature Creation Application (SCA)*. - **Signature Creation Application (SCA):** prepares the *Data To Be Signed Representation (DTBSR)* from the *Signer's document* and additional attributes and creates the signed document / *Signed Data Object (SDO)*. - **Server Signing Application (SSA)** creates the digital signature of the *DTBSR* on behalf of the signer that activated the signature using the *SIC*. It receives the signing requests, coordinates their activation and produces *Digital Signature Values (DSV)*. The SSA is operated in the QTSP environment. - **Signer Interaction Component (SIC):** is under the control of the signer and used to support the signature activation protocol to the *Server Signing Application*. In the EUDI Wallet infrastructure the SIC is implemented as a part of the Wallet. - **Signature Authorization**: same as Signature Activation, see *SIC* - **Signature Application**: same as *Signature Creation Application (SCA)* ## EUDI Wallet support for QES The creation and verification of remote electronic signatures involves a number of software components and standardized data objects. These components can be assigned to different actors, depending on the QES implementation model: - **Relying Party**: wants a document to be signed - **Wallet**: signs a document and gets user's authorizations, e.g., for a QES - **QTSP**: issues signature certificates and creates cryptographic signatures (digital signature values) on behalf of a user - **User**: natural person signing a document The eIDAS 2 regulation defines that users can sign documents using qualified signatures which are provided within their Wallet. There are different models to implement QES using the Wallet, depending on the control flows for signature and authorization requests. Wallets must support both models described below: - **Wallet-centric model:** the Wallet creates a signed document or just the signature, supported by a QTSP for the cryptographic signature value - **QTSP-centric model:** a user uses the Wallet to authorizes a QTSP to sign a document on behalf of the user In both cases, OpenID4VP authorization requests for credential presentations are used to interact with the Wallet. In the case of a QES, the RP requests the user to authorize transactions described in the OpenID4VP request using so-called "transaction data". Hashes of the transaction data are part of the verifiable credential presentation to prove the authorization. Depending on the QES implementation model, a **presentation of the following credentials** (including a confirmation of the respective transaction data) may be requested from the Wallet: - **PID:** to identify the user as a natural person and to allow a QTSP the issuance of a qualified signature certificate to this person. The certificate may then be used to sign a document on behalf of the PID owner. Short-lived qualified certificates based on a PID presentation are created to sign a specific document and expire or are revoked shortly after this operation, see [CSC]. - **Authentication credential (EAA):** to authenticate the user, e.g., to a QTSP using a credential issued by the QTSP during a previous onboarding / QTSP profile creation. After a successful presentation, the QTSP may give access to users signature credentials during subsequent signature calls. - **X.509:** credential format (`https://cloudsignatureconsortium.org/2025/x509`) where the returned VP token contains the signed document. The original document (SOD) is provided with the presentation request. A QTSP needs the user's authorization to perform certain actions. The following QES-related **transaction data types** have to be supported by wallets, see [OID4VP] and [CSC Data Model] (Pre-Release, still work in progress): - **qc-request:** (`https://cloudsignatureconsortium.org/2025/qc-request`) to get user consent for the creation of signature certificates according to the Terms and Conditions (T&C) of the QTSP - **qes** (`https://cloudsignatureconsortium.org/2025/qes`) to authorize the QTSP to create a QES for a document / batch of documents on behalf of the user. This includes showing information about the document(s) to be signed, e.g., document label, hash value, or the option to open the document via a provided protected link. The difference between giving consent for a certificate creation and authorizing a signature for a certain document must be clearly visible for the user. ## Wallet-centric Model ### User Experience Non-normative example for a wallet-centric use case: - User opens the Wallet and picks a document to be signed or the document is provided by a Relying Party. - User selects the QTSP profile for the signature in the Wallet. - User is asked by the Wallet to authorize the signature for the chosen document. - User authorizes the signature by biometrics or PIN. - Wallet shows a confirmation about the successful signature. ![User Journey: Wallet-centric-model with RP provided data = document](../../../user_journeys/Wallet-centric-flow_RP_provided_data_document.png) ### Architecture Overview In the Wallet-centric model, the user's Wallet is the central actor to sign a document and to control and approve necessary transactions with a QTSP. The Signature Creation Application (SCA) is part of the Wallet or of the Wallet backend. ```plantuml @startuml !include LAYOUT_TOP_DOWN() hide stereotype Person(user, "User") System_Boundary(ec, "QES Ecosystem") { package "RP environment" as RP { System_Ext(DA, "Driving Application") } package "QTSP environment" as QTSP { System_Ext(SSA, "Server Signing Application") } package "EUDI Wallet Instance" as EUDIW #lightgreen { System_Ext(W, "OID4VP Wallet") System_Ext( SCA, "Signature Creation Application") System_Ext(SIC, "Signature Interaction Component") } } Rel_D(user, EUDIW, "Interacts with") Rel_L(user, DA, "(1) Interacts with") Rel_D(DA, W ,"(2) Signing \n Request", "OID4VP \n(X.509)") Rel_U(W, SCA, "(3) Signing \n request") Rel_D(SCA, SSA, "(4) Signing Request", "CSC/OAuth2") Rel_U(SSA, W, "(5) Certificate Creation / \n Signature Authorization \n Request" , OID4VP) Rel_R(W, SIC, "(6) Request user\nconfirmation") Rel_D(W, SSA, "(7) Confirmation / Authorization") Rel_U(SSA, SCA, "(8) Digital \nSignature Value") Rel_U(SCA, W, "(9) Signed \n document") Rel_U(W, DA ,"(10) Credential presentation with signed Document") @enduml ``` *Figure 1: Wallet-centric model* The Driving Application at a RP sends the request to sign a document to the user's Wallet. Alternatively, the user uses the Wallet to select a document on the users device to sign. The user then chooses a QTSP profile in the Wallet. The Wallet sends the signature request to the QTSP. The QTSP starts a QES authorization flow with the Wallet (details see below). After successful authorization, the QTSP generates the signature value and returns it to the Wallet. The signature is embedded into the document by the SCA in the Wallet. **QTSP profiles** in the Wallet can be pre-configured or the result of previous user enrollments at a QTSP. If a user is not known to the QTSP when requesting a signature, the QTSP rejects the signature and requires an enrollment first. Alternatively, the QTSP may integrate a PID presentation into the QES authorization to create a short-lived qualified certificate for one signature creation without creating a user account at the QTSP. QTSP profiles are Wallet-internal and can contain information like: - name of the QTSP - access points for APIs - registered user ID (**client_id**) of the user at the QTSP - authentication credentials (EAA) issued by the QTSP to the user Wallet during enrollment QTSPs may support multiple user profiles for the same natural person with optional additional attributes, e.g., for commercial and private use. Interfaces and protocols used in the Wallet centric model: - **Relying Party --> Wallet: OpenID4VP with X.509 profile** (see [CSC DM]) to request the users signature for a document and to receive the signed document - **Wallet --> QTSP: CSC API v2** to request QES authorization and document signature by the QTSP, authorization is requested using the CSC API methods `oauth2/authorize` and `oauth2/token` - **QTSP --> Wallet: OID4VP with transaction data** for QES authorization by the user The OID4VP credential presentation to the QTSP to authorize the QES is part of the processing of the CSC / OAuth signature request from the Wallet to the QTSP. This situation is similar to the ["Presentation during Issuance"](../../archive/flows/Presentation-During-Issuance.md) for credential issuing. For better user experience, the same [OAuth 2.0 for First-Party Applications](https://www.ietf.org/archive/id/draft-parecki-oauth-first-party-apps-02.html) mechanism is used to pass the authorization request to the Wallet during the CSC signature flow. ### Sample Flow: Wallet-centric model - RP provided document #### Assumptions - Wallet-centric model, Signature Creation Application (SCA) is a part of the Wallet or Wallet backend - user is already enrolled to the QTSP: an EAA for user authentication is issued by the QTSP and stored in the QTSP profile in the Wallet, user gave consent to certificate creation, certificate is created or will be crated on demand - signature over document (SOD provided to the Wallet) #### Outline In this flow, the user selects a QTSP profile in the Wallet to request a QES for a document, provided to the Wallet by the DA. The Wallet sends an CSC / OAuth2 signature authorization request to the QTSP. The QTSP uses the OAuth 2.0 for First-Party Applications Mechanism to request the users EAA presentation with transaction data for QES authorization from the Wallet. the Wallet processes the authorization request, gets the user's authorization for the QES and presents the EAA from the QTSP enrollment with the transaction data hash. After verifying the presentation, the QTSP returns the CSC authorization code for the signature to the Wallet and the Wallet gets the signature (DSV) from the QTSP. #### Sequence diagram Below is a non-normative diagram illustrating the flow (it includes only the components relevant to the illustration of the flow described in this document): ```plantuml @startuml 'Lets define some common colors globally !$C_PRT = "#118888" !$C_ARG = "#daa520" !$C_VAR = "#daa520" 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [OID4VP] block !function oid4vp() !return "[OID4VP]" !endfunction 'Macro for colored [OID4VP X.509] block !function oid4vpx() !return "[OID4VP (X.509)]" !endfunction 'Macro for colored [Internal or QTSP specific] block !function iqtsp() !return "[Internal or QTSP specific]" !endfunction 'Macro for colored [CSC or other] block !function csco() !return "[CSC or other]" !endfunction 'Macro for colored [CSC/OAuth2] block !function cscoauth() !return "[CSC/OAuth2]" !endfunction 'Macro for colored block !function params($p) !return ""+ $p + "" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title QES creation: Wallet-centric flow with RP-provided document actor u as "User" participant b as "Browser App" participant r as "Relying Party\n----\nDA (Driving Application)" participant w as "EUDI Wallet Instance \n----\n OID4VP Wallet" #lightgreen participant s as "EUDI Wallet Instance \n----\n(OAuth 2.0 Client)\nSCA (Signature Creation Application)" #lightgreen participant as as "QTSP\n----\n (OAuth 2.0 Authorization Server)" participant rs as "QTSP\n----\n (OAuth 2.0 Resource Server)\n SSA (Server Signing Application)" u --> b : browse Driving Application b -> r : sign document r -> w : signing request (SOD) \n oid4vpx() note right : DCQL query for **X.509** credential format with transaction data of type **qes** hnote over w #dfd: Screen: Wallet request - pdf file w -> s : signing request u <--> s: Wallet profile/QTSP selection hnote over s #dfd: Screen: Wallet profile selection\n QTSP existing account s -> s : prepare authorization request (SOD to SDR, ...) s -> as : authorization request for signature (SDR, client_id) \n cscoauth() \n params(csc/v2/oauth2/authorize?...) as -> as: check if user with //client_id// \n is registered as -> as: prepare transaction data for signature authorization as -> as : create OID4VP Authorization Request for users EAA presentation with transaction data note over as #ddf: start OID4VP flow for EAA presentation with transaction data group EAA presentation during signature authorization as -> w : Authorization request oid4vp() note right : DCQL query for EAA presentation with transaction data of type **qes** for signature authorization u <--> w : user authorization to sign the document hnote over w #dfd: Screen: QTSP consent u <--> w : PIN entry hnote over w #dfd: Screen: Biometrics or PIN w -> w : generate VP token including \ntransaction data hash w -> as : Verifiable Presentation \n oid4vp() as -> as : verify VP token note left: Transaction data hash for signature authorization end note over as #ddf: end OID4VP flow for EAA presentation with transaction data as -> as : verify response as -> s : return authorization code cscoauth() s -> as : send authorization code to \n get access token \n cscoauth() \n params(csc/v2/oauth2/token) as -> s : return access token with the //"credential"// scope s <-> rs: retrieve QES certificate (access token ...) \n cscoauth() \n params(csc/v2/credentials/list) \n params(csc/v2/credentials/info) s -> s: compose DTBS \n and generate DTBSR s -> rs: send signature request \n (DTBSR + access token) \n cscoauth() \n params(csc/v2/signatures/signDoc) rs -> s : return signature (DSV) \n cscoauth() s -> s : compose signed document / SDO s -> w : signed document w -> r : credential presentation with signed document \n oid4vp() hnote over w #dfd: Screen: Success r -> b : signature successful hnote over r #dfd: Screen: RP final screen @enduml ``` ### Sample data *Disclaimer: Some attribute names and types are still in standardization, e.g., in CSC, and can possibly be subject of future changes.* #### Request RP -> Wallet ##### DCQL query ```json { "credentials":[ { "id":"certificate_by_policy", "format":"https://cloudsignatureconsortium.org/2025/x509" } ] } ``` ##### Transaction data ```json { "type":"https://cloudsignatureconsortium.org/2025/qes", "credential_ids":[ "certificate_by_policy" ], "numSignatures":1, "signatureQualifier":"eu_eidas_qes", "documentDigests":[ { "signature_format":"P", "conformance_level":"Ades-B-B", "signed_envelope_property":"Certification", "label":"Example Contract", "href":"https://protected.rp.example.com/contract-01.pdf?token=HS9naJKWwp901hBcK348IUHiuH8374", "checksum":"sha256-sTOgwOm+474gFj0q0x1iSNspKqbcse4IeiqlDg/HWuI=", "access":{ "type":"OTP", "oneTimePassword":"51623" } } ], "hashAlgorithmOID":"2.16.840.1.101.3.4.2.1" } ``` #### Response Wallet -> RP The response is a credential presentation containing the signed document as specified in the requests transaction data. Since the qualified signature already provides sufficient transaction data binding, and sufficient holder binding by the the qualified signature certificate issued by the QTSP, there is no need for a KB-JWT and transaction data hashes. ##### response ```json { "certificate_by_policy": { "documentWithSignature": [ "" ] } } ``` ## QTSP-centric Model ### User Experience Non-normative example for a one-shot certificate use case: - The Relying Party asks the user to sign a document. - The user scans a QR code and logs into the Wallet. - The user is asked by the Wallet to authorize the signature and to accept the T&C of the QTSP for the creation of a qualified signature certificate. - The user is prompted by the Wallet for a PID presentation. - The RP informs the user about the successful signature. ![User Journey: QTSP-centric model with one-shot certificate](../../../user_journeys/QTSP-centric-flow.png) ### Architecture Overview In the QTSP-centric model, the QTSP is the central actor for the signature flow. The SCA may be part of the RP, the QTSP, or provided by a 3rd party. Remark: There are several actors in the role of a RP in the QTSP-centric model: - In the overall architecture, the party hosting the Driving Application acts as a "Signature-RP" to get a document signed using an eIDAS trusted service. - From the Wallet's viewpoint, the QTSP acts as a "Wallet-RP" to get a signature authorization. A party hosting the DA may support both the Wallet-centric and QTSP-centric models. For consistency, the term RP is used for the DA environment in diagrams and flows. ```plantuml @startuml !include LAYOUT_TOP_DOWN() hide stereotype Person(user, "User") System_Boundary(ec, "QES Ecosystem") { package "RP environment" as RP { System_Ext(DA, "Driving Application") } package "RP or QTSP" as TR { System_Ext(SCA, "Signature Creation Application") } package "QTSP environment" as QTSP #lightgreen { System_Ext(SSA, "Server Signing Application") } package "EUDI Wallet Instance" as EUDIW { System_Ext(W, "OID4VP Wallet") System_Ext(SIC, "Signature Interaction Component") } } Rel_L(user, EUDIW, "Interacts with") Rel_L(user, DA, "(1) Interacts with") Rel_D(DA, SCA ,"(2) Signing \n Request", "internal or \n QTSP specific") Rel_D(SCA, SSA, "(3) Signing Request", "CSC or other") Rel_U(SSA, W, "(4) Certificate Creation / \n Signature Authorization \n Request" , OID4VP) Rel_R(W, SIC, "(5) Request user\nconfirmation") Rel_D(W, SSA, "(6) Confirmation / Authorization") Rel_U(SSA, SCA, "(7) Digital \nSignature Value") Rel_U(SCA, DA ,"(8) Signed Document") @enduml ``` *Figure 2: QTSP-centric model* The QTSP for a QES is chosen by the Relying Party. The user can be enrolled beforehand, including identification and the consent for certificate creation. Alternatively, the user identification by PID presentation can be part of the signature flow to create a short-lived qualified certificate for one signature creation without creating a user account at the QTSP. The RP sends the request to sign a document to the QTSP. The QTSP requests from the Wallet user a credential presentation (PID for identification or EAA from former enrollment) and includes transaction data for QES authorization. **Remark**: The PID presentation and QES authorization can be implemented as one or separate OID4VP authorization requests. After authorization, the QTSP generates the signature value, which is then integrated into the document by SCA at QTSP or RP. Interfaces used in this model: - **Relying Party --> QTSP: CSC API v2 or QTSP specific** to request the users signature for one / multiple documents and to return the Signed Data Object - **QTSP --> Wallet: OID4VP with transaction data** to authenticate / identify the user and activate the signature ### Sample Flow: QTSP-centric model with PID Presentation #### Assumptions - QTSP-centric model - Signature Creation Application (SCA) is part of the QTSP environment - On-the-fly signature without prior user enrollment - short-lived certificate created after PID presentation - user's consent is gathered using transaction data and the Wallet UI, not via the QTSP's web UI - signature over document (SOD provided to the QTSP) #### Outline In this flow, the QES is created using an authorization request with PID presentation. This request serves several purposes: - authorization of the user to sign a document (signature authorization) - user's consent to present the PID to the QTSP, which is necessary to create a qualified certificate - users consent for the QTSP to use this information to create a signing certificate The authorization request for PID presentation therefore includes two sets of transaction data that were created by the QTSP. When the Wallet processes the authorization request, the user gives consent to PID presentation and certificate creation and authorizes the signature based on the Signers Original Document (SOD) provided by the DA. No prior user enrollment is necessary. The transaction data hashes are included in the PID presentation to the QTSP. The QTSP issues a short-lived certificate to the user and uses it for the document signature. #### Sequence diagram Below is a non-normative diagram illustrating the flow (it includes only the components relevant to the illustration of the flow described in this document): ```plantuml @startuml 'Lets define some common colors globally !$C_PRT = "#118888" !$C_ARG = "#daa520" !$C_VAR = "#daa520" 'Ensure messages are not too wide skinparam maxMessageSize 200 skinparam wrapWidth 300 'Macro for colored [OID4VP] block !function oid4vp() !return "[OID4VP]" !endfunction 'Macro for colored [Internal or QTSP specific] block !function iqtsp() !return "[Internal or QTSP specific]" !endfunction 'Macro for colored [QTSP specific] block !function qtsps() !return "[QTSP specific]" !endfunction 'Macro for colored [CSC or other] block !function csco() !return "[CSC or other]" !endfunction 'Macro for colored block !function params($p) !return ""+ $p + "" !endfunction 'Align text on arrows to center skinparam sequenceMessageAlign center 'padding between boxes skinparam BoxPadding 100 autonumber "(000)" title QES creation: QTSP-centric flow with PID presentation actor u as "User" participant b as "Browser App" participant r [ Relying Party ---- DA (Driving Application) ] participant s as "QTSP \n----\nSCA (Signature Creation Application)" #lightgreen participant q as "QTSP\n----\nSSA (Server Signing Application)" #lightgreen participant w as "EUDI Wallet Instance" u --> b : browse Driving Application b -> r : sign document r -> s : signing request (SOD) \n iqtsp() s -> q : signing request (SODR) \n qtsps() q -> q : prepare transaction data for acceptance of signature authorization and QCert creation note over q #ddf: start OpenID4VP flow for PID Presentation with transaction data group PID presentation with transaction data q -> q : create OpenID4VP Authorization Request with transaction data,\nstore under q -> s : request_uri s -> r : request_uri opt r -> r : generate QR-code for cross-device end r -> b : request_uri / QR-code u --> b : action to start flow / launch Wallet b -> w : launch Wallet with request_uri // or Digital Credentials API // or scan QR-code for cross device hnote over w #dfd: Screen: launch_wallet u --> w : unlock Wallet hnote over w #dfd: Screen: unlock_wallet w -> q : Request the Request Object oid4vp() q -> w : Respond with Request Object oid4vp() note right : DCQL query for PID presentation with transaction data types **qes** for signature authorization and **qc-request** for user consent u <--> w : user authorization to sign the document hnote over w #dfd: Screen: QTSP Flow started u <--> w : user consent to QCert creation and acceptance of T&C hnote over w #dfd: Screen: QTSP consent u <--> w : user consent to present PID and PIN entry hnote over w #dfd: Screen: PID hnote over w #dfd: Screen: Enter PIN w -> w : generate VP token including \ntransaction data hashes w -> q : Verifiable Presentation \n oid4vp() q -> q : verify VP token note left: PID + transaction data hashes for signature authorization + QCert creation acceptance end note over q #ddf: end OpenID4VP flow for PID Presentation with transaction data q -> q : verify transaction data hashes q -> q : create signing certificate using PID group Signing Document s <-> q : sign document note over s,q: internal interaction between SCA and SSA end q -> s : return DSV s -> s : compose document / SDO s -> r : signing response (SDO) r -> b : signature successful @enduml ``` ### Sample data *Disclaimer: Some attribute names and types are still in standardization, e.g., in CSC, and can possibly be subject of future changes.* **OpenID4VP flow for PID Presentation with transaction data for user consent and QES activation** #### Request QTSP -> Wallet ##### DCQL query ```json { "credentials": [ { "id": "my_credential", "format": "dc+sd-jwt", "meta": { "vct_values": [ "urn:eudi:pid:1" ] }, "claims": [ {"path": ["given_name"]}, {"path": ["family_name"]}, {"path": ["birthdate"]}, {"path": ["place_of_birth"]["country"]}, {"path": ["place_of_birth"]["locality"]}, {"path": ["expiry_date"]} ] } ] } ``` ##### Transaction data Remark: The attribute `processID`my be used by the QTSP for a cryptographic binding between the requested QES authorization and the corresponding SDR at the QTSP. ```json [ { "type":"https://cloudsignatureconsortium.org/2025/qes", "credential_ids":["my_credential"], "numSignatures":1, "signatureQualifier":"eu_eidas_qes", "documentDigests":[ { "label":"Example Contract", "hashType":"sodr", "hash":"HZQzZmMAIWekfGH0/ZKW1nsdt0xg3H6bZYztgsMTLw0=" } ], "processID":"eOZ6UwXyeFLK98Do51x33fmuv4OqAz5Zc4lshKNtEgQ=", "transaction_data_hashes_alg":"sha-256" }, { "type":"https://cloudsignatureconsortium.org/2025/qc-request", "credential_ids":["my_credential"], "QC_terms_conditions_uri":"https://qtsp.example.com/policies/terms_and_conditions.pdf", "QC_hash":"ohxKcClPp/J1dI1iv5x519BpjduGZC794x4ABFeb+Ds=", "QC_hashAlgorithmOID":"2.16.840.1.101.3.4.2.1", "transaction_data_hashes_alg":"sha-256" } ] ``` #### Response Wallet -> QTSP ##### sd-jwt ```json { "exp": 1898949016, "iat": 1741269016, "iss": "https://pid-issuer.example.com", "nbf": 1741269016, "vct": "urn:eu.europa.ec.eudi:pid:1", "_sd": [ "ewgzkNuXusuMhykjisSRT4w-Oj2NVC9gvOFRbJ4X-OI", "zFxDfNErVeVKm9z9ctTyTLQ83lrD49T4gbJEMoGn3pc", "4fCywfbrmm6UgBmpmi-bxP466HJd-5O7WzYDf2v1RzM", "OQKiYuGyqcoeNnqnhpqqU2q6PJX8YpmxULs7rVB1ElU" ], "_sd_alg": "sha-256", "cnf": { "jwk": { "alg": "ES384", "crv": "P-384", "kty": "EC", "use": "sig", "x": "jpIk_Hc51OPM-8u4DZSHtocWZAtHJ7r9plYJu-NNW-kPhv1L-ige2k8X2rBNom-F", "y": "jV1CHkNSJ0Xa6K5an_28BD9Ivme4L7iXPRxWzTlyzQxg6VS9NCPc4xWUu-IcpZFO" } } } ``` ##### kb-jwt ```json { "aud": "https://qtsp.example.com/verifier", "iat": 1741269093, "nonce": "bUtJdjJESWdmTWNjb011YQ", "sd_hash": "Re-CtLZfjGLErKy3eSriZ4bBx3AtUH5Q5wsWiiWKIwY", "transaction_data_hashes": [ "605c9551a3dc2ec7ca4510c05fa9ed319de61b006ff615a97dbb6f5223f64b3d", "df485d584a07583414dec577e3601d2925ec6fdbb7d188419cb5894266e0ea2e" ], "transaction_data_hashes_alg": "sha-256" } ``` --- ## How to Read This Blueprint This document combines policy, governance, and technical architecture perspectives. The following guide aims to help readers find the sections most relevant to them. --- ## If you want to understand the overall idea Start with: - Ecosystem Vision & Fundamentals - Ecosystem Concepts - EUDI Value Proposition --- ## If you are responsible for governance or regulation Focus on [Governance & Operation Model](./content/ecosystem-vision-and-fundamentals/governance-and-operation-model.md) These chapters describe **rule-setting, onboarding, and supervision**, not technical validation. --- ## If you are implementing a wallet or relying party Focus on: - [Ecosystem Concepts](./content/ecosystem-concepts/introduction-and-goals.md) - [Trust → Validation](./content/ecosystem-concepts/trust/trust-validation.md) - [Wallet Relying Party Authentication](./content/ecosystem-concepts/trust/wallet-relying-party-authentication.md) These chapters describe **technical trust establishment and validation logic**. --- ## Trust, Governance, and Oversight — a clarification Trust validation in this blueprint refers to **local, cryptographic validation** performed by wallets and relying parties using trust lists and trust anchors. It is **not** a governance or supervisory activity. Governance defines _who may issue_. Trust validation defines _how artefacts are verified_. --- ## Appendix The appendix provides detailed flows and rulebooks referenced from the main chapters. It is not intended to be read linearly. --- ## Blueprint for the EUDI Wallet Ecosystem in Germany Everything you need to understand the architecture, trust model, governance, and core features of the German EUDI Wallet Ecosystem. ## Discover Ecosystem Fundamentals Understand the purpose, actors, value proposition, standards, and operating model of the German EUDI Wallet Ecosystem. Ecosystem Concepts Explore goals, constraints, building blocks, deployment concepts, security, privacy, and trust foundations. PID Read the German PID Rulebook and the current design decisions and runtime views for PID issuance and presentation. EAA Review credential anatomy, design recommendations, the catalogue of attestations, and EAA issuance and presentation flows. ## Integrate Developer Guide Find implementation-oriented onboarding, integration guidance, relying party material, issuer guidance, and sandbox resources. Wallet Architecture Dive into implementation-specific wallet architecture, technical flows, interfaces, and components. How to Read This Blueprint Use the reader guidance to find the sections most relevant to your role and level of technical depth. Trust Decision Guide Understand trust establishment and validation decisions across PID, EAA, QEAA, relying parties, and wallet components. ## About This Blueprint This document is part of Germany’s consultation process for implementing the EU Digital Identity Wallet (EUDIW). It proposes **architectural, governance, and operational models** for a national EUDI Wallet ecosystem that is interoperable across the EU while respecting Germany’s legal, technical, and institutional landscape. It is based on the **eIDAS 2.0 Regulation**, the **Architecture and Reference Framework (ARF)**, relevant **ETSI specifications**, national requirements, and identified use cases. The blueprint serves as a **discussion and design basis**, not as a final or binding specification. Future ARF updates and Implementing Acts may influence the final design. ## Audience This document is intended for: - policy makers and regulators - public and private service providers - wallet and relying party implementers - auditors and conformity assessment bodies - standards and ecosystem contributors - other interested parties or individuals that want to better understand the ecosystem Different sections are relevant depending on the reader’s role. :::info Looking for Wallet implementation details? This blueprint describes the **ecosystem and trust architecture**, not a concrete wallet implementation. Please refer to the [**Architecture Documentation of the German National EUDI Wallet**](https://bmi.usercontent.opencode.de/eudi-wallet/wallet-development-documentation-public) for implementation-specific architecture, flows, and interfaces. ::: ## Additional Links Glossary Look up key ecosystem, identity, credential, and trust terminology used throughout the blueprint. Feedback File feedback, questions, or proposed improvements for this blueprint on OpenCoDE. Repository Browse the source repository, contribution guidelines, and project history. ## Providing Feedback We welcome feedback on all aspects of this blueprint, including: - clarity and completeness of the descriptions - architectural soundness - security, privacy, and user experience considerations - operational feasibility and complexity Please file feedback as an [Issue on OpenCoDE](https://gitlab.opencode.de/bmi/eudi-wallet/eidas-2.0-architekturkonzept/-/issues). Contribution guidelines are available in [CONTRIBUTING.md](https://gitlab.opencode.de/bmi/eudi-wallet/eidas-2.0-architekturkonzept/-/blob/main/CONTRIBUTING.md). --- ## Change History All changes to this document are tracked in [CHANGELOG.md](https://gitlab.opencode.de/bmi/eudi-wallet/eidas-2.0-architekturkonzept/-/blob/main/CHANGELOG.md).