Skip to content

4 Wallet Provider Backend

This chapter describes the operations provided by the Wallet Provider Backend (WPB): the registration of a Wallet Instance, the issuance of Wallet Instance Attestations (WIA) and the deletion of a Wallet Instance's account. The registration is part of the broader wallet activation as introduced here.

Design Decisions

The WPB enables authenticated Wallet Instances to perform operations of the Wallet Instance's lifecycle. The WPB uses one-factor authentication to ensure integrity and authenticity of the requests sent by the Wallet Instance (WI):

  • The possession factor is based on a hardware-bound key pair from the Hardware-backed Key Store (HKS) of the WI, that is attested by the Mobile Device Vulnerability Management (MDVM). The MDVM issues MDVM tokens that attest to the general security posture of the mobile device. The WPB leverages the MDVM tokens to get assurance into the possession factor wi_mdvm_auth_prvk.

The WPB provides self-contained, short-lived challenges for replay protection. The WI uses the possession factor in a challenge-response pattern to authenticate and sign operation requests towards the WPB. Every request is signed by the possession factor itself, the WPB does not use session keys and does not store session state during an operation to reduce state for improved scalability. A challenge is one-time use and is only accepted for a single operation, therefore the WB stores the challenges that were used in a request until they expire.

During the Wallet activation, the WI requests the Create Account operation and the WPB generates a Wallet Instance identifier wpb_wi_id and stores it alongside the WI's possession factor in its account database. When the WI first interacts with a Credential Issuer, it requests the Create WIA operation to obtain a Wallet Instance Attestation (wpb_wia) for that Issuer, and requests it again to renew an expired WIA. An overview of supported operations is given in WPB Operations.

The Wallet Instance Attestation is a signed artifact generated by the Wallet Provider and presented towards PID and EAA Providers by the Wallet Instance. The wpb_wia is a short-lived JWT as defined in attestation-based client authentication, using an X.509 certificate chain as the trust mechanism for the WPB's signing key wpb_wia_auth_prvk, which is operated inside a Hardware Security Module (HSM, see WPB setup). Before issuing a WIA, the WPB verifies the security posture of the WI from the mdvm_token and that the WI has not been revoked by the user or the MDVM (see wallet revocation). The Wallet Instance generates a hardware-bound key pair (wi_wia_prvk, wi_wia_pubk) on the mobile device and transmits the public key to the WPB. The key generation must utilize the most secure key store available on the mobile device, such as a Secure Element, StrongBox, SecureEnclave or TEE. The wpb_wia is bound to the public key (wi_wia_pubk), the corresponding private key (wi_wia_prvk) is used to make a proof of possession towards the PID and EAA Providers.

The WIA is requested ad-hoc by the Wallet Instance before issuance and the WIA itself is a short-lived attestation. The WIA also contains a long-lived Status List entry wpb_wia_status, that the Credential Issuer may use to verify the security posture of the Wallet Instance in the future. The WIA may be revoked if:

The WPB references each wpb_wia_status by a backend-generated client instance identifier wpb_client_instance_id. The WI stores the mapping of Credential Issuer to wpb_client_instance_id and provides it on renewal, so that the WPB reuses the same Status List entry without the WI having to parse a previously issued wpb_wia.

4.1 WPB Operations

The WPB offers various operations that are each handled by dedicated endpoints. The operations have different authentication requirements, as listed in table below:

Operation Authentication Description
Create Account possession factor Create an account for a Wallet Instance by establishing a possession factor for authentication.
Create WIA possession factor Create a Wallet Instance Attestation (WIA) that attests the WI's authenticity and integrity.
Purge Account internal (purge queue) Delete all data that is stored or related to a wallet instance upon a purge event.
Revoke Account internal (revocation queue) Revoke the account of a Wallet Instance upon a revocation event, revoke all issued WIAs and trigger the WI to self-lock.

4.2 WPB Data Flows

This section described the data flow of the WPB Operations in a sequence diagram and a more detailed table. Artifacts in italics are further explained in the data register chapter.

4.2.1 Create Account

