Skip to content
This repository was archived by the owner on Aug 11, 2025. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 142 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,82 +93,182 @@ 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<IdentityProviderConfig> 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<CredentialElement> 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<DOMString> certificates;

required DOMString documentType;
required sequence<MdocRequestedElement> requestedElements;
};

dictionary RequestConfiguration {
required DOMString nonce;
dictionary MdocElement {
required DOMString namespace; // As defined in ISO 18013-5 clause 8.
required DOMString name;
};

[
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`).
dictionary MdocRequestedElement : MdocElement{
boolean critical = true;
DOMString oneOfGroup;
};

Promise<CredentialDocument> requestDocument(RequestConfiguration configuration);

Promise<undefined> abort();
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:

```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...",
Comment on lines +183 to +186
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these keys are new (documentType excepted). Do these changes have to do with the subject of this PR, "Criticality"? If so, how?

In general, this PR has almost no description to it. Can we please add a PR description talking about what changes there are here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change you're commenting on is in PR #5, which this builds on top of.

This view is the incremental change in this PR over PR #5 .

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..."
}],
}
};
```

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" },
],
}],
}
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For compatibility with DeviceRequest in 18013-5, I would prefer that we default to critical being false and that's also how I read MdocRequestedElement. Your example suggests it's the other way around though.


```

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

Expand Down