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 16 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
46 changes: 39 additions & 7 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Former Editor: Rolf Lindemann, w3cid 84447, Nok Nok Labs, [email protected]
!Contributors: <a href="mailto:[email protected]">Christiaan Brand</a> (Google)
!Contributors: <a href="mailto:[email protected]">Adam Langley</a> (Google)
!Contributors: <a href="mailto:[email protected]">Giridhar Mandyam</a> (Qualcomm)
!Contributors: <a href="mailto:[email protected]">Pascoe</a> (Apple)
pascoej marked this conversation as resolved.
Show resolved Hide resolved
!Contributors: <a href="mailto:[email protected]">Nina Satragno</a> (Google)
!Contributors: <a href="mailto:[email protected]">Ki-Eun Shin</a> (SK Telecom)
!Contributors: <a href="mailto:[email protected]">Nick Steele</a> (1Password)
Expand Down Expand Up @@ -1582,15 +1583,16 @@ that are returned to the caller when a new credential is created, or a new asser

: {{PublicKeyCredential/isConditionalMediationAvailable()}}
:: {{PublicKeyCredential}} overrides this method to indicate availability for {{CredentialMediationRequirement/conditional}}
mediation. [=[WRPS]=] SHOULD verify availability before attempting to set
<code>|options|.{{CredentialRequestOptions/mediation}}</code> to {{CredentialMediationRequirement/conditional}}.
mediation during {{CredentialsContainer/get()|navigator.credentials.get()}}. [=[WRPS]=] SHOULD verify availability before
attempting to set <code>|options|.{{CredentialRequestOptions/mediation}}</code> to {{CredentialMediationRequirement/conditional}}.

Upon invocation, a promise is returned that resolves with a value of [TRUE] if {{CredentialMediationRequirement/conditional}}
[=user mediation=] is available, or [FALSE] otherwise.

This method has no arguments and returns a promise to a Boolean value.

Note: If this method is not present, {{CredentialMediationRequirement/conditional}} [=user mediation=] is not available.
Note: If this method is not present, {{CredentialMediationRequirement/conditional}} [=user mediation=] is not available for
{{CredentialsContainer/get()|navigator.credentials.get()}}.

: {{PublicKeyCredential/toJSON()}}
:: This operation returns {{RegistrationResponseJSON}} or {{AuthenticationResponseJSON}},
Expand Down Expand Up @@ -1736,8 +1738,16 @@ 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|.{{CredentialCreationOptions/mediation}}</code> to {{CredentialMediationRequirement/conditional}},
[=[RPS]=] can indicate that they would like to register a credential without prominent modal UI if user has already consented to create a credential. The [=[RP]=] SHOULD first check that {{ClientCapability/conditionalCreate}} is present
in the result of {{PublicKeyCredential/getClientCapabilities()}} 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()}}.
The authenticator SHOULD set BOTH |userPresence| and |userVerification| to |FALSE| when <code>|options|.{{CredentialCreationOptions/mediation}}</code> is set to {{CredentialMediationRequirement/conditional}}
Copy link
Member

@timcappalli timcappalli Apr 3, 2024

Choose a reason for hiding this comment

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

s/SHOULD/MUST

unless explicitly collected during the ceremony.
Copy link
Member

Choose a reason for hiding this comment

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

This section is the client operation, but this is a requirement on the authenticator. This needs to go in section 6 (WebAuthn Authenticator Model) instead, or be rewritten in terms of how the client is to set the arguments to the authenticator operation.


Any {{CredentialsContainer/create()|navigator.credentials.create()}} operation can be aborted by leveraging the {{AbortController}};
see [[dom#abortcontroller-api-integration]] for detailed instructions.


Expand Down Expand Up @@ -1776,6 +1786,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|.{{CredentialCreationOptions/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 @@ -1912,6 +1927,16 @@ 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|.{{CredentialCreationOptions/mediation}}</code> is present with the value
{{CredentialMediationRequirement/conditional}}:

1. If the user agent has not recently mediated an authentication, the origin of said authentication is not |callerOrigin|, or the user
does not consent to this type of credential creation, throw a "{{NotAllowedError}}" {{DOMException}}.

It is up to the user agent to decide when it believes an authentication ceremony has
been completed. That authentication ceremony MAY be performed via other means than the
[=Web Authentication API=].

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 @@ -2000,7 +2025,14 @@ a numbered step. If outdented, it (today) is rendered as a bullet in the midst o
<dl class="switch">

: is set to {{UserVerificationRequirement/required}}
:: Let |userVerification| be [TRUE].
:: If <code>|options|.{{CredentialCreationOptions/mediation}}</code> is set to
<dl class="switch">
: {{CredentialMediationRequirement/conditional}}
:: throw a {{NotAllowedError}} {{DOMException}} unless it can be explicitly collected during the ceremony.

: empty or another value
:: Let |userVerification| be [TRUE].
</dl>
Copy link
Member

Choose a reason for hiding this comment

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

The flow here is a bit convoluted, I would formulate it something more like this:

Suggested change
:: If <code>|options|.{{CredentialCreationOptions/mediation}}</code> is set to
<dl class="switch">
: {{CredentialMediationRequirement/conditional}}
:: throw a {{NotAllowedError}} {{DOMException}} unless it can be explicitly collected during the ceremony.
: empty or another value
:: Let |userVerification| be [TRUE].
</dl>
:: 1. If <code>|options|.{{CredentialCreationOptions/mediation}}</code> is set to {{CredentialMediationRequirement/conditional}}
and [=user verification=] cannot be collected during the ceremony,
throw a {{NotAllowedError}} {{DOMException}}.
1. Let |userVerification| be [TRUE].

Copy link
Member

Choose a reason for hiding this comment

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

Also, is NotAllowedError the right behaviour here? The closest analogue currently in the spec is the "error code equivalent to ConstraintError" returned by the authenticator when UV is required but cannot be satisfied by that authenticator. Returning an error at all also differs from conditional mediation in get(), which simply hangs forever on most errors. Should conditional create do that too?

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 idea with conditional registration is that you invoke it right after logging in and get a result quickly. If the user didn't consent to this type of create, then they will quickly get an error, otherwise a credential.

I think ConstraintError does sound okay in this case. I've made the change.


: is set to {{UserVerificationRequirement/preferred}}
:: If the |authenticator|
Expand Down Expand Up @@ -2199,7 +2231,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|.{{CredentialCreationOptions/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 via means determined by the user agent.
timcappalli marked this conversation as resolved.
Show resolved Hide resolved
</div>


Expand Down
Loading