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. When the MDVM itself initiates a revocation, it marks the affected accounts directly, see wallet revocation by the MDVM.
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 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. |
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
- 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. Account records are only deleted upon an explicit account deletion requested by the user; 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
typas recommended by JWT BCP - JOSE Header
algindicating ECDSA NIST P-256 - JOSE Header
x5c: The X.509 Certificate chain of the MDVM service which authenticates mdvm_attestation_pubk - JWT Claim
isscontaining a URN to represent the current deployment environment, e.g. dev/staging/prod - JWT Claim
iatcontaining the issue time of the MDVM token - JWT Claim
expcontaining the expiry time of the MDVM token - JWT Claim
cnfcontaining the serialized wi_mdvm_auth_pubk
Below is a non-normative example of a mdvm_token:
Protected headers:
Payload:{
"iss": "german-national-wallet:mdvm:prod",
"iat": 1726126250,
"exp": 1726214250,
"cnf": {
"kty": "EC",
"crv": "P-256",
"x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
"y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
}
}
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.