Skip to content

6.2 MDVM Flows

Design Decision

  • stateful MDVM endpoint because:
    • plausibility checks
    • using iOS DeviceCheck attestation for every MDVM check likely are affected into rate limits imposed by Apple
    • using iOS DeviceCheck assertion is the only way to use attested hardware-backed keys to re-identify the wallet instance, but is inherently stateful
    • using iOS DeviceCheck assertion allows us to validate the usage counter
    • encapsulate Android/iOS-specific mechanisms to the MDVM endpoints, WB and RWSCA should have the same code path for Android/iOS
  • state-less design does not match with iOS device check attestation/assertion strategy
  • issuing short-lived tokens to avoid backend-to-backend calls that may impact scalability and performance
  • not using Android device-specific attestation key ("parent key" or "intermediate key") to associate all keys to a particular device, as it may not be sufficiently well supported across the Android ecosystem
    • we may re-consider this if we have better insight and resources to test this

Flows

The sequence diagrams for registering and issuance/renewal of an MDVM token is divided by WI operating system:

6.2.3 Revoke Account

In the Revoke Account operation, the MDVM marks the account of a Wallet Instance as revoked and triggers the WI to self-lock. When the MDVM itself initiates a revocation, it marks the affected accounts directly, see wallet revocation by the MDVM.

MDVM - Revoke AccountMessage Queue .MQ.Mobile DeviceMDVM account databaseMessage Queue (MQ)Message Queue (MQ)Mobile DeviceVulnerability Management(MDVM)Mobile DeviceVulnerability Management(MDVM)MDVM account databaseMDVM account database(001)fetch revocation event containing the JWKthumbprint of wi_mdvm_auth_pubk from therevocation queue(002)lookup mdvm_wi_id by the JWK thumbprint ofwi_mdvm_auth_pubk(003)mark mdvm_wi_state for mdvm_wi_id asREVOKED(004)publish push notification event containing theJWK thumbprint of wi_mdvm_auth_pubk tothe push notification queue(005)acknowledge the revocation event

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

No Description
001 The MDVM continuously fetches revocation events from the revocation queue. Each event contains the JWK thumbprint of a wi_mdvm_auth_pubk, which identifies the Wallet Instance across all backends, and triggers the Revoke Account operation.
002 The MDVM looks up the corresponding mdvm_wi_id in the MDVM account database using the JWK thumbprint of wi_mdvm_auth_pubk as the indexed lookup key. If no matching account is found, the MDVM ignores the event.
003 The MDVM marks the mdvm_wi_state for the mdvm_wi_id as REVOKED. A revoked account can no longer renew its MDVM token, see the renewal flows for Android and iOS. The account record is retained for traceability, see the MDVM account database.
004 The MDVM publishes a push notification event containing the JWK thumbprint of wi_mdvm_auth_pubk to the push notification queue. The Send Push Notification operation of the Push Notification Service consumes the event and delivers a push notification via the MPP to trigger the WI to confirm the revocation through a mdvm_token renewal attempt and self-lock, see Wallet Instance self-locking for details. The self-lock confirmation is decoupled from the processing of the revocation event: the account is already revoked in step (003), regardless of whether or when the WI confirms.
005 The MDVM 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.

6.2.4 Purge Account

In the Purge Account operation, the MDVM deletes the account record of a Wallet Instance and all related data. The operation is not exposed as an endpoint towards the WI; it is triggered by purge events that the MDVM continuously fetches from the purge queue. The MDVM itself is the producer of these events, as it identifies the Wallet Instances that exceeded the data retention period, see backend deletion.

MDVM - Purge AccountMessage Queue .MQ.Mobile DeviceMDVM account databaseMessage Queue (MQ)Message Queue (MQ)Mobile DeviceVulnerability Management(MDVM)Mobile DeviceVulnerability Management(MDVM)MDVM account databaseMDVM account database(001)fetch purge event containing the JWKthumbprint of wi_mdvm_auth_pubk(002)lookup mdvm_wi_id by the JWK thumbprint ofwi_mdvm_auth_pubk(003)delete all data for mdvm_wi_id(004)acknowledge the purge event

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

No Description
001 The MDVM continuously fetches purge events from the purge queue. Each event contains the JWK thumbprint of a wi_mdvm_auth_pubk, which identifies the Wallet Instance across all backends, and triggers the Purge Account operation.
002 The MDVM looks up the corresponding mdvm_wi_id in the MDVM account database using the JWK thumbprint of wi_mdvm_auth_pubk as the indexed lookup key. If no matching account is found, e.g. because the account has already been deleted, the MDVM ignores the event.
003 The MDVM deletes all data from the MDVM account database corresponding to the mdvm_wi_id, including the platform-specific attestation key material, the wi_device_class and the last-seen timestamp.
004 The MDVM 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.

MDVM Account Database

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

  • mdvm_wi_id
  • mdvm_wi_state (VALID, REVOKED) & timestamp of revocation event
  • last-seen timestamp (the most recent activity, e.g. renewal of the mdvm_token)
  • wi_mdvm_auth_pubk
  • JWK Thumbprint of wi_mdvm_auth_pubk
  • platform-specific attestation key material:
    • iOS: wi_devicecheck_pubk
    • Android: no additional key is persisted
  • platform-specific wi_device_class:
    • Android: attestationIdModel, attestationIdProduct, attestationIdDevice, osVersion, osPatchLevel, app versionCode
    • iOS: device model, operating system version

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

The last-seen timestamp is updated during the MDVM registration and on every successful renewal of the mdvm_token and is the basis for the retention-based deletion of the account records, see backend deletion.

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.

MDVM Token

The mdvm_token is an assertion by the MDVM about the security posture of the device. It is bound to a wi_mdvm_auth_prvk / wi_mdvm_auth_pubk key pair and attests to an expiry time. WB and RWSCA must fetch the valid mdvm_attestation_pubk out-of-band.

The mdvm_token contains:

  • JOSE Header typ as recommended by JWT BCP
  • JOSE Header alg indicating ECDSA NIST P-256
  • JOSE Header x5c: The X.509 Certificate chain of the MDVM service which authenticates mdvm_attestation_pubk
  • JWT Claim iss containing a URN to represent the current deployment environment, e.g. dev/staging/prod
  • JWT Claim iat containing the issue time of the MDVM token
  • JWT Claim exp containing the expiry time of the MDVM token
  • JWT Claim cnf containing the serialized wi_mdvm_auth_pubk
  • JWT Claim mdvm_wi_id containing the WI's account identifier at the MDVM, letting other backends re-use it instead of generating separate identifiers

Below is a non-normative example of a mdvm_token:

Protected headers:

{
  "typ": "mdvm-token+jwt",
  "alg": "ES256",
  "x5c": ["MIIDQjCCA..."]
}
Payload:
{
  "iss": "german-national-wallet:mdvm:prod",
  "iat": 1726126250,
  "exp": 1726214250,
  "cnf": {
      "kty": "EC",
      "crv": "P-256",
      "x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
      "y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
    },
  "mdvm_wi_id": "018f1a7e-9f3b-7c2a-8b3e-3a6c2e1f9d4b"
}

Signed by mdvm_attestation_prvk

Challenge JWT

Defined in Wallet Registration.

Proof of possessions

The wi_mdvm_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. mdvm_auth_challenge, mdvm_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 either MDVM registration or renewal.

The proof of possession also serves to assert the possession factor using the wi_mdvm_auth_prvk.

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