Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial text for conditional create #1951

Merged
merged 19 commits into from
May 15, 2024
Merged
Changes from 1 commit
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
72 changes: 67 additions & 5 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1726,8 +1726,14 @@ To support obtaining assertions via {{CredentialsContainer/get()|navigator.crede
{{PublicKeyCredential}}'s [=interface object=]'s implementation of the <dfn for="PublicKeyCredential" method>\[[Create]](origin,
pascoej marked this conversation as resolved.
Show resolved Hide resolved
options, sameOriginWithAncestors)</dfn> [=internal method=] [[!CREDENTIAL-MANAGEMENT-1]] allows
[=[WRP]=] scripts to call {{CredentialsContainer/create()|navigator.credentials.create()}} to request the creation of a new
Copy link
Contributor

Choose a reason for hiding this comment

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

In the CredentialsContainer/create() the RP will pass in user. id and names.
Are these names the one the authenticator must use or can the passkey provider override them?
Is the assumption that this goes back to the password manager used to fill in the password, or would the user be given a choice of where to create it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The user.id and user.name will be respected as normal. The client may choose pass along which password account was used for authentication for the purposes of linking. The default passkey provider used is up to the client. I imagine it'd be a user configurable setting of all providers that could possibly satisfy such a request.

[=public key credential source=], [=bound credential|bound=] to an [=authenticator=]. This
{{CredentialsContainer/create()|navigator.credentials.create()}} operation can be aborted by leveraging the {{AbortController}};
[=public key credential source=], [=bound credential|bound=] to an [=authenticator=].

By setting <code>|options|.{{CredentialRequestOptions/mediation}}</code> to {{CredentialMediationRequirement/conditional}},
pascoej marked this conversation as resolved.
Show resolved Hide resolved
[=[RPS]=] can indicate that a prominent modal UI should <i>not</i> be shown <i>unless</i> the user has already consented to create a credential via the [=conditionalCreate|conditionalCreate extension=]). [=[RP]=] script SHOULD first check that [conditionalCreate] is present
in {=ClientCapabilities=} in order to avoid the possibility of causing a user-visible error to be returned if the user agent does
not support {{CredentialMediationRequirement/conditional}} [=user mediation=] for {{CredentialsContainer/create()|navigator.credentials.create()}}.
pascoej marked this conversation as resolved.
Show resolved Hide resolved

This {{CredentialsContainer/create()|navigator.credentials.create()}} operation can be aborted by leveraging the {{AbortController}};
pascoej marked this conversation as resolved.
Show resolved Hide resolved
see [[dom#abortcontroller-api-integration]] for detailed instructions.


Expand Down Expand Up @@ -1766,6 +1772,11 @@ When this method is invoked, the user agent MUST execute the following algorithm

1. If <var ignore>sameOriginWithAncestors</var> is [FALSE]:

1. If <code>|options|.{{CredentialRequestOptions/mediation}}</code> is present with the value
{{CredentialMediationRequirement/conditional}}:

1. Throw a "{{NotAllowedError}}" {{DOMException}}

1. If the [=relevant global object=], as determined by the calling
{{CredentialsContainer/create()}} implementation, does not have
[=transient activation=]:
Expand Down Expand Up @@ -1903,6 +1914,13 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o
[=authenticators=] can be <a href="https://en.wikipedia.org/w/index.php?title=Hot_plug">hot-plugged</a> into (e.g., via USB)
or discovered (e.g., via NFC or Bluetooth) by the [=client=] by various mechanisms, or permanently built into the [=client=].

1. If <code>|options|.{{CredentialRequestOptions/mediation}}</code> is present with the value
{{CredentialMediationRequirement/conditional}}:

1. If |conditionalCreateLifetimeTimer| is expired or |conditionalCreateOrigin| is not |callerOrigin|, throw a "{{NotAllowedError}}" {{DOMException}}.

1. Set |lifetimeTimer| to a client-specific default.
pascoej marked this conversation as resolved.
Show resolved Hide resolved

1. Consider the value of {{PublicKeyCredentialCreationOptions/hints}} and craft the user interface accordingly, as the user-agent sees fit.

1. Start |lifetimeTimer|.
Expand Down Expand Up @@ -2182,7 +2200,6 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o
|authenticator| and [=set/remove=] it from |issuedRequests|.

1. Return |constructCredentialAlg| and terminate this algorithm.

</dl>
</li>

Expand All @@ -2191,7 +2208,7 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o
[[#sctn-make-credential-privacy]] for details.

During the above process, the user agent SHOULD show some UI to the user to guide them in the process of selecting and
authorizing an authenticator.
authorizing an authenticator. When <code>|options|.{{CredentialRequestOptions/mediation}}</code> is set to {{CredentialMediationRequirement/conditional}}, prominent modal UI should <i>not</i> be shown <i>unless</i> credential creation was previously consented to.
</div>


Expand Down Expand Up @@ -4888,7 +4905,6 @@ client ignores any further responses from the authenticator for the canceled ope
This operation is ignored if it is invoked in an [=authenticator session=] which does not have an [=authenticatorMakeCredential=]
or [=authenticatorGetAssertion=] operation currently in progress.


### The <dfn>silentCredentialDiscovery</dfn> operation ### {#sctn-op-silent-discovery}

This is an OPTIONAL operation authenticators MAY support to enable {{CredentialMediationRequirement/conditional}}
Expand Down Expand Up @@ -6714,6 +6730,52 @@ During a transition from the FIDO U2F JavaScript API, a [=[RP]=] may have a popu
: Authenticator extension output
:: None.

### Conditional Create Extension (<dfn>conditionalCreate</dfn>) ### {#sctn-authenticator-conditional-create-extension}

This [=client extension|client=] [=authentication extension=] indicates that the RP would like to create a credential after an authenticaton ceremony is successfully mediated by the user agent.
emlun marked this conversation as resolved.
Show resolved Hide resolved

Copy link
Contributor

Choose a reason for hiding this comment

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

Further up this change says:

prominent modal UI should not be shown unless the user has already consented to create a credential via the [=conditionalCreate|conditionalCreate extension=])

That suggests that a conditional create() shows a modal UI unless the user refused consent to create a credential during the previous conditional get(). It sounds like it's a way to avoid bothering the user with a modal creation UI if they didn't "opt-in" to being bothered during autofill. (Which is different from "the create() can resolve silently if the user consented previously".)

While user agents can ultimately implement any UI, how do you want sites thinking about how to use this extension?


: Extension identifier
:: `conditionalCreate`

: Operation applicability
:: [=authentication extension|Authentication=]

: Client extension input
:: The Boolean value [TRUE] to indicate that this extension is requested by the [=[RP]=].
<xmp class="idl">
partial dictionary AuthenticationExtensionsClientInputs {
boolean conditionalCreate;
};
</xmp>

: Client extension processing

:: When [[[#sctn-getAssertion|assertion]]:
1. Just after [establishing the RP ID](#GetAssertion-DetermineConditional) perform these steps:
pascoej marked this conversation as resolved.
Show resolved Hide resolved

1. If <code>|options|.{{CredentialRequestOptions/mediation}}</code> is not present or does not have the value
{{CredentialMediationRequirement/conditional}}:

1. Throw a "{{NotAllowedError}}" {{DOMException}}

1. When [showing conditional assertion form control](GetAssn-ConditionalMediation-Interact-FormControl):
pascoej marked this conversation as resolved.
Show resolved Hide resolved

1. Inform the user that the RP will create a credential if the user agent mediates the authentication ceremony.
pascoej marked this conversation as resolved.
Show resolved Hide resolved

1. Set conditionalCreateLifetimeTimer to a client-specific default.
pascoej marked this conversation as resolved.
Show resolved Hide resolved

1. Set conditionalCreateOrigin to the current origin.

1. If the user agent mediates the authentication ceremony while the conditional assertion is running:

1. Start conditionalCreateLifetimeTimer.

1. Optionally collect an [=authorization gesture=] confirming [=user consent=] to create the credential which may later be used to skip (this step)[#op-makecred-step-user-consent] when processing an associated {{CredentialsContainer/get()|navigator.credentials.get()}} call with <code>|options|.{{CredentialRequestOptions/mediation}}</code> set to {{CredentialMediationRequirement/conditional}}.
pascoej marked this conversation as resolved.
Show resolved Hide resolved

: Client extension output
:: None


### Credential Properties Extension (<dfn>credProps</dfn>) ### {#sctn-authenticator-credential-properties-extension}

Expand Down