In the Create Account operation, the WI provides the MDVM token to authenticate and provide the attested public key as the possession factor for the new account at the WPB. As part of the same operation, the WPB generates the wpb_wi_revocation_code that the WI uses to set up the user-initiated wallet revocation. This operation is only performed once during wallet activation.

Wallet RegistrationWallet Instance . App .WI.Wallet Provider Backend .WPB.WPB account databaseMobile DeviceWallet Instance / App (WI)Wallet Provider Backend (WPB)WPB account databaseMobile DeviceVulnerability Management(MDVM)Wallet Instance / App (WI)Wallet Provider Backend (WPB)WPB account databaseMobile DeviceVulnerability Management(MDVM)(001)issuance or renewal of mdvm_token(002)</challengeEndpoint>()(003)generate wpb_auth_challenge: sign(nonce,timestamp)wpb_challenge_symk(004)<wpb_auth_challenge>(005)generate wi_wpb_auth_pop:sign(wpb_auth_challenge,mdvm_token)wi_mdvm_auth_prvk(006)</wbRegistrationEndpoint>(wi_wpb_auth_pop)(007)verify wpb_auth_challenge fromwi_wpb_auth_pop using wpb_challenge_symkand check one-time use(008)verify mdvm_token withmdvm_attestation_pubk to ensure deviceauthenticity and integrity(009)verify wi_wpb_auth_pop using includedwi_mdvm_auth_pubk from mdvm_token(010)generate unique wpb_wi_id and persist newwallet instance record with wpb_wi_id andwi_mdvm_auth_pubk(011)generate wpb_wi_revocation_secret:generate 128-bit randomness(012)update wpb_wi_id withHash(wpb_wi_revocation_secret)(013)calculate wpb_wi_revocation_code:Bech32("rev", wpb_wi_revocation_secret)(014)wpb_wi_id, wpb_wi_revocation_code(015)store wpb_wi_id, wpb_wi_revocation_code

The following table describes the steps of the sequence diagram in more detail:

No Description
001 The WI determines if its most recent mdvm_token is still valid. If the mdvm_token is not up-to-date, the WI may fetch a fresh one from the MDVM endpoint using the renewal flow for either Android or iOS.
002 - 004 The WI requests a challenge from the WPB challenge endpoint, the request is unauthenticated. The WPB generates a JSON structure containing a random nonce and a timestamp of the current time and MACs it using a symmetric key (wpb_challenge_symk) as a JSON Web Token (JWT), the resulting structure is the wpb_auth_challenge. The WPB responds to the WI with the wpb_auth_challenge in the HTTP payload. The WI uses the challenge as an opaque string and does not evaluate the JWT claims. The WPB does not store the challenge after creation, it only stores challenges when being used in a request to enforce its one-time use.
005 The WI re-uses the hardware-bound, attested cryptographic key pair (wi_mdvm_auth_prvk, wi_mdvm_auth_pubk) as the possession factor towards the WPB and computes a proof of possession by signing the wpb_auth_challenge for freshness and to enable replay protection and the mdvm_token to provide the possession factor and proof of device authenticity and integrity. The WI signs the proof of possession with the wi_mdvm_auth_prvk. The resulting structure is called wi_wpb_auth_pop.
006 The WI requests the WPB to perform the registration and sends the wi_wpb_auth_pop to the WPB's registration endpoint. The request is unauthenticated (as WPB does not know the WI yet at registration).
007 The WPB verifies the self-contained wpb_auth_challenge using its wpb_challenge_symk and validating that the timestamp is within a valid time interval as specified in the token lifecycle section of the cryptography chapter. The WB maintains a database to enforce one-time use of the wb_auth_challenge: it validates a new challenge is not yet in the database, then it inserts the new challenge, the challenge is then removed from the database after its expiration. This step ensures replay protection within and beyond the valid time interval of the challenge.
008 - 009 The WPB verifies the received mdvm_token with mdvm_attestation_pubk for authenticity and integrity and checks that it is still valid. The WPB has a trusted, out-of-band mechanism towards the MDVM to fetch the valid mdvm_attestation_pubk. The WPB verifies the received proof of possession for the WI's possession factor (wi_wpb_auth_pop) using the included wi_mdvm_auth_pubk from the mdvm_token. Lastly, the WPB verifies that the used key wi_mdvm_auth_pubk is the same in wi_wpb_auth_pop and mdvm_token.
010 The WPB generates a unique Wallet Instance identifier wpb_wi_id and stores the combination of wpb_wi_id and wi_mdvm_auth_pubk in its database to register the new WI.
011 The WPB generates the revocation secret wpb_wi_revocation_secret from 128 bits of random, ensuring a sufficiently secure random generator is being used.
012 The WPB updates the WPB account database to store the hash of the wpb_wi_revocation_secret for Wallet Instance account wpb_wi_id that was authenticated in the request. The WPB stores the hash using a single, unsalted SHA-256 computation over the raw wpb_wi_revocation_secret. A computationally expensive, memory-hard key derivation function (such as Argon2id) is not required here: the wpb_wi_revocation_secret already carries 128 bits of entropy and is generated by the WPB rather than chosen by the user, so it is infeasible to brute-force regardless of the speed of the hash. For the same reason no salt is needed, as each secret is unique and high-entropy, which rules out rainbow-table and cross-account attacks. Using a fast hash avoids exhausting CPU and memory resources during onboarding peaks, when many wallet registrations are processed in parallel. Storing the hash instead of the plain wpb_wi_revocation_secret prevents attackers to revoke arbitrary Wallet Instances in case of a database leak.
013 The WPB calculates the Bech32 encoding using rev for the human readable header part, 1 as the default separator character and the concatenated, raw binary representation of (un-hashed!) wpb_wi_revocation_secret. Calculating this string in the backend avoid complexity of keeping the code in sync between backend, Android and iOS implementation. The resulting string is the wpb_wi_revocation_code.
014 The WPB responds with the generated Wallet Instance identifier wpb_wi_id and the wpb_wi_revocation_code to the WI.
015 The WI stores the received Wallet Instance identifier wpb_wi_id and the wpb_wi_revocation_code. The WI then sets up the user-initiated wallet revocation by offering the user options to store the wpb_wi_revocation_code.

