[webauthn] Possible experiences in a future WebAuthn (#1637)

agl has just created a new issue for https://github.com/w3c/webauthn:

== Possible experiences in a future WebAuthn ==
Dear WG members,

With the publication of WebAuthn Level Two and CTAP 2.1, the WebAuthn standard is now reasonably mature. Google has been talking with some other parties about how to build upon this to help sites fully migrate their users to a new default credential built on WebAuthn that can broadly replace the username+password pattern.

Some components of these ideas have been discussed for some time, or have been recently made public:
* Apple [discussed](https://developer.apple.com/videos/play/wwdc2021/10106/) syncing of platform credentials at WWDC a few weeks ago. ([Summary]( https://www.cnet.com/news/apple-says-its-new-logon-tech-is-as-easy-as-passwords-but-far-more-secure/))
* Google has been talking about caBLE and phones as security keys for quite a while.
* Microsoft have [supported](https://www.microsoft.com/en-us/microsoft-365/blog/2018/11/20/sign-in-to-your-microsoft-account-without-a-password-using-windows-hello-or-a-security-key/) 1st-factor sign-in via WebAuthn for some years.
* #1576 sketches out ideas for how WebAuthn UI might be more hospitable to RPs that have a population of people used to passwords.
* #1546 raises the possibility of associating a second, device-bound key with a credential.

With this message (which is really an abuse of the GitHub issue system to post something!) we would like to draw these threads together.

(Also, we would like to briefly acknowledge that password managers and federation provide some of the same benefits as WebAuthn and we wish to note that nothing in this message signals a reduction in investment in these areas by Google.)

### Possible experiences in a future WebAuthn

In order to motivate discussions about what WebAuthn changes may be needed to support wider adoption we would like to sketch some user experiences that we might want to enable:

When signing up on a new website, rather than being forced to choose a password, a user is invited to register a WebAuthn authenticator. They choose to register their phone, using a technology like caBLE. This creates a discoverable credential on the phone and that credential is encrypted and synced so that loss of the phone doesn’t lock the user out.

Later, that same person picks up their phone and goes to the website of that service. The autocomplete UI in the browser offers the discoverable credential as a sign-in option, which can be exercised by using the biometric sensors on the phone. If the user installs the service’s app on their phone then the credential will also be available to facilitate sign-in there.

When signing in on a different computer, either the credential will already be locally present (if the computer is using the same sync fabric as the phone) and suggested by autocomplete, or else the user’s phone can be used to transmit the assertion to the computer. In the latter case, the service may invite the user to enroll a local platform authenticator for easier sign-in in the future. (Now the newly registered credential may be part of a different sync fabric, and thus enable local sign-in on other devices.)

When signing into existing services using a username+password, those services can offer to enroll a WebAuthn credential and, ultimately, _delete_ the user’s password. For such users, we would expect a significant reduction in account recoveries as synced credentials solve many issues that previously required site-specific recovery flows.

Very roughly, phones become roaming authenticators capable of creating “durable” credentials: ones which can survive loss of the device. Within an ecosystem of devices, credentials may be synced between devices but there is also caBLE-like support for bridging between devices and thus between ecosystems.

In this world, physical security keys continue to serve important uses as there exist many contexts where syncable credentials on phones do not meet regulatory-, compliance-, or security-related needs. If we can grow the ecosystem of WebAuthn-enabled services with an experience like this then we hope for the use of physical security keys to grow too, although we do not expect the typical consumer user to have them.

As a measure to potentially address some of the challenges of introducing syncable credentials we have [floated](https://github.com/w3c/webauthn/issues/1546) the idea that syncable credentials may be paired with an automatically-generated, device-bound key pair. That would be a WebAuthn extension. This document is about changes to the core WebAuthn API, so that topic will be developed in a different GitHub issue.

### Possible API changes

#### Conditional UI

*Status*: we think this is reasonable; seeking things that we might have missed.

When a site has no ambient identity information it can present two methods for WebAuthn sign-in if window.PublicKeyCredential is present:

Include an explicit button / link. When clicked, make a WebAuthn get() call with uv=preferred/required and no allow-list.
If [navigator.credentials.conditionalMediationSupported](https://docs.google.com/document/d/11hWpUPAnblPtkn1f7AIQW0ujoiu_BAKzlMVhZKQPiW8/edit#) is true and there’s a username entry textbox on the page then include username-webauthn as an [autocomplete attribute token](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete) and make a WebAuthn get() call with [mediation=conditional](https://www.w3.org/TR/credential-management-1/#dom-credentialrequestoptions-mediation), uv=preferred/required, and no allow-list.

The first of these is already standard. The second is new. The links above take you to our existing proposal for an API to invoke a UI that facilitates a transition to WebAuthn. (It needs some updating to focus on autocomplete rather than a pop-up.) We feel that the username and password field are currently a recognisable pattern for sign-in and propose that, by integration with auto-complete, we can create a much smoother experience for users who are used to passwords.

Supporting a conditional WebAuthn call will need some additional spec changes because there can currently only be a single WebAuthn call active on a page. But this envisions that clicking the button would invoke a modal UI even though the conditional call is still running in the background.

UV may be either preferred or required and suggest that, for many sites, “preferred” is the best option. For computers without biometrics, “preferred” may, depending on the platform, allow the credential to work as smoothly as an auto-filled password, while “required” would force the user to enter something like their local login password. On devices with biometric sensors, “preferred” will still use them. Of course, the UV bit in the assertion will be set accordingly in all cases.

#### Assertion transports

*Status*: we think this is reasonable; seeking things that we might have missed.

In order for a site to know whether a local platform authenticator was used, or whether the user used another device and thus might want to register a local platform authenticator, we propose that a transport field be added to assertion responses.

Thus, if the proposed transport field of the assertion is not “internal”, and isUVPAA returns true, then sites may offer to the user to register the current device's platform authenticator.

(In order to avoid superfluously re-registering devices if the user happened to use a phone or security key to sign in, even though the platform authenticator is already registered, the site may wish to track the registration status of the platform authenticator in local state. If the assertion transport _was_ “internal” then the local state should be set to reflect that.)

#### Preventing unintended credential overwrites

*Status*: we think this is reasonable; seeking things that we might have missed.

A given authenticator only stores a single discoverable credential for a given (RP ID, user ID) pair. Some authenticators always create discoverable credentials. This can lead to a situation where a platform credential is unexpectedly overwritten by a second registration on the same platform.

We propose that, in order to register a platform authenticator, sites make a WebAuthn create() call with rk=required, uv=preferred/required, attachment=platform. excludeCredentials must list  all registered credential IDs for the current user. If the result is an InvalidStateError then the current computer was already registered and nothing more needs to be done. Thus the site should ignore the error.

An excluded credential indicates that an authenticator is unacceptable. For the case where attachment=platform, there are no other possible authenticators. In this case, we think that platform authenticators should align so that the UI does not reflect any sort of problem and this distinctive error is returned. InvalidStateError is already specified in WebAuthn for this situation and is unambiguous. 

(Of course, the standard UI interaction will still be required; this is not a method for silent challenges.)

For attachment=any there are other possible authenticators. So trying to use the platform authenticator when an excluded credential matches is still a user-visible error in that case.

(If the site is tracking the registration state of the platform authenticator in local state then it should update it after a successful registration.)

#### Reauthentication

*Status*: no API changes here, but perhaps a change of best-practices.

If a site knows the identity of a user but wants to reassert that the correct human is holding the device / at the keyboard then they should make a traditional get() call with uv=required and include the full set of known credential IDs for the current user in the allow list.

We do not suggest remembering a single credential ID in a cookie. Any of the user’s authenticators can be used. I.e. if they signed in with caBLE but have a credential on the current computer too (perhaps made after this session was signed in) then they can use the local device for reauthentication.

#### Upgrading to WebAuthn

*Status*: we think this is reasonable; seeking things that we might have missed.

If a user signs in with another method (e.g. username + password) then we propose that sites test if [navigator.credentials.conditionalMediationSupported](https://docs.google.com/document/d/11hWpUPAnblPtkn1f7AIQW0ujoiu_BAKzlMVhZKQPiW8/edit#) and isUVPAA are both true. If so then offer to the user to use WebAuthn. If they accept, make a WebAuthn create() call with rk=required, uv=preferred/required, and an exclude list that contains all the known credentials for this user.

isUVPAA would remain false if there wasn’t a platform authenticator available but a linked caBLE device was available. Thus computers without a platform authenticator wouldn’t be prompting users to switch to WebAuthn. We felt that this was simpler than adding another isUVPAA-like function.

The test for conditionalMediationSupported is based on the assumption that the site will want to use the conditional UI during sign-in, and that that signal will be a proxy for caBLE support.

(In order to avoid superfluously re-registering devices if the user happened to use a password to sign in, even though the platform authenticator is already registered, the site may wish to track the registration status of the platform authenticator in local state.)

#### Durable signal

*Status*: speculative; we’re not sure about this.

If we are suggesting to sites that passwords could be deleted once WebAuthn is used, then it’s important for them to know whether a credential is “durable” (i.e. backed up) or whether it disappears with device loss. Registering a single durable credential may be a strong enough signal to offer to delete the user’s password, but perhaps several non-durable credentials are needed.

Without such a signal sites may conservatively keep the password path for nearly everyone, and passwords will turn into an obscure backdoor that people leave unattended. Thus we have wondered about defining [authenticator data](https://www.w3.org/TR/webauthn-2/#authenticator-data) flag bit 3 to be: 0 = lost upon device loss, 1 = durable (i.e. synced).

(This could be an extension, but we have these bits to use and, if we ever get to the last bit, we can just define an “extended flags” extension at that time.)

Since it’s in the authenticator data, this information is also provided with every assertion. Thus a credential can become durable at a later date. A phone, for example, may not want to initially set the durable flag during registration if it hasn’t successfully uploaded the encrypted credential at that point.

(Physical security keys could also adopt this if they offered a mechanism for backing up credentials and thus could potentially support the extension for a second, device-bound key too.)

#### Credential management

*Status*: no API changes here, but we think this makes sense.

Platform authenticators will offer users the ability to enumerate, delete, and change the displayName of credentials via local UI. While sites can still overwrite credentials with a create() call, same as today, they can leave updating of displayName fields to the platform if they wish.

(We are not suggesting that W3C specs should try and mandate things out of their scope like this. Rather we are seeking to communicate our expectations in order to aid consideration of this proposal.)

#### Report signaling

*Status*: speculative; we’re not sure about this _at all_.

If a credential is deleted on a site, it will not be automatically deleted on the corresponding authenticator. Also, if a site attempts to overwrite a credential with a create() call, there’s a risk that the new credential will not reach the server and the user will be locked out.

Thus we have some ideas around an augmentation of CredMan that allows signals about credentials to be asynchronously asserted to the browser by a site:

navigator.credentials.report() would take the following:

```
dictionary CredentialReportOptions {
  DOMString signal;  // “deleted”, “rejected”, or “accepted”.
};
```

That dictionary would be merged with type-specific members, as the other CredMan options dicts are, so that a call like the following would work:

```
navigator.credentials.report({
  signal: “accepted”,
  publicKey: {
    id: credentialId,
  },
})
```

The signals would mean:

 * _deleted_: that the given credential ID has been deleted by the user. This should promptly follow the user taking some action on the site to delete the credential. Perhaps if the browser knows that it’s a local credential the user might be asked if they wish to delete it locally. (But the site does not learn what happened. Perhaps the browser did nothing.)

 * _rejected_: the site rejected the assertion for the given credential ID. This should promptly follow such an assertion being provided by the browser. If that credential recently overwrote another, perhaps that should be reverted. If not, perhaps the user should delete that credential because it is no longer recognised by the server.

 * _accepted_: this site accepted the assertion for the given credential ID. This should promptly follow such an assertion being provided by the browser. If older versions of that credential were being kept around because the platform didn’t know if an overwrite reached the server, then they could be released.


— Adam & Jeff

Please view or discuss this issue at https://github.com/w3c/webauthn/issues/1637 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 1 July 2021 20:22:31 UTC