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 5 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
93 changes: 80 additions & 13 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|.{{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. [=[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()}}.

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 @@ -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,15 @@ 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}}.

Note: |conditionalCreateLifetimeTimer| and |conditionalCreateOrigin| will be set by the user agent after it believes an authentication ceremony has been completed and the user consents to this type of credential creation.

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 +2202,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 +2210,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 @@ -2265,19 +2284,22 @@ When this method is invoked, the user agent MUST execute the following algorithm

1. Let |pkOptions| be the value of <code>|options|.{{CredentialRequestOptions/publicKey}}</code>.

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

1. Let |credentialIdFilter| be the value of <code>|pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code>.
<li id='GetAssn-DetermineConditional'>
emlun marked this conversation as resolved.
Show resolved Hide resolved
If <code>|options|.{{CredentialRequestOptions/mediation}}</code> is present with the value
{{CredentialMediationRequirement/conditional}}:

1. Set <code>|pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> to [=list/empty=].
1. Let |credentialIdFilter| be the value of <code>|pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code>.

Note: This prevents [=non-discoverable credentials=] from being used during {{CredentialMediationRequirement/conditional}} requests.
1. Set <code>|pkOptions|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> to [=list/empty=].

1. Set a timer |lifetimeTimer| to a value of infinity.
Note: This prevents [=non-discoverable credentials=] from being used during {{CredentialMediationRequirement/conditional}} requests.

Note: |lifetimeTimer| is set to a value of infinity so that the user has the entire lifetime of
the [=Document=] to interact with any <{input}> form control tagged with a `"webauthn"` [=autofill detail token=]. For example, upon the user clicking in such an input field, the user agent can render a list of discovered credentials for the user to select from, and perhaps also give the user the option to "try another way".
1. Set a timer |lifetimeTimer| to a value of infinity.

Note: |lifetimeTimer| is set to a value of infinity so that the user has the entire lifetime of
the [=Document=] to interact with any <{input}> form control tagged with a `"webauthn"` [=autofill detail token=]. For example, upon the user clicking in such an input field, the user agent can render a list of discovered credentials for the user to select from, and perhaps also give the user the option to "try another way".
</li>

1. Else:

Expand Down Expand Up @@ -4888,7 +4910,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 +6735,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 if the authentication ceremony is completed successfully.

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]]:
pascoej marked this conversation as resolved.
Show resolved Hide resolved
1. Just after [establishing the RP ID](#GetAssn-DetermineConditional) perform these steps:

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):

1. Inform the user that the [=[RP]=] will create a credential if the user agent mediates the authentication ceremony.

1. Set |conditionalCreateLifetimeTimer| to a client-specific default. A period of at least two minutes is RECOMMENDED.

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].

: Client extension output
:: None


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

Expand Down