4.2.2 Create WIA

The sequence diagram contains two flows marked as alternatives when they diverge:

1) In the initial WIA issuance operation, the WI requests a Wallet Instance Attestation for the very first interaction with a new Credential Issuer. The green section describes steps that are only relevant for this flow. 2) In the WIA renewal operation, the WI requests to get an updated WIA for a Credential Issuer that it already interacted with in the past. The pink section describes steps that are only relevant for this flow.

Issuance of Wallet Instance Attestation (WIA)Wallet Instance . AppWallet Provider BackendWPB account databaseHardware Security ModuleMobile DeviceWallet Instance / App(WI)Wallet Provider Backend(WPB)WPB account databaseHardware Security Module(HSM)Mobile DeviceVulnerability Management(MDVM)Wallet Instance / App(WI)Wallet Provider Backend(WPB)WPB account databaseHardware Security Module(HSM)Mobile DeviceVulnerability Management(MDVM)(001)renewal of mdvm_token(002)</challengeEndpoint>()(003)generate wpb_auth_challenge: sign(nonce,timestamp)wpb_challenge_symk(004)<wpb_auth_challenge>(005)generate client attestation key pair(wi_wia_prvk, wi_wia_pubk)(006)look-up mapping of Credential Issueridentifier to wpb_client_instance_id(007)generate wi_wpb_auth_pop: sign(wpb_wi_id,wpb_auth_challenge, mdvm_token,wi_wia_pubk,<back:#fef>wpb_client_instance_id</back>)wi_mdvm_auth_prvk,wi_wia_prvkwpb_client_instance_id is only provided inWIA renewal flow(008)</wiaEndpoint> (wi_wpb_auth_pop)(009)verify wpb_auth_challenge fromwi_wpb_auth_pop using wpb_challenge_symkand check one-time use(010)verify mdvm_token withmdvm_attestation_pubk to ensure deviceauthenticity and integrity of the WI(011)lookup wi_mdvm_auth_pubk from thedatabase using wpb_wi_id(012)match wi_mdvm_auth_pubk contained inmdvm_token with database(013)verify wi_wpb_auth_pop usingwi_mdvm_auth_pubk(014)verify wi_wpb_auth_pop using wi_wia_pubk(015)check wpb_wi_state if the wallet instance isrevoked by the user or MDVMalt[initial WIA issuance](016)generate a new wpb_client_instance_id andstatuslist entry wpb_wia_status(017)store wpb_wia_status for (wpb_wi_id,wpb_client_instance_id)[WIA renewal](018)look-up wpb_wia_status for (wpb_wi_id,wpb_client_instance_id)(019)prepare payload for wpb_wia and callPKCS#11 C_SignInit and C_Sign to generatesignature: wpb_wia sign(wi_wia_pubk,wpb_wia_status)wpb_wia_auth_prvk(020)wpb_wia, wpb_client_instance_idalt[initial WIA issuance](021)store mapping of wpb_client_instance_id forCredential Issuer identifier

The following table describes the steps of the sequence diagram in more detail:

No Description
001 The WI determines if its most recent mdvm_token is still valid. If the mdvm_token is not up-to-date, the WI may fetch a fresh one from the MDVM endpoint using the renewal flow for either Android or iOS.
002 - 004 The WI requests a challenge from the WPB challenge endpoint using an HTTP POST request, the request is unauthenticated. The WPB generates a JSON structure containing a random nonce and a timestamp of the current time and MACs it using a symmetric key (wpb_challenge_symk) as a JSON Web Token (JWT), the resulting structure is the wpb_auth_challenge. The WPB responds to the WI with the wpb_auth_challenge in the HTTP payload. The WI uses the challenge as an opaque string and does not evaluate the JWT claims. The WPB does not store the challenge after creation, it only stores challenges when being used in a request to enforce its one-time use.
005 The WI generates a new hardware-bound key pair (wi_wia_prvk, wi_wia_pubk) which is used as the client attestation key for the wallet attestation (WIA). The WI must leverage the most secure, local key storage available, i.e. a Secure Element, StrongBox, SecureEnclave or TEE. The key must have sufficient security, information on algorithms and key lengths can be found in the cryptography chapter.
006 The WI performs a look-up in its internal mapping of Credential Issuer identifier to the backend-generated client instance identifier wpb_client_instance_id. If the WI already interacted with this Credential Issuer before, it finds the wpb_client_instance_id that it stored in Step 021 and the operation is a WIA renewal; otherwise no mapping exists and the operation is an initial WIA issuance. Using the wpb_client_instance_id instead of the wpb_wia_status avoids that the WI has to parse a previously issued wpb_wia.
007 The WI computes a proof of possession by signing the payload of wpb_wi_id for identification, wpb_auth_challenge for freshness and to enable replay protection, the mdvm_token to ensure authenticity and integrity of the WI, the client attestation public key wi_wia_pubk and — only in the WIA renewal operation — the wpb_client_instance_id of the previous interaction, with
  • the possession factor wi_mdvm_auth_prvk
  • the client attestation private key wi_wia_prvk
The resulting structure is called wi_wpb_auth_pop.
008 The WI requests the WPB to issue a WIA by sending the proof of possession (wi_wpb_auth_pop) to the WIA endpoint. The request is authenticated.
009 The WPB verifies the self-contained wpb_auth_challenge included in the wi_wpb_auth_pop using its symmetric key (wpb_challenge_symk) and validating that the timestamp is within a valid time interval as specified in the token lifecycle section of the cryptography chapter. The WB maintains a database to enforce one-time use of the wb_auth_challenge: it validates a new challenge is not yet in the database, then it inserts the new challenge, the challenge is then removed from the database after its expiration. This step ensures replay protection within and beyond the valid time interval of the challenge.
010 - 013 The WPB validates the security posture of the WI by verifying the mdvm_token with mdvm_attestation_pubk and checks that it is still valid. The WPB has a trusted, out-of-band mechanism towards the MDVM to fetch the valid mdvm_attestation_pubk. The WPB fetches the public key for the possession factor wi_mdvm_auth_pubk from the database using the provided account identifier wpb_wi_id included in wi_wpb_auth_pop. The WPB verifies the signature of the received proof of possession (wi_wpb_auth_pop) for the WI's possession factor using wi_mdvm_auth_pubk from the mdvm_token. Lastly, the WPB verifies that the used key wi_mdvm_auth_pubk is the same in mdvm_token and in the database. The database lookup is not subject to prevention of distributed denial of service attacks, as these attacks need to be mitigated further up in the infrastructure layer.
014 The WPB verifies the second signature of the proof of possession wi_wpb_auth_pop using the included wi_wia_pubk.
015 The WPB queries the revocation state wpb_wi_state from its database to validate that the user did not revoke its WI. If the state is not "VALID", the request is aborted. This step ensures that a revoked WI cannot receive new WIAs to prevent further issuances.
016 - 017 Steps 016 - 017 only occur in the initial WIA issuance operation
The WPB generates a new client instance identifier wpb_client_instance_id and chooses a new, un-used Status List entry wpb_wia_status for the WIA to be created. The WPB then stores the wpb_wia_status under the combination of (wpb_wi_id, wpb_client_instance_id) in its database, so that it can retrieve the same Status List entry for future renewals without parsing a previously issued wpb_wia.
018 Step 018 only occurs in the WIA renewal operation
The WPB looks up the existing Status List entry wpb_wia_status for the combination of (wpb_wi_id, wpb_client_instance_id) provided in the wi_wpb_auth_pop, so that the renewed wpb_wia reuses the same Status List entry.
019 The WPB generates a Wallet Instance Attestation wpb_wia by signing the provided public key wi_wia_pubk and the status entry wpb_wia_status using its wpb_wia_auth_prvk using PKCS#11 function C_SignInit and C_Sign. As the wpb_wia_auth_prvk is a long-term key stored in the HSM, it does not need to be imported or destroyed. The resulting wpb_wia assures the Issuer that the corresponding Wallet Instance is a valid client of the wallet solution, the particular WI's security posture is attested by the WPB and that the user did not revoke its WI. The Issuer later fetches the wpb_wia_auth_pubk from a trust list to verify the wpb_wia.
020 The WPB returns the Wallet Instance Attestation wpb_wia together with the wpb_client_instance_id to the WI. Returning the wpb_client_instance_id on every operation keeps the response uniform and allows the WI to store or confirm the mapping without parsing the wpb_wia.
021 Step 021 only occurs in the initial WIA issuance operation
The WI stores the mapping of the Credential Issuer identifier to the received wpb_client_instance_id, so that it can provide the wpb_client_instance_id in future WIA renewal operations (see Step 006 and Step 007).

4.2.3 Purge Account

In the Purge Account operation, the WPB deletes the wallet instance record and all related data. The operation is not exposed as an endpoint towards the WI; it is triggered by purge events that the WPB continuously fetches from the purge queue, once a Wallet Instance has exceeded the data retention period, see backend deletion.

Purge AccountMessage Queue .MQ.Wallet Provider Backend .WPB.WPB account databaseMessage Queue (MQ)Wallet Provider Backend (WPB)WPB account databaseMessage Queue (MQ)Wallet Provider Backend (WPB)WPB account database(001)fetch purge event containing thewi_mdvm_auth_pubk_jkt(002)lookup wpb_wi_id by thewi_mdvm_auth_pubk_jkt(003)delete all data for wpb_wi_id(004)acknowledge the purge event

The following table describes the steps of the sequence diagram in more detail:

No Description
001 The WPB continuously fetches purge events from the purge queue. Each event contains the wi_mdvm_auth_pubk_jkt, which identifies the Wallet Instance across all backends, and triggers the Purge Account operation.
002 The WPB looks up the corresponding wpb_wi_id in the WPB account database using the wi_mdvm_auth_pubk_jkt as the indexed lookup key. If no matching account is found, e.g. because the account has already been deleted, the WPB ignores the event.
003 The WPB deletes all data from the WPB account database corresponding to the wpb_wi_id, including the hash of the wpb_wi_revocation_secret, so that the wpb_wi_revocation_code of the user becomes invalid, and the mapping of wpb_client_instance_id to wpb_wia_status.
004 The WPB acknowledges the purge event only after the account has been successfully deleted. Events that are not acknowledged are redelivered by the purge queue and reprocessing them is idempotent, as the deletion of an already deleted account has no further effect.

4.2.4 Revoke Account

In the Revoke Account operation, the WPB revokes the account of a Wallet Instance together with all Wallet Instance Attestations issued to it. The operation is not exposed as an endpoint towards the WI; it is triggered by revocation events that the WPB continuously fetches from the revocation queue, see revocation propagation between backends.

Revoke AccountMessage Queue .MQ.Wallet Provider Backend .WPB.WPB account databaseMessage Queue (MQ)Wallet Provider Backend (WPB)WPB account databaseMessage Queue (MQ)Wallet Provider Backend (WPB)WPB account database(001)fetch revocation event containing thewi_mdvm_auth_pubk_jkt(002)lookup wpb_wi_id by thewi_mdvm_auth_pubk_jkt(003)iterate through all issued wpb_wia andrevoke wpb_wia_status(004)mark the wpb_wi_state for wpb_wi_id asREVOKED(005)acknowledge the revocation event

The following table describes the steps of the sequence diagram in more detail:

No Description
001 The WPB continuously fetches revocation events from the revocation queue. Each event contains the wi_mdvm_auth_pubk_jkt, which identifies the Wallet Instance across all backends, and triggers the Revoke Account operation.
002 The WPB looks up the corresponding wpb_wi_id in the WPB account database using the wi_mdvm_auth_pubk_jkt as the indexed lookup key. If no matching account is found, the WPB ignores the event.
003 The WPB invalidates the status list entries of all WIAs (wpb_wia_status) that were previously issued to the wpb_wi_id by setting the status list values to INVALID. This initiates the revocation chaining towards the PID/EAA Providers.
004 The WPB marks the wpb_wi_state for the wpb_wi_id as REVOKED. The WPB subsequently rejects any further authentication of the revoked Wallet Instance. The account record is retained for traceability, see the WPB account database.
005 The WPB acknowledges the revocation event only after the account has been successfully revoked. Events that are not acknowledged are redelivered by the revocation queue and reprocessing them is idempotent, see revocation propagation between backends.

4.3 WPB Setup

The WPB uses a Hardware Security Module (HSM) for the following use cases:

  • wpb_wia_auth_prvk (used to sign the Wallet Instance Attestations)

The WPB and the HSM uses mutual TLS to encrypt and authenticate their communication. Additionally, the PKCS#11 C_Login operation is used to authenticate to a specific HSM partition. The WPB uses PKCS#11 as the API to send requests to the HSM.

4.4 WPB Account Database

The WPB account database stores the necessary information for each Wallet Instance's account:

  • wpb_wi_id
  • wi_mdvm_auth_pubk
  • wi_mdvm_auth_pubk_jkt
  • Hash(wpb_wi_revocation_secret)
  • wpb_wi_state (VALID, REVOKED) & timestamp of revocation event
  • mapping of wpb_client_instance_id to wpb_wia_status

Access to the database is secured by mutual TLS to encrypt and authenticate communication to the WPB.

Account records are deleted by the Purge Account operation once the Wallet Instance exceeded the data retention period, see backend deletion; on a revocation event the record is retained for traceability.

4.5 Wallet Instance Attestation

The wpb_wia is a signed attestation of the Wallet Provider backend, attesting to the validity of the Wallet Instance towards Issuers and Relying Parties. The format is described in Section 5.1 of attestation-based client authentication and further profiled in ETSI 119 476-3. According to these rules, the wpb_wia contains:

  • JOSE Header typ: The type oauth-client-attestation+jwt identifying the JWT
  • JOSE Header alg: A digital signature algorithm identifier for the signing key wpb_wia_auth_prvk, see cryptographic primitives for algorithm choice
  • JOSE Header x5c: The X.509 certificate chain containing wpb_wia_auth_pubk in the leaf certificate and providing a chain to the trust list
  • JWT Claim iss: The Issuer claim of the Wallet Provider Backend (this is included as a backwards compatibility for Draft-07)
  • JWT Claim sub: The client_id of the Wallet Provider Backend
  • JWT Claim iat: Issuance date of the WIA token
  • JWT Claim exp: Expiration date of the WIA token, see token lifecycle
  • JWT Claim cnf: The serialized wi_wia_pubk in JWK format, see cryptographic primitives for algorithm choice
  • JWT Claim client_status: Status information wpb_wia_status about the authenticity and integrity of the Wallet Instance according to ETSI 119 476-3
    • JWT Claim status: status information about the authenticity and integrity of the Wallet Instance
      • JWT Claim status_list: status information as a Status List
        • JWT Claim uri: URI that links to the Status List Token
        • JWT Claim idx: index within the Status List Token that represents the status of the WI
    • JWT Claim exp: Expiration date of the status information (guaranteed maintenance time by the Wallet Provider), see token lifecycle

Below is a non-normative example of a wpb_wia:

Protected headers:

{
  "typ": "oauth-client-attestation+jwt",
  "alg": "ES256",
  "x5c": [
    "MIIBETCBuQIJAM6k5TM9MgHEMAkGByqGSM49BAEwEjEQMA4GA1UEAwwHdGVzdC5kZTAeFw0yNDExMTExMjMwMTRaFw0yNTExMTExMjMwMTRaMBIxEDAOBgNVBAMMB3Rlc3QuZGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATQivHxcyv56XIfjt6EeyekabQ44oXSvplQXwE42c5SKheiZyhKfjhATMdpNQKV+2WnNX28Dwlv/mBQkA2pPe98MAkGByqGSM49BAEDSAAwRQIgcn7PP74vJ82nUxVQA4nt++IzWK+xYX2jGe9oh/5R9CICIQCsCjry+BL5biHKY6Pp8hUSsGqpMCV2uza/lhq4C4RoWg=="
  ]
}
Payload:
{
  "iss": "german-national-wallet:wpb:prod",
  "sub": "de.bmi.eudi-wallet.wallet-provider-backend",
  "iat": 1750742508,
  "exp": 1750828908,
  "cnf": {
    "jwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "32jtyqhBGxKxqeihaRsmW449oB9hcMUSgNCxDjHfADo",
      "y": "3ARvwMghvfz7zAcGEdwQj2h5DQU64BezdaSthn7qJzk"
    }
  },
  "client_status": {
    "status" : {
      "status_list" : {
        "uri" : "https://wallet-provider-backend.eudi-wallet.de/status/0953e816-c84e-4ae4-a955-d2190552f21b",
        "idx" : 5217
      }
    },
    "exp": 1756099308
  }
}

