Skip to content

Support a "create or get [or replace]" credential re-association operation #1568

Open
@lgarron

Description

@lgarron

Proposal

I would like to propose the addition of a way for an RP ask the browser to:

  • Show a create-style prompt the user to create a new credential (matching certain selection criteria), if possible.
  • Otherwise, show a get-style prompt for the user to authenticate using an existing credential matching those criteria, if possible.

In essence: "create or get", where "or" has the same meaning as in most programming languages (take the second branch if the first was unsuccessful). This could be implemented as:

  • An option for create (indicating to use its excludeCredentials as allowCredentials for the get fallback, along with the same selection criteria).
  • A new API call in addition to create and get.

Note that there are situations where the site is trying to ensure that they end up with a credential that matches certain criteria (e.g. discoverable credential, or platform authenticator) but does not know exactly which existing registrations match those criteria (i.e. if the RP cannot tell because some of those registrations were created with different selection criteria). In this case, it's valuable for the selection criteria to filter the get-style prompt.

(Perhaps "get or create" might make more sense, or maybe it could be useful to give the RP the choice of preference between the operations. In any case, the overall idea is similar.)


Motivation

I originally asked about this #1533 and I felt like it was closed quickly because this was an intentional omission of the spec. However, after a lot of work on GitHub's WebAuthn implementation, and several dozen emails with browser authors, it seems that there is still a fundamental issue with authenticators that are shared across multiple browser profiles (as is the case with Windows Hello):

  • It is impossible for the RP to tell if the user has an existing registration or not.
    • If the RP always prompts the user to create a new credential in a fresh browser session, the expected user experience is that the user encounters an error. This sounds pretty undesirable to me.
    • If the RP offers UI with buttons for both "create" and "get", then they are making their registration flow needlessly complicated for new device registrants. This also puts responsibility on the user to remember on which sites/devices/browsers they have signed in before, which seems counter to goals of folks working on WebAuthn. It also requires sites to put in extra engineering effort to handle both cases where the user picked the wrong choice of "create" or "get".

Note that:

  • Some browsers create discoverable credentials even if the RP does not ask for it.
    • In particular, this means that they may create credentials in a way that invalidates previous registrations for the same RP, even if the RP did not ask for this. (Safari and Windows Hello both do this at the moment.)
  • RPs may not want to use discoverable credential auth at the time they first start creating discoverable credentials. They may set residentKey: "preferred" but initially only use the credentials as if they were server-side.
  • As far as I know, there are no browsers that currently allow users to manage registrations. Registrations remain forever (unless evicted by new registrations, in some browsers).
  • It is currently hard to tell if a create call failed due to an existing registration: Can RPs assume that InvalidStateError for create() means an excludeCredentials match? #1566

This puts a wrench in certain hacky workarounds, like using a different user handle for each browser session (which not only seems contrary to the intention of the user handle, but can result in a ballooning set of redundant registrations if discoverable credentials are created).

It can also cause issues with sites that have existing registrations for security keys, and want them to keep working while adding support for passwordless flows: #1569


I'd argue that the benefits of a "create or get" operation like this outweigh the complexity or security implications. It would allow RPs to:

  • Check for isUserVerifyingPlatformAuthenticatorAvailable()
  • If true, show a simple prompt saying "would you like to use your device's built-in authenticator to sign in to this site?"

To me, it seems that this would support the priority of constituencies better than only supporting create or get in the spec.

(EDIT: I flipped the "get" and "create" order after reading @equalsJeffH's comment at #1567 (comment) , since most sites would probably prefer the get path over creating additional credentials..)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions