From 0609c977beb4bf69f243b6ad5962480ab4310eb4 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 10 Feb 2023 09:01:29 -0800 Subject: [PATCH 1/6] Update suggested API. This change updates the proposed API to use IdentityCredential instead. --- README.md | 129 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 3c3a79a..246d9fd 100644 --- a/README.md +++ b/README.md @@ -93,80 +93,125 @@ EncryptionParamaters = { ### API -One idea a new `CredentialRequest` (et al) -``` -dictionary CredentialElement { - required DOMString namespace; // As defined in ISO 18013-5 clause 8. - required DOMString name; +We propose to build upon the Credential Manager’s “identity” request, which [Federated Credential Management](https://fedidcg.github.io/FedCM/#dictdef-identitycredentialrequestoptions) is also built on top of, with the following structures: + +```webidl +// The existing extension to the credential management API: +partial dictionary CredentialRequestOptions { + IdentityCredentialRequestOptions identity; }; -dictionary CredentialStorageDuration { - // At least one of these is required. +dictionary IdentityCredentialRequestOptions { + required sequence providers; - boolean forever; // Cannot be used with any other properties. + // Common fields across all types of providers: - long days; // Cannot (currently) be used with any other properties. + // Omitting `retention` implies that the identity information will not be stored. + IdentityStorageDuration retention; }; -dictionary CredentialDocumentDescriptor { - required DOMString documentType; // As defined in ISO 18013-5 clause 8. +dictionary IdentityStorageDuration { + // Exactly one of the following must be provided. + boolean forever; + long days; +}; - required sequence requestedElements; +dictionary IdentityProviderConfig { + required string scheme; - CredentialStorageDuration desiredStorageDuration; // Not providing this is equivalent to not asking to store. + // Common fields across all identity provider types: + required DOMString nonce; }; -dictionary CredentialDocument { - object data; // The CBOR encoded `CredentialDocument` defined above. +// extends the IdentityProviderConfig with mDoc-specific attributes +partial dictionary IdentityProviderConfig { + // For use where `scheme` is `mdoc`: + + // base64-encoded reader HPKE public key. + required DOMString readerPublicKey; + + // base64-encoded reader certification chain, if the platform requires it. + optional sequence certificates; + + required DOMString documentType; + required sequence requestedElements; +}; + +dictionary MdocElement { + required DOMString namespace; // As defined in ISO 18013-5 clause 8. + required DOMString name; }; -dictionary RequestConfiguration { - required DOMString nonce; +partial dictionary IdentityProviderConfig { + // ... + // Federated provider specific configs, not covered here. + // ... }; +``` -[ - SecureContext, - Exposed=Window, -] interface CredentialRequest { - constructor(DOMString requesterIdentity, CredentialDocumentDescriptor documentDescriptor); // This throws if anything in the `documentDescriptor` is not recognized (e.g. an invalid `documentType`). +There is always a bijection from `IdentityCredentialRequestOptions` to JSON strings, and that bijection is implemented by `JSON.parse` and `JSON.stringify`. This allows requests to be generated on the server and easily transported to the user agent. - Promise requestDocument(RequestConfiguration configuration); +When an `IdentityCredentialRequestOptions` is used with [`get`](https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-get), the result is an `IdentityCredential`: - Promise abort(); +```webidl +[Exposed=Window, SecureContext] +interface IdentityCredential : Credential { + // The CBOR encoded `CredentialDocument` defined above, wrapped in base64. + DOMString token; }; ``` +The `id` of the `IdentityCredential` for an mdoc response would be `mdoc`. ## Examples +Requesting specific attributes from a driver’s license: + ```js -// Driver's License -let mDLCredentialRequest = new CredentialRequest(certificate, { - documentType: "org.iso.18013.5.1.mDL", - requestedElements: [ +let request = { + identity: { + retention: { + days: 90, + }, + providers: [{ + scheme: “mdoc”, + nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", + documentType: "org.iso.18013.5.1.mDL", + readerPublicKey: "ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X/6w...", + requestedElements: [ { namespace: "org.iso.18013.5.1", name: "document_number" }, { namespace: "org.iso.18013.5.1", name: "portrait" }, { namespace: "org.iso.18013.5.1", name: "driving_privileges" }, { namespace: "org.iso.18013.5.1.aamva", name: "organ_donor" }, { namespace: "org.iso.18013.5.1.aamva", name: "hazmat_endorsement_expiration_date" }, - ], - desiredStorageDuration: { - days: 7, - }, + ], + }], + } +}; +navigator.credentials.get(request).then(() => { }); -mDLCredentialRequest.request({ nonce }).then((credentialDocument) => { ... }); ``` +Requesting specific mDL attributes from a COVID card: + ```js -// Vaccination Card -let micovCredentialRequest = new CredentialRequest(certificate, { - documentType: "org.micov.1", - requestedElements: [ - { namespace: "org.micov.attestation.1", name: "PersonId_dl" }, - { namespace: "org.micov.attestation.1", name: "portrait" }, - ], -}); -micovCredentialRequest.request({ nonce }).then((credentialDocument) => { ... }); +let request = { + identity: { + retention: { + days: 90, + }, + providers: [{ + scheme: “mdoc”, + documentType: "org.micov.1", + requestedElements: [ + { namespace: "org.micov.attestation.1", name: "PersonId_dl" }, + { namespace: "org.micov.attestation.1", name: "portrait" }, + ], + nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", + readerPublicKey: "ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X/6w..." + }], + } +}; ``` From 6d80fa1fa32780088f415eeb1419266da12df099 Mon Sep 17 00:00:00 2001 From: Rick Byers Date: Tue, 25 Apr 2023 13:55:43 -0400 Subject: [PATCH 2/6] Adam's work-in-progress prior to handoff to me --- README.md | 212 ++++++++++++++++++++++++++---------------------------- 1 file changed, 102 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 246d9fd..56ee917 100644 --- a/README.md +++ b/README.md @@ -15,47 +15,113 @@ ## Introduction -This is a proposal for a new web API that allows websites to request a mobile document as defined in ISO/IEC 18013-5 using structures defined in the same ISO in order to achieve an online presentment. The API would protect the mobile document credential data, supports selective disclosure, and allow the user to control the release of credential data. +This is a proposal for a new web API that allows websites to request a mobile document as defined in ISO/IEC 18013-5 using structures defined in the same ISO standard in order to achieve an online presentment. The API protects the mobile document credential data, supports selective disclosure, and allows the user to control the release of credential data. -The ISO/IEC 18013-5:2021 standard specifies how a driver license (mDL) is represented on a mobile device and how it is presented to a physical reader. Users who chose to have their mDL on device can present it to compatible readers instead of the physical driver license. The ISO standard defines the protocols and the exchanges between the mDL and the mDL reader for different physical uses case (e.g. TSA, Hotel, store,... ). The ISO standard provides building blocks to allow remote presentment of the the mobile driver’s license over the Web such as data structures and operational phases. The ISO standard ISO/IEC 18013-5:2021 for mobile driver’s license does not define a web API to allow presentement via user agent. - -The mechanisms defined by ISO/IEC 18013-5 are designed to support any type of mobile document, called mdoc. Besides the mDL, this API can therefore be used to request and transmit any mobile document that implements the ISO mdoc specification. +The ISO/IEC 18013-5:2021 standard specifies how a mobile driver's license (mDL) is represented on a mobile device and how it is presented to a physical reader. Users who choose to have their mDL on device can present it to compatible readers instead of the physical driver's license. The ISO standard defines the protocols and the exchanges between the mDL and the mDL reader for different physical uses case (e.g. TSA, hotels, stores, …). The ISO standard provides building blocks to allow remote presentment of the the mobile driver’s license over the Web such as data structures and operational phases, however it does not define a web API to allow presentement via user agent. +The mechanisms defined by ISO/IEC 18013-5 are designed to support any type of mobile document, generically called “mdocs”. The API defined in this document can therefore be used to request and transmit any mobile document that implements the ISO mdoc specification. ## Goals -- Allow websites to request the presentment of a mobile document in mdoc format such as driver’s license. -- Enable the user to have a consent based control of what data is released to the website. +- Allow websites to request the presentment of a mobile document in mdoc format, such as driver’s license. +- Enable the user to have control of what data is released to the website. - Protect the released data using encryption to ensure only the website the data is intended for can access the data. +- Don't preclude the addition of other credential types in the future, if needed. ## Non-goals +- Support requests spanning identity and authentication mechanisms. - Define issuance and provisioning of an mdoc. -- Define the communication between the User Agent and the website server is out of scope. +- Define the communication between the User Agent and the website server - Define the native communication between the User Agent and the application holding the mdoc. -- Define how the response to the request is used by the server is out of scope. -- Requesting multiple mdocs in one API call. - +- Define how the response to the request is used by the server. +- Support requesting multiple mdocs in one API call. ## Proposed Solution -The API request should contain all the information needed to build up and encrypt the response. The response data from the mdoc should be a CBOR-encoded blob encrypted end-to-end for the intended relying party using Hybrid Public Key Encryption (HPKE) defined in RFC 9180. Only the targeted relying party, holder of the private part corresponding to the public key used for the response encryption, should be able to decrypt the response (with the assumption that the server always holds and protects the private key). The API should allow the server to pass as a parameter a requester identity object that allows the mdoc device to extract the public key material needed for the encryption. The passed object can be anything that allows the mdoc to determine which public key to encrypt the response to, like a certificate, a key or a key identifier. +This API would be a new identity scheme within [IdentityCredential](https://github.com/agl/identity-credential) using the scheme identifier `mdoc`. + +### Requests +```webidl +partial dictionary IdentityProviderRequestOptions { + optional MdocRequest mdoc; +} -### Request +dictionary MdocRequest { + required DOMString nonce; -The website would need to provide a document type and desired data elements, as well as a requester identity object that allows the device to extract the encryption public key (and the mdoc to optionally verify the eligibility of the website to request the mdoc presentment). + // The mdoc document type requested. See ISO 18013-5 section 7.1. + required DOMString documentType; + + // The elements of the mdoc requested. + required sequence requestedElements; + + // The number of days that the requester will keep the data for. + // Must be non-negative. A value of zero indicates that the data + // will not be retained beyond the time to process it. A value of + // positive infinity indicates unlimited retention. + required double retentionDays; + + // A set of reader identities. Each value is a base64-encoded sequence of one + // or more X.509 certificates in ASN.1 DER encoding (a “chain” of + // certificates). At least one value must be provided. The first element of + // each X.509 chain MUST be the end-entity certificate. Subsequent X.509 + // certificates in a chain are intermediate certificates as may help the wallet + // verify the end-entity certificate. + // + // If the requester has no applicable X.509 chain then it may use a + // single, self-signed certificate. + // + // The underlying wallet will evaluate these certificate chains + // and pick one, at its discretion, to identify the requesting entity. The + // SubjectPublicKeyInfo of the end-entity certificate of the selected chain + // is used to encrypt the response. + required sequence readerAuthentication; +}; + +dictionary MdocElement { + required DOMString namespace; // As defined in ISO 18013-5 section 7. + required DOMString name; +}; +``` + +An example request: + +```js +let request = { + identity: { + mdoc: { + nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", + documentType: "org.iso.18013.5.1.mDL", + retentionDays: 90, + readerAuthentication: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X/6w..."], + mdocRequestedElements: [ + { namespace: "org.iso.18013.5.1", name: "document_number" }, + { namespace: "org.iso.18013.5.1", name: "portrait" }, + { namespace: "org.iso.18013.5.1", name: "driving_privileges" }, + { namespace: "org.iso.18013.5.1.aamva", name: "organ_donor" }, + { namespace: "org.iso.18013.5.1.aamva", name: "hazmat_endorsement_expiration_date" }, + ], + }, + } +}; +navigator.credentials.get(request).then(() => { +}); +``` -Once mdoc application verifies the server identity object to make sure it is a legitimate request (if needed), it would build up the response according to ISO/IEC 18013-5, including the credential data itself, the authentication by the issuer, and the authentication by the device, encrypting everything with the key derived from the requester identity object using HKPE so that only the server can decrypt the binary blob (assuming the server keeps and protects the private key). +### Processing -After sending the encrypted data to the server, it would be decrypted to verify the presented mdoc issuer signature and device signature according to ISO/IEC 18013-5. +If the user rejects the request, or if no applicable mdocs are available, or if the identity in `readerAuthentication` is not authorized to request the applicable mdoc, then a "[NotAllowedError](https://heycam.github.io/webidl/#notallowederror)" [DOMException](https://heycam.github.io/webidl/#idl-DOMException) is raised. +Otherwise the application holding the responsive mdoc builds a response according to ISO/IEC 18013-5, including the credential data itself, the authentication by the issuer, and the authentication by the device, encrypting everything with the key taken from the selected `readerAuthentication` value. ### Response -The response from the server would be the `DeviceResponse` object as defined in ISO/IEC 18013-5 clause 8.3.2.1.2.2 encoded with CBOR according to ISO/IEC 18013-5, encrypted using HPKE with the following settings: +A positive result from an mdoc request will be an [IdentityCredential](https://github.com/agl/identity-credential) where the `scheme` will be `mdoc` and the `result` with be the base64-encoding of the `DeviceResponse` object as defined in ISO/IEC 18013-5 clause 8.3.2.1.2.2 encoded with CBOR according to ISO/IEC 18013-5, encrypted using HPKE with the following settings: + ``` mode: mode_base KEM: DHKEM(P-256, HKDF-SHA256) @@ -64,7 +130,8 @@ AEAD: AES-128-GCM ``` Part of the signature generated for `DeviceAuth` is done using the `SessionTranscript` structure as defined in ISO/IEC 18103-5 section 9.1.5.1. The `DeviceEngagementBytes` and the `EReaderKeyBytes` are both not present, and therefore have a value of `null`. The `Handover` element shall be as defined below: -``` + +```cddl BrowserHandover = [ "BrowserHandoverv1", Nonce, @@ -73,10 +140,12 @@ BrowserHandover = [ pkEm ] ``` -where `Nonce` is the nonce provided by the request, `OriginInfoBytes` contains the origin of the request and is defined in ISO/IEC 18013-7, and `RequesterIdentity` is the requester identity object from the request. + +where `Nonce` is the nonce provided by the request, `OriginInfoBytes` contains the origin of the request and is defined in ISO/IEC 18013-7, and `RequesterIdentity` is the requester identity object from the request. (**TODO**: tighen the definition of `RequesterIdentity`, should it be the SubjectPublicKeyInfo?) This is all included inside a CBOR encoded `CredentialDocument` with the following structure: -``` + +```cddl CredentialDocument = { "version": tstr, "encryptionParamaters": EncryptionParamaters, @@ -91,78 +160,6 @@ EncryptionParamaters = { ``` -### API - -We propose to build upon the Credential Manager’s “identity” request, which [Federated Credential Management](https://fedidcg.github.io/FedCM/#dictdef-identitycredentialrequestoptions) is also built on top of, with the following structures: - -```webidl -// The existing extension to the credential management API: -partial dictionary CredentialRequestOptions { - IdentityCredentialRequestOptions identity; -}; - -dictionary IdentityCredentialRequestOptions { - required sequence providers; - - // Common fields across all types of providers: - - // Omitting `retention` implies that the identity information will not be stored. - IdentityStorageDuration retention; -}; - -dictionary IdentityStorageDuration { - // Exactly one of the following must be provided. - boolean forever; - long days; -}; - -dictionary IdentityProviderConfig { - required string scheme; - - // Common fields across all identity provider types: - required DOMString nonce; -}; - -// extends the IdentityProviderConfig with mDoc-specific attributes -partial dictionary IdentityProviderConfig { - // For use where `scheme` is `mdoc`: - - // base64-encoded reader HPKE public key. - required DOMString readerPublicKey; - - // base64-encoded reader certification chain, if the platform requires it. - optional sequence certificates; - - required DOMString documentType; - required sequence requestedElements; -}; - -dictionary MdocElement { - required DOMString namespace; // As defined in ISO 18013-5 clause 8. - required DOMString name; -}; - -partial dictionary IdentityProviderConfig { - // ... - // Federated provider specific configs, not covered here. - // ... -}; -``` - -There is always a bijection from `IdentityCredentialRequestOptions` to JSON strings, and that bijection is implemented by `JSON.parse` and `JSON.stringify`. This allows requests to be generated on the server and easily transported to the user agent. - -When an `IdentityCredentialRequestOptions` is used with [`get`](https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-get), the result is an `IdentityCredential`: - -```webidl -[Exposed=Window, SecureContext] -interface IdentityCredential : Credential { - // The CBOR encoded `CredentialDocument` defined above, wrapped in base64. - DOMString token; -}; -``` - -The `id` of the `IdentityCredential` for an mdoc response would be `mdoc`. - ## Examples Requesting specific attributes from a driver’s license: @@ -170,22 +167,19 @@ Requesting specific attributes from a driver’s license: ```js let request = { identity: { - retention: { - days: 90, - }, - providers: [{ - scheme: “mdoc”, + mdoc: [{ + retentionDays: 90, nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", documentType: "org.iso.18013.5.1.mDL", - readerPublicKey: "ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X/6w...", - requestedElements: [ + readerAuthentication: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X…"], + mdocRequestedElements: [ { namespace: "org.iso.18013.5.1", name: "document_number" }, { namespace: "org.iso.18013.5.1", name: "portrait" }, { namespace: "org.iso.18013.5.1", name: "driving_privileges" }, { namespace: "org.iso.18013.5.1.aamva", name: "organ_donor" }, { namespace: "org.iso.18013.5.1.aamva", name: "hazmat_endorsement_expiration_date" }, ], - }], + }, } }; navigator.credentials.get(request).then(() => { @@ -197,19 +191,16 @@ Requesting specific mDL attributes from a COVID card: ```js let request = { identity: { - retention: { - days: 90, - }, - providers: [{ - scheme: “mdoc”, + mdoc: [{ documentType: "org.micov.1", - requestedElements: [ - { namespace: "org.micov.attestation.1", name: "PersonId_dl" }, - { namespace: "org.micov.attestation.1", name: "portrait" }, - ], + retentionDays: 90, nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", - readerPublicKey: "ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X/6w..." - }], + readerAuthentication: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X…"], + mdocRequestedElements: [ + { namespace: "org.micov.attestation.1", name: "PersonId_dl" }, + { namespace: "org.micov.attestation.1", name: "portrait" }, + ], + }, } }; ``` @@ -218,6 +209,7 @@ let request = { ## Privacy & Security Considerations This API provides the ability for websites to retrieve an ISO 18013-5 mDoc already on the device. An important part of the security and privacy mechanisms are provided by ISO 18013-5: + - Protection against forgery with passive data authentication defined in ISO 18013-5 based on Mobile Security Object (MSO). - Protection against cloning using active authentication leveraging a signature over session data. The signature is produced by the device using the device private key as defined in ISO 18013-5. The Device Public key is part of the MSO signed by the issuer. - The ability for the user to see the requested data before disclosure, in addition to being able to choose what to disclose. From 0d5d31c457a9a6ecd30a47fad4c0372199e4824b Mon Sep 17 00:00:00 2001 From: Rick Byers Date: Thu, 27 Apr 2023 17:03:20 -0400 Subject: [PATCH 3/6] Add agl to authors --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 56ee917..ff0e6e4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ - [@dcrousso](https://github.com/dcrousso) - [@hlozi](https://github.com/hlozi) - [@martijnharing](https://github.com/martijnharing) - +- [@agl](https://github.com/agl) ## Participate @@ -223,7 +223,6 @@ This API provides the ability for websites to retrieve an ISO 18013-5 mDoc alrea Many thanks for valuable feedback and advice from: - [@15characterlimi](https://github.com/15characterlimi) -- [@agl](https://github.com/agl) - [@balfanz](https://github.com/balfanz) - [@bslassey](https://github.com/bslassey) - [@cwilso](https://github.com/cwilso) From 7498741ed337e7e753379898a6eb1748d7c31bdb Mon Sep 17 00:00:00 2001 From: Rick Byers Date: Fri, 28 Apr 2023 08:53:19 -0400 Subject: [PATCH 4/6] Update to match latest IdentityCredential proposal --- README.md | 113 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index ff0e6e4..82499c1 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - [@hlozi](https://github.com/hlozi) - [@martijnharing](https://github.com/martijnharing) - [@agl](https://github.com/agl) +- [@samuelgoto](https://github.com/samuelgoto) ## Participate @@ -28,6 +29,7 @@ The mechanisms defined by ISO/IEC 18013-5 are designed to support any type of mo - Enable the user to have control of what data is released to the website. - Protect the released data using encryption to ensure only the website the data is intended for can access the data. - Don't preclude the addition of other credential types in the future, if needed. +- Integrate with other types of identity requests which websites may want to let users choose between. ## Non-goals @@ -46,11 +48,19 @@ This API would be a new identity scheme within [IdentityCredential](https://gith ### Requests ```webidl -partial dictionary IdentityProviderRequestOptions { - optional MdocRequest mdoc; +partial dictionary IdentityProviderConfig { + optional MDocsSpecificParameters mdoc; } -dictionary MdocRequest { +dictionary CredentialStorageDuration { + // At least one of these is required. + + boolean forever; // Cannot be used with any other properties. + + long days; // Cannot (currently) be used with any other properties. +}; + +dictionary MDocsSpecificParameters { required DOMString nonce; // The mdoc document type requested. See ISO 18013-5 section 7.1. @@ -59,11 +69,9 @@ dictionary MdocRequest { // The elements of the mdoc requested. required sequence requestedElements; - // The number of days that the requester will keep the data for. - // Must be non-negative. A value of zero indicates that the data - // will not be retained beyond the time to process it. A value of - // positive infinity indicates unlimited retention. - required double retentionDays; + // The duration of time that the requester will keep the data for. + // Not providing this is equivalent to not asking to store. + CredentialStorageDuration retention; // A set of reader identities. Each value is a base64-encoded sequence of one // or more X.509 certificates in ASN.1 DER encoding (a “chain” of @@ -93,19 +101,23 @@ An example request: ```js let request = { identity: { - mdoc: { - nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", - documentType: "org.iso.18013.5.1.mDL", - retentionDays: 90, - readerAuthentication: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X/6w..."], - mdocRequestedElements: [ - { namespace: "org.iso.18013.5.1", name: "document_number" }, - { namespace: "org.iso.18013.5.1", name: "portrait" }, - { namespace: "org.iso.18013.5.1", name: "driving_privileges" }, - { namespace: "org.iso.18013.5.1.aamva", name: "organ_donor" }, - { namespace: "org.iso.18013.5.1.aamva", name: "hazmat_endorsement_expiration_date" }, - ], - }, + providers: [{ + mdoc: { + nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", + documentType: "org.iso.18013.5.1.mDL", + retention: { + days: 90 + }, + readerPublicKey: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X/6w..."], + requestedElements: [ + { namespace: "org.iso.18013.5.1", name: "document_number" }, + { namespace: "org.iso.18013.5.1", name: "portrait" }, + { namespace: "org.iso.18013.5.1", name: "driving_privileges" }, + { namespace: "org.iso.18013.5.1.aamva", name: "organ_donor" }, + { namespace: "org.iso.18013.5.1.aamva", name: "hazmat_endorsement_expiration_date" }, + ], + }, + }], } }; navigator.credentials.get(request).then(() => { @@ -114,9 +126,9 @@ navigator.credentials.get(request).then(() => { ### Processing -If the user rejects the request, or if no applicable mdocs are available, or if the identity in `readerAuthentication` is not authorized to request the applicable mdoc, then a "[NotAllowedError](https://heycam.github.io/webidl/#notallowederror)" [DOMException](https://heycam.github.io/webidl/#idl-DOMException) is raised. +If the user rejects the request, or if no applicable mdocs are available, or if the identity in `readerPublicKey` is not authorized to request the applicable mdoc, then a "[NotAllowedError](https://heycam.github.io/webidl/#notallowederror)" [DOMException](https://heycam.github.io/webidl/#idl-DOMException) is raised. -Otherwise the application holding the responsive mdoc builds a response according to ISO/IEC 18013-5, including the credential data itself, the authentication by the issuer, and the authentication by the device, encrypting everything with the key taken from the selected `readerAuthentication` value. +Otherwise the application holding the responsive mdoc builds a response according to ISO/IEC 18013-5, including the credential data itself, the authentication by the issuer, and the authentication by the device, encrypting everything with the key taken from the selected `readerPublicKey` value. ### Response @@ -167,19 +179,23 @@ Requesting specific attributes from a driver’s license: ```js let request = { identity: { - mdoc: [{ - retentionDays: 90, - nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", - documentType: "org.iso.18013.5.1.mDL", - readerAuthentication: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X…"], - mdocRequestedElements: [ - { namespace: "org.iso.18013.5.1", name: "document_number" }, - { namespace: "org.iso.18013.5.1", name: "portrait" }, - { namespace: "org.iso.18013.5.1", name: "driving_privileges" }, - { namespace: "org.iso.18013.5.1.aamva", name: "organ_donor" }, - { namespace: "org.iso.18013.5.1.aamva", name: "hazmat_endorsement_expiration_date" }, - ], - }, + providers: [{ + mdoc: { + nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", + readerPublicKey: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X…"], + retention: { + days: 90, + }, + documentType: "org.iso.18013.5.1.mDL", + requestedElements: [ + { namespace: "org.iso.18013.5.1", name: "document_number" }, + { namespace: "org.iso.18013.5.1", name: "portrait" }, + { namespace: "org.iso.18013.5.1", name: "driving_privileges" }, + { namespace: "org.iso.18013.5.1.aamva", name: "organ_donor" }, + { namespace: "org.iso.18013.5.1.aamva", name: "hazmat_endorsement_expiration_date" }, + ], + } + }] } }; navigator.credentials.get(request).then(() => { @@ -191,16 +207,20 @@ Requesting specific mDL attributes from a COVID card: ```js let request = { identity: { - mdoc: [{ - documentType: "org.micov.1", - retentionDays: 90, - nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", - readerAuthentication: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X…"], - mdocRequestedElements: [ - { namespace: "org.micov.attestation.1", name: "PersonId_dl" }, - { namespace: "org.micov.attestation.1", name: "portrait" }, - ], - }, + providers: [{ + mdoc: { + nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", + readerPublicKey: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X…"], + retention: { + days: 90, + }, + documentType: "org.micov.1", + requestedElements: [ + { namespace: "org.micov.attestation.1", name: "PersonId_dl" }, + { namespace: "org.micov.attestation.1", name: "portrait" }, + ], + }, + }], } }; ``` @@ -230,5 +250,4 @@ Many thanks for valuable feedback and advice from: - [@divegeek](https://github.com/divegeek) - [@hober](https://github.com/hober) - [@jyasskin](https://github.com/jyasskin) -- [@samuelgoto](https://github.com/samuelgoto) - [@sethmoo](https://github.com/sethmoo) From 49961ad51970faea9c986cb789fe0cb22c12ae6e Mon Sep 17 00:00:00 2001 From: Rick Byers Date: Fri, 28 Apr 2023 12:04:31 -0400 Subject: [PATCH 5/6] Move retention to a double per @othermaciej feedback --- README.md | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 82499c1..22bbd84 100644 --- a/README.md +++ b/README.md @@ -52,14 +52,6 @@ partial dictionary IdentityProviderConfig { optional MDocsSpecificParameters mdoc; } -dictionary CredentialStorageDuration { - // At least one of these is required. - - boolean forever; // Cannot be used with any other properties. - - long days; // Cannot (currently) be used with any other properties. -}; - dictionary MDocsSpecificParameters { required DOMString nonce; @@ -69,9 +61,10 @@ dictionary MDocsSpecificParameters { // The elements of the mdoc requested. required sequence requestedElements; - // The duration of time that the requester will keep the data for. - // Not providing this is equivalent to not asking to store. - CredentialStorageDuration retention; + // The number of days that the requester will keep the data for. + // Not providing this is equivalent to 0, meaning not asking to store. + // Infinity means forever. + double retentionDays; // A set of reader identities. Each value is a base64-encoded sequence of one // or more X.509 certificates in ASN.1 DER encoding (a “chain” of @@ -105,9 +98,7 @@ let request = { mdoc: { nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", documentType: "org.iso.18013.5.1.mDL", - retention: { - days: 90 - }, + retentionDays: 90, readerPublicKey: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X/6w..."], requestedElements: [ { namespace: "org.iso.18013.5.1", name: "document_number" }, @@ -183,9 +174,7 @@ let request = { mdoc: { nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", readerPublicKey: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X…"], - retention: { - days: 90, - }, + retentionDays: 90, documentType: "org.iso.18013.5.1.mDL", requestedElements: [ { namespace: "org.iso.18013.5.1", name: "document_number" }, @@ -211,9 +200,7 @@ let request = { mdoc: { nonce: "gf69kepV+m5tGxMyMF0cnn9NCnRHez/LUIsFtLi6pwg=", readerPublicKey: ["ftl+VEHPB17r2oi6it3ENaqhOOB0AZbAkb5f4VlCPakpdNioc9QZ7X…"], - retention: { - days: 90, - }, + retentionDays: 90, documentType: "org.micov.1", requestedElements: [ { namespace: "org.micov.attestation.1", name: "PersonId_dl" }, From b68274e2872cfb361bf2e4cd0baf410174c55a57 Mon Sep 17 00:00:00 2001 From: Rick Byers Date: Fri, 28 Apr 2023 14:29:58 -0400 Subject: [PATCH 6/6] Update proposed mdoc dictionary name --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 22bbd84..4c6b6da 100644 --- a/README.md +++ b/README.md @@ -49,10 +49,10 @@ This API would be a new identity scheme within [IdentityCredential](https://gith ```webidl partial dictionary IdentityProviderConfig { - optional MDocsSpecificParameters mdoc; + optional MdocIdentityProviderConfig mdoc; } -dictionary MDocsSpecificParameters { +dictionary MdocIdentityProviderConfig { required DOMString nonce; // The mdoc document type requested. See ISO 18013-5 section 7.1.