Signed by wpb_wia_auth_prvk

Token Status List

The wpb_wia_status references a Status List entry that is published by the WPB as a Status List Token wpb_wia_tsl. The Credential Issuer dereferences the uri from the wpb_wia to fetch the wpb_wia_tsl and reads the bit at position idx to determine the current status of the Wallet Instance. The wpb_wia_tsl is a long-lived token that the WPB re-issues periodically to update the status of all referenced Wallet Instances and to refresh its validity, see token lifecycle.

The wpb_wia_tsl is defined by Token Status List in JWT format, using the an X.509 certificate chain as the trust mechanism for the WPB's signing key wpb_wia_tsl_prvk. According to these rules, the wpb_wia_tsl contains:

  • JOSE Header typ: The type statuslist+jwt identifying the Status List Token
  • JOSE Header alg: A digital signature algorithm identifier for the signing key wpb_wia_tsl_prvk, see cryptographic primitives for algorithm choice
  • JOSE Header x5c: The X.509 certificate chain containing wpb_wia_tsl_pubk in the leaf certificate and providing a chain to the trust list
  • JWT Claim sub: The URI of the Status List Token, identical to the uri referenced in the wpb_wia
  • JWT Claim iss: The wpb_client_id of the Wallet Provider Backend
  • JWT Claim iat: Issuance date of the Status List Token
  • JWT Claim exp: Expiration date of the Status List Token, see token lifecycle
  • JWT Claim ttl: Time Duration how often the Token Status List i refreshed, see token lifecycle
  • JWT Claim status_list: The Status List itself
    • JWT Claim bits: The number of bits per referenced token, 1 is used to encode the valid/revoked status of the Wallet Instance
    • JWT Claim lst: The base64url-encoded, DEFLATE-compressed byte array holding the status of all referenced Wallet Instances
    • JWT Claim aggregation_uri: URI linking to the Status List Aggregation endpoint of the WPB, allowing a Credential Issuer to retrieve the URIs of all Status List Tokens (wpb_wia_tsl) published by the WPB in a single application/json document (a status_lists array of URI strings). Fetching and caching the complete set this way preserves the privacy of the Wallet Instance, as the WPB cannot observe which individual wpb_wia_status a Credential Issuer dereferences.

Below is a non-normative example of a wpb_wia_tsl:

Protected headers:

{
  "typ": "statuslist+jwt",
  "alg": "ES256",
  "x5c": [
    "MIIBETCBuQIJAM6k5TM9MgHEMAkGByqGSM49BAEwEjEQMA4GA1UEAwwHdGVzdC5kZTAeFw0yNDExMTExMjMwMTRaFw0yNTExMTExMjMwMTRaMBIxEDAOBgNVBAMMB3Rlc3QuZGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATQivHxcyv56XIfjt6EeyekabQ44oXSvplQXwE42c5SKheiZyhKfjhATMdpNQKV+2WnNX28Dwlv/mBQkA2pPe98MAkGByqGSM49BAEDSAAwRQIgcn7PP74vJ82nUxVQA4nt++IzWK+xYX2jGe9oh/5R9CICIQCsCjry+BL5biHKY6Pp8hUSsGqpMCV2uza/lhq4C4RoWg=="
  ]
}
Payload:
{
  "iss": "de.bmi.eudi-wallet.wallet-provider-backend",
  "sub": "https://wallet-provider-backend.eudi-wallet.de/status/0953e816-c84e-4ae4-a955-d2190552f21b",
  "iat": 1750742508,
  "exp": 1750828908,
  "ttl": 1800,
  "status_list": {
    "bits": 1,
    "lst": "eNpjYBgFo2AUQAAAAw4AAQ",
    "aggregation_uri": "https://wallet-provider-backend.eudi-wallet.de/status/aggregation"
  }
}

Signed by wpb_wia_tsl_prvk

Wallet Challenge JWT

The wpb_auth_challenge encapsulates a verifiable challenge, that is generated and verified by the WPB. As the producer and consumer is the WPB, a MAC key wpb_challenge_symk is used for efficiency reasons to ensure the integrity and authenticity of the challenge.

The wpb_auth_challenge contains:

  • JOSE Header typ: as recommended by JWT BCP
  • JOSE Header alg: indicating HMAC-SHA256 as MAC algorithm
  • JOSE Header kid: containing a key identifier for wpb_challenge_symk
  • JWT Claim iss: containing the name of service which issued the challenge
  • JWT Claim nonce: containing at least 128 bits of random
  • JWT Claim iat current time, indicating the issuance date

Below is a non-normative example of a wpb_auth_challenge:

Header

{
  "typ": "auth-challenge+jwt",
  "alg": "HS256",
  "kid": "1"
}
Payload
{
  "iss": "german-national-wallet:wallet:prod",
  "nonce": "564edacb-ad81-420c-a74e-6cfbaa713d48",
  "iat": 1726214250
}

Signed by wpb_challenge_symk

Proof of possessions

The wi_wpb_auth_pop is a proof of possession encoded as an HTTP Message Signature. The signature includes the HTTP path and all assets mentioned in the sequence diagrams (e.g. wpb_auth_challenge, wpb_wi_id, ...), signed as either a JSON structure in the HTTP body or in HTTP header. The signed HTTP path component serves as an identifier for the WPB operations.

The proof of possession serves to assert the possession factor using the wi_mdvm_auth_prvk. In the Create WIA operation, the wi_wpb_auth_pop is additionally signed with the freshly generated client attestation key wi_wia_prvk to prove possession of wi_wia_pubk and to bind it to the request. This is realized by multi-signing the same payload with both keys.

Additional details on proof of possessions using HTTP Message signatures, will be added in a dedicated section.