Wallet Attestation¶
The Wallet Attestation containing details about the Wallet Instance and the device's security level where the Wallet Instance is installed. It generally attests the authenticity, integrity, security, privacy, and trust of a specific Wallet Instance. The Wallet Attestation MUST contain a Wallet Instance public key.
General Properties¶
The Wallet Attestation:
MUST be issued and MUST be signed by Wallet Provider;
MUST give all the relevant information to attests the integrity and security of the device where the Wallet Instance is installed.
It is necessary for each Wallet Instance to obtain a Wallet Attestation before entering the Operational state.
Requirements¶
The following requirements for the Wallet Attestation are met:
The Wallet Attestation MUST use the signed JSON Web Token (JWT) format.
The Wallet Provider MUST offer a RESTful set of services for issuing the Wallet Attestations.
The Wallet Attestation MUST be securely bound to the Wallet Instance public key (Holder Key Binding).
The Wallet Attestation MUST be issued and signed by an accredited and reliable Wallet Provider, thereby providing integrity and authenticity to the attestation.
The Wallet Attestation MUST ensure the integrity and authenticity of the Wallet Instance, verifying that it was accurately created and provided by the Wallet Provider.
Each Wallet Instance SHOULD be able to request multiple attestations with different public keys associated to them. This requirement provides a privacy-preserving measure, as the public key MAY be used as a tracking tool during the presentation phase (see also the point number 10, listed below).
The Wallet Attestation SHOULD be usable multiple times during its validity period, allowing for repeated authentication and authorization without the need to request new attestations with each interaction.
The Wallet Attestation SHOULD have an expiration date time, after which it will no longer be considered valid.
When the private key associated with the Wallet Instance is lost or deleted, the attestation MUST become invalid to prevent unauthorized use of the Wallet Instance.
High-level Design¶
Static Component View¶
Dynamic Component View¶
This section describes the Wallet Attestation format and how the Wallet Provider issues it.
Message 1: The User starts the Wallet Instance mobile app and gets authenticated to it.
Message 2: The Wallet Instance verifies the Wallet Provider's trustworthiness by evaluating its Trust Chain.
Message 3-4: The Wallet Instance retrieves the Wallet Provider metadata, including the list of supported algorithms, public keys, and endpoints.
Message 5: The Wallet Instance generates a new key pair.
Message 6-7: The Wallet Instance requests a
nonce
from the App Attestation Service.Message 8: The Wallet Instance creates a Wallet Attestation Request in JWS format, signed with the private key associated with the public key for which it request the attestation.
Message 9-13: The Wallet Instance provides the Wallet Attestation Request to the Wallet Provider, which validates it and returns a signed attestation to the Wallet Instance.
Message 13-14: The Wallet Instance receives the Wallet Attestation signed by the Wallet Provider and performs security and integrity verifications.
Message 15: The Wallet Attestation is now ready for use.
Detailed Design¶
The detailed design is explained below.
Wallet Attestation Request¶
To obtain a Wallet Attestation from the Wallet
Provider it is necessary to send a Wallet Attestation
Request from the Wallet Instance containing the associated public key
, the nonce
value provided by the App Attestation Service and a jti
value.
The Wallet Instance MUST do an HTTP request to the Wallet Provider's token endpoint, using the method POST.
The token endpoint (as defined in RFC 7523 section 4) requires the following parameters
encoded in application/x-www-form-urlencoded
format:
grant_type
set tourn:ietf:params:oauth:grant-type:jwt-bearer
;assertion
containing the signed JWT defined in the Section Wallet Attestation Request.
Below a non-normative example of the HTTP request.
POST /token HTTP/1.1
Host: wallet-provider.example.org
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer
&assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6ImtoakZWTE9nRjNHeGRxd2xVTl9LWl83NTVUT1ZEbmJIaDg2TW1KcHh2a1UifQ.eyJpc3MiOiAidmJlWEprc000NXhwaHRBTm5DaUc2bUN5dVU0amZHTnpvcEd1S3ZvZ2c5YyIsICJhdWQiOiAiaHR0cHM6Ly93YWxsZXQtcHJvdmlkZXIuZXhhbXBsZS5vcmciLCAianRpIjogImY1NjUyMDcyLWFiZWYtNDU5OS1iODYzLTlhNjkwNjA3MzJjYyIsICJub25jZSI6ICIuLi4uLiIsICJjbmYiOiB7Imp3ayI6IHsiY3J2IjogIlAtMjU2IiwgImt0eSI6ICJFQyIsICJ4IjogIjRITnB0SS14cjJwanlSSktHTW56NFdtZG5RRF91SlNxNFI5NU5qOThiNDQiLCAieSI6ICJMSVpuU0IzOXZGSmhZZ1MzazdqWEU0cjMtQ29HRlF3WnRQQklScXBObHJnIiwgImtpZCI6ICJ2YmVYSmtzTTQ1eHBodEFObkNpRzZtQ3l1VTRqZkdOem9wR3VLdm9nZzljIn19LCAiaWF0IjogMTY5MTQ4ODk2MiwgImV4cCI6IDE2OTE0OTYxNjJ9.Dg_yFaiv6lVftR3FFx0v5JW250mBgXLVP1j0ezZcHRyitqSY7xGmx4y-MGur93FAS85vf_Da-L-REVEltwU2Jw
The response is the Wallet Attestation in JWT format:
HTTP/1.1 201 OK
Content-Type: application/jwt
eyJhbGciOiJFUzI1NiIsInR5cCI6IndhbGxldC1hdHRlc3RhdGlvbitqd3QiLCJraWQiOiI1dDVZWXBCaE4tRWdJRUVJNWlVenI2cjBNUjAyTG5WUTBPbWVrbU5LY2pZIiwidHJ1c3RfY2hhaW4iOlsiZXlKaGJHY2lPaUpGVXouLi42UzBBIiwiZXlKaGJHY2lPaUpGVXouLi5qSkxBIiwiZXlKaGJHY2lPaUpGVXouLi5IOWd3Il19.eyJpc3MiOiJodHRwczovL3dhbGxldC1wcm92aWRlci5leGFtcGxlLm9yZyIsInN1YiI6InZiZVhKa3NNNDV4cGh0QU5uQ2lHNm1DeXVVNGpmR056b3BHdUt2b2dnOWMiLCJ0eXBlIjoiV2FsbGV0SW5zdGFuY2VBdHRlc3RhdGlvbiIsInBvbGljeV91cmkiOiJodHRwczovL3dhbGxldC1wcm92aWRlci5leGFtcGxlLm9yZy9wcml2YWN5X3BvbGljeSIsInRvc191cmkiOiJodHRwczovL3dhbGxldC1wcm92aWRlci5leGFtcGxlLm9yZy9pbmZvX3BvbGljeSIsImxvZ29fdXJpIjoiaHR0cHM6Ly93YWxsZXQtcHJvdmlkZXIuZXhhbXBsZS5vcmcvbG9nby5zdmciLCJhdHRlc3RlZF9zZWN1cml0eV9jb250ZXh0IjoiaHR0cHM6Ly93YWxsZXQtcHJvdmlkZXIuZXhhbXBsZS5vcmcvTG9BL2Jhc2ljIiwiY25mIjp7Imp3ayI6eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6IjRITnB0SS14cjJwanlSSktHTW56NFdtZG5RRF91SlNxNFI5NU5qOThiNDQiLCJ5IjoiTElablNCMzl2RkpoWWdTM2s3alhFNHIzLUNvR0ZRd1p0UEJJUnFwTmxyZyIsImtpZCI6InZiZVhKa3NNNDV4cGh0QU5uQ2lHNm1DeXVVNGpmR056b3BHdUt2b2dnOWMifX0sImF1dGhvcml6YXRpb25fZW5kcG9pbnQiOiJldWRpdzoiLCJyZXNwb25zZV90eXBlc19zdXBwb3J0ZWQiOlsidnBfdG9rZW4iXSwidnBfZm9ybWF0c19zdXBwb3J0ZWQiOnsiand0X3ZwX2pzb24iOnsiYWxnX3ZhbHVlc19zdXBwb3J0ZWQiOlsiRVMyNTYiXX0sImp3dF92Y19qc29uIjp7ImFsZ192YWx1ZXNfc3VwcG9ydGVkIjpbIkVTMjU2Il19fSwicmVxdWVzdF9vYmplY3Rfc2lnbmluZ19hbGdfdmFsdWVzX3N1cHBvcnRlZCI6WyJFUzI1NiJdLCJwcmVzZW50YXRpb25fZGVmaW5pdGlvbl91cmlfc3VwcG9ydGVkIjpmYWxzZSwiaWF0IjoxNjg3MjgxMTk1LCJleHAiOjE2ODcyODgzOTV9.tNvCyFPCL5tUi2NakKwdaG9xbrtWWl4djSRYRfHrF8NdmffdT044U55pRn35J2cl0LZxbesEDrfSAz2pllw2Ug
Below are described the JWT headers and the payload claims of the assertion used in the request.
Assertion Header¶
key |
value |
alg |
Algorithm to verify the token signature (es. ES256). |
kid |
Key id of the public key created by the Wallet Instance. |
typ |
Media type, set to
|
Assertion Payload¶
key |
value |
iss
|
Thumbprint value
of the JWK of the Wallet Instance
for which the attestation is
being requested.
|
aud
|
The public url of the Wallet
Provider.
|
jti
|
|
nonce
|
The nonce value obtained from the
App Attestation Service.
|
cnf
|
JSON object, according to
containing the public part of an asymmetric key pair owned
by the Wallet Instance.
|
iat
|
Unix timestamp of attestation request
issuance time.
|
exp
|
Unix timestamp regarding the
expiration date time.
|
Below a non-normative example of the Wallet Attestation request where the decoded JWS headers and payload are separated by a comma:
{
"alg": "ES256",
"kid": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
"typ": "wiar+jwt"
}
.
{
"iss": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
"aud": "https://wallet-provider.example.org",
"jti": "6ec69324-60a8-4e5b-a697-a766d85790ea",
"nonce" : ".....",
"cnf": {
"jwk": {
"crv": "P-256",
"kty": "EC",
"x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44",
"y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg",
"kid": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c"
}
},
"iat": 1686645115,
"exp": 1686652315
}
Whose corresponding JWS is verifiable using the public part of an asymmetric key pair owned by the Wallet Instance that has a key id which is the same as the kid made available in the JWS header.
Wallet Attestation¶
The Wallet Attestation MUST be provisioned in JWT format, with headers and payload claims are listed below.
Header¶
key |
value |
alg |
Algorithm to verify the token signature (es. ES256). |
kid |
The key id of the key used by the Wallet Provider to sign the attestation. |
typ |
Media type, set to wallet-attestation+jwt, according to [OPENID4VC-HAIP] |
x5c |
Array containing the X.509 chain of certificates used to attest the public key of the Wallet Provider. |
trust_chain |
Array containing the Federation Trust Chain relating to the Wallet Provider. |
Note
One of the claims trust_chain and x5c MUST be provisioned. If they are both provided, the related public key MUST be the same in both trust_chain and x5c.
Payload¶
key |
value |
iss
|
The public url of the Wallet Provider
|
sub
|
Thumbprint value
of the JWK of the Wallet Instance
for which the attestation is
being issued.
|
iat
|
Unix timestamp of attestation
issuance time.
|
exp
|
Unix timestamp regarding the
expiration date time.
A good practice to avoid security
problems is to have a limited
duration of the attestation.
|
aal
|
JSON String asserting the authentication level
of the Wallet and the key as asserted in
the cnf claim.
|
cnf
|
This parameter contains the
jwk parameter
with the public key of the Wallet Instance
necessary for the Holder Key Binding.
|
authorization_endpoint
|
URL of the SIOPv2
Authorization Endpoint.
|
response_types_supported
|
JSON array containing a list of
the OAuth 2.0
response_type values. |
response_modes_supported
|
JSON array containing a list of the OAuth 2.0
"response_mode" values that this
authorization server supports.
|
vp_formats_supported
|
JSON object with name/value pairs,
identifying a Credential format supported
by the Wallet.
|
request_object_signing
_alg_values_supported
|
JSON array containing a list of the
JWS signing algorithms (alg values)
supported.
|
presentation_definition
_uri_supported
|
Boolean value specifying whether the
Wallet Instance supports the transfer of
presentation_definition byreference. MUST set to false.
|
Below is an example of Wallet Attestation:
{
"alg": "ES256",
"kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY",
"trust_chain": [
"eyJhbGciOiJFUz...6S0A",
"eyJhbGciOiJFUz...jJLA",
"eyJhbGciOiJFUz...H9gw",
],
"typ": "wallet-attestation+jwt",
}
.
{
"iss": "https://wallet-provider.example.org",
"sub": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
"aal": "https://trust-list.eu/aal/high",
"cnf":
{
"jwk":
{
"crv": "P-256",
"kty": "EC",
"x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44",
"y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg",
"kid": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c"
}
},
"authorization_endpoint": "eudiw:",
"response_types_supported": [
"vp_token"
],
"response_modes_supported": [
"form_post.jwt"
],
"vp_formats_supported": {
"vc+sd-jwt": {
"sd-jwt_alg_values": [
"ES256",
"ES384"
]
}
},
"request_object_signing_alg_values_supported": [
"ES256"
],
"presentation_definition_uri_supported": false,
"iat": 1687281195,
"exp": 1687288395
}