From 0609c977beb4bf69f243b6ad5962480ab4310eb4 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 10 Feb 2023 09:01:29 -0800 Subject: [PATCH 1/3] 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 1b1f70ba9be0e1470527b8d90dd11e33359c3b17 Mon Sep 17 00:00:00 2001 From: Brad Lassey Date: Thu, 30 Mar 2023 16:21:29 -0400 Subject: [PATCH 2/3] Add support for critiality and 'one of' expressions --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 246d9fd..bddd264 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ partial dictionary IdentityProviderConfig { optional sequence certificates; required DOMString documentType; - required sequence requestedElements; + required sequence requestedElements; }; dictionary MdocElement { @@ -142,6 +142,12 @@ dictionary MdocElement { required DOMString name; }; +dictionary MdocRequestedElement : MdocElement{ + boolean critical; + DOMString oneOfGroup; +}; + + partial dictionary IdentityProviderConfig { // ... // Federated provider specific configs, not covered here. @@ -214,6 +220,55 @@ let request = { }; ``` +Requesting mDL attributes with organ donor as non-critical: + +```js +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", critical: false }, + { namespace: "org.iso.18013.5.1.aamva", name: "hazmat_endorsement_expiration_date" }, + ], + }], + } +}; + +``` + +Requesting mDL attributes specifying a request of one of age over 18 or date of birth: + +```js +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: "portrait" }, + { namespace: "org.iso.18013.5.1", name: "date_of_birth", oneOfGroup: "ofage" }, + { namespace: "org.iso.18013.5.1", name: "age_over_18", oneOfGroup: "ofAge" }, + ], + }], + } +}; + +``` ## Privacy & Security Considerations From 6cfc95453eeb2278d72851a689b4eeef130b8793 Mon Sep 17 00:00:00 2001 From: Brad Lassey Date: Thu, 30 Mar 2023 16:47:27 -0400 Subject: [PATCH 3/3] Update README.md default criticality to true --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bddd264..db3e7cc 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ dictionary MdocElement { }; dictionary MdocRequestedElement : MdocElement{ - boolean critical; + boolean critical = true; DOMString oneOfGroup; };