w3c / webauthn

Web Authentication: An API for accessing Public Key Credentials
https://w3c.github.io/webauthn/
Other
1.18k stars 171 forks source link

Should an RP be able to provide finer grained authenticator filtering in attestation options? #1688

Open sbweeden opened 2 years ago

sbweeden commented 2 years ago

The use case in mind is when an RP is required to enforce attestation-based registration requirements. Why not allow the RP to suggest in attestation options a richer set of acceptable authenticator properties?

An extreme here might be an AAGUID allow-list however there are other scenarios such as allowing an RP to express that it does not wish to leverage passkeys. If the RP is able to provide these types of constraints up front in attestation options it would permit a more streamlined client UX during registration flows.

ve7jtb commented 2 years ago

If a RP sent a flag to disable passkeys would the platform not make the credential on the platform authenticator if that authenticator only supported passkey credentials, and prompt the user to use an external authenticator?

We did add certifications to GetInfo In speculation of browser or RP policy eventually allowing for restricting creation FIPS 140 or something like that in regulated environments.

I can see providing a list as being useful in some situations, though it would likely add a fair bit of complexity if it is general purpose and may cause more people to shoot themselves in the foot.

I am interested in @agl ;s take on this.

timcappalli commented 2 years ago

If an RP does not wish to leverage platform passkeys, they can request a hardware-bound device public key using the extension.

ve7jtb commented 2 years ago

Shane and I have been talking with Max H in the consumer deployment working group.

I think he is looking for a simple way for RP to disable passkey without having to completely change all their existing webAuthn logic. That is I think partially where this request is coming from.

I suspect that @timcappalli is correct and any RP not wanting to accept passkey replication is going to have to do the work to redesign their backend to support that.

Keeping the default hardware-bound keys and making the RP do something to accept passkeys received a negative response at the plenary.

I understand that the desire is for the default to be what platforms consider to be the larger use case.

timcappalli commented 2 years ago

I think terminology and wording is important. An RP can't disable a certain credential export behavior. They can, however, request a second device-specific, hardware bound key, if they have a use case that requires this (and results in a degradation of user experience).

Another important note is that an existing platform credential does not automatically become a passkey on platform flag days.

sbweeden commented 2 years ago

They can, however, request a second device-specific, hardware bound key and ignore the passkey, if they have a use case that requires this (and results in a degradation of user experience).

Can you really "ignore the passkey"?

Shouldn't the RP during registration actually store both the passkey user credential, and the device-bound key, verifying the attestation of both, then on subsequent authentication flows request the device-bound key extension, verifying the authentication signature of the both the passkey public key and that in the extension, and make sure both the authenticating passkey credential is a property of the user's account, plus the credential in the extension is already associated with the user's passkey credential?

That's how I understood the requirements of the extension to work, which is actually quite complicated for RPs to implement.

As a related topic, what would happen if the credentialID of the device-bound credential observed in extension output during creation was used as a credentialID in the allowCredentials list of a subsequent authentication flow? I don't know of any currently defined behaviour for such a thing.

ve7jtb commented 2 years ago

@sbweeden that is how I understand it as well.

I believe there is only one credentialID with two public keys per device.

So if the user has three devices the RP stores one CredentialID and four related public keys.

One for the passkey and one for each of the devices.

It will be a major change for RP that want to keep using device bound credentials .

I am not necessarily arguing against this approach, but we need to be honest and realistic about the impact on enterprises and regulated entities.

My concern is those organisations will just ban all platform authenticator AAGUID for however many years it will take them to update the backends.

I will note that some organisations like SalesForce are just now migrating from U2F. Others like Bank of America have just rolled out WebAuthn. If we expect them to be able to deal with these changes by the time passkeys launch we need to start reaching out to them now. A spec may also be helpful.

emlun commented 2 years ago

[...] Why not allow the RP to suggest in attestation options a richer set of acceptable authenticator properties?

An extreme here might be an AAGUID allow-list [...]

This is precisely what the authnSel extension does. It was removed from L2 for lack of client implementations, but it still "exists" in the sense that it's there and "ready to go" if someone were to implement it.

Also it seems like I'm a bit out of the loop, what does "passkey" mean in this context?

dwaite commented 2 years ago

Also it seems like I'm a bit out of the loop, what does "passkey" mean in this context?

Someone correct me if they are using the term differently, but I expect a combination of:

  1. Conditional UI through mediation, possibly used to make the UX appear closer to the "password manager form fill" experience
  2. An authenticator which has credentials exported from the device to provide account-held credentials rather than device-held credentials. So far this appears to be more of a platform-proprietary synchronization feature than a general-purpose credential export.
  3. Device-bound keys available an extension as more of a risk-system trigger - this is also being added as an alternative to behavioral selection for higher-assurance use cases (including the potential of those organizations rejecting some platform-issued credentials)
timcappalli commented 2 years ago

A passkey is a durable/survivable, FIDO2 discoverable credential (disclaimer: we're still tweaking the formal/official definition). The items @dwaite listed are features to support passkeys.

agl commented 2 years ago

A birdshot of thoughts:

While sites do not have assurance that a credential is device-bound today without checking the attestation, I accept that there is a norm that it will be, and that syncing credentials does perturb that. However, on the operating systems where Google provides a platform authenticator (i.e. Android and Chrome OS) our plan is that non-discoverable credentials will continue to be bound to the device as they always have been. Thus any RPs currently/planning to use non-discoverable credentials(*) are not disrupted.

(*) and those platforms don't support discoverable credentials yet(). () sorry; we know.

As noted above, sites that want to use passkeys and which feel that they can productively incorporate visibility about different devices into their risk calculations can use the device-bound key extension. This gives them the same device-bound properties as always, with additional information about who the sync provider believes the the user is. I hope that passkey support ships concurrently with support for that extension so that there's no gap. It is more work for the RPs to support, but it feels correct that sites with more complex needs deal with the more complex interface rather than the other way around.

About the authenticator selection extension itself: We have never implemented it because we don't feel that authenticator discrimination is broadly a good thing. Multiple different RPs might each have locally valid reasons for wanting to select the authenticators that are permitted on their site, but the sum of this is that users need to have multiple authenticators to span the set of different site policies that they encounter, they have to remember which goes with each site, and they can't have the expectation that a given security key will broadly work where they want to use it.

That argument isn't compelling in an enterprise setting where a company is distributing security keys for people to use specifically with their systems. Thus we wouldn't have a policy objection to supporting authenticator selection for RPs listed in an enterprise policy. But the feedback that we received was that depending on enterprise policy on the client was problematic. That's why enterprise attestation was incorporated in CTAP 2.1. It allows the policy to be contained on the security key itself and thus avoids this restriction. It's true that attestation is an after-the-fact rejection of a registration, but in an enterprise setting the enterprise is probably better equipped than the browser to communicate why a registration was rejected, and an enterprise always needs to check attestation if they want to require a specific authenticator because the client could ignore the authsel extension.

equalsJeffH commented 2 years ago

on 23-Feb-2022 call: @sbweeden's position is that enterprise RPs wish to be able to establish their needs up-front when doing makeCred(), rather than after-the-fact (eg by examining resulting cred flags and/or attestation). @ve7jtb seems that there would be a number of potential issues/special-cases in trying to broadly address this @agl notes that giving RPs more tools to discriminate amongst authnrs will lead to situation we are trying to avoid where users have a plethora of authnrs and one or some work with one or some RPs.... though perhaps putting this sort of feature behind an "enterprise policy" is something to consider....

Firstyear commented 2 years ago

@sbweeden But nothing can be truly asserted or trusted from the initial makeCred, you can only trust things that are signed in the response from the attestation. So it's not possible to achieve this "up front" need selection ....

sbweeden commented 2 years ago

@sbweeden But nothing can be truly asserted or trusted from the initial makeCred, you can only trust things that are signed in the response from the attestation. So it's not possible to achieve this "up front" need selection ....

At no point was I suggesting that verification is not still required at the server - it is. The reason for desiring up-front authenticator selection criteria is to improve the UX for legitimate registration use cases. This is the same reason for example that front-end JS is used to do initial form field validation for email/integer/etc rather than wait till everything be posted to the server and then rejected.

ChadKillingsworth commented 2 years ago

From my perspective, the ability to restrict or hint authenticator type is not to ban authenticator types that are not trusted, but instead to improve the user experience. I would like to heavily favor platform authenticators for the primary authentication flow and segregate user-verifying cross-platform authenticators to account recovery flows. The current UX provided is too confusing for my users unless they are first identified by username where the authenticator choice can be restricted. Even the CABLE use cases suggest upgrading the user to device-bound authenticators when possible.

I do intend to fully support passkeys as soon as they are ready.

1716 requested to restrict authenticators by transport, but I believe attachment is much more valuable.

For perspective, my company is a a major financial services provider for the US with millions of users and has had Webauthn passwordless logins in production for over a year.

The conditional mediated UI work will assist in the user experience, but is not a complete solution.

sbweeden commented 2 years ago

@ChadKillingsworth Can you please clarify what the ask is (if any) from your perspective?

I noticed you said that you want to favour selection by attachment, which is available today in attestation options, though these things are always a hint to the browser and if it's a requirement must be confirmed with attestation.

Are you saying that the current options are satisfactory for your use case, or are you looking for something else?

ChadKillingsworth commented 2 years ago

These are a confusing set of topics that's for sure. What I want is something like:

navigator.credentials.get({
  publicKey: {
    challenge: new Uint8Array([/* bytes sent from the server */]),
    userVerification: true,
    authenticatorSelection: {
      attachment: "platform" // this is the missing piece
    }
  }
})

There's been some discussion of doing this via extensions, but also an acknowledgement that no user agent currently recognizes the extensions. Or did I miss a capability that already is in the spec? This could be accomplished with transport filtering as well, but I'm personally more interested in attachment.

sbweeden commented 2 years ago

I would have thought you could indicate this with:

navigator.credentials.create({
  publicKey: {
    challenge: new Uint8Array([/* bytes sent from the server */]),
    authenticatorSelection: {
      "authenticatorAttachment": "platform"
      "userVerification": "required" /* or "preferred" */
    }
  }
})

Note both the placement of userVerification and authenticatorAttachment are within authenticatorSelection. There are additional parameters required and not shown (such as user.id).

With this clarification, is your use case satisfied by the current specifications?

ChadKillingsworth commented 2 years ago

The spec doesn't currently have an authenticatorSelection option at all on a PublicKeyCredentialRequestOptions object.

Unless I'm looking at an old spec.

sbweeden commented 2 years ago

Ok - you are looking at assertion options. This github issue started on the topic of attestation options (credential creation), which uses PublicKeyCredentialCreationOptions.

sbweeden commented 2 years ago

You are correct with regards to login operations and I have subsequently updated my earlier comment to indicate use of navigator.credentials.create instead of navigator.credentials.get.

ChadKillingsworth commented 2 years ago

Should I start a new issue? I was trying hard not to create a duplicate. #1716 was closed but at least someone indicated that it was a duplicate of this issue.

sbweeden commented 2 years ago

I think it depends on whether or not there is a need for something new in the spec to satisfy your use case requirements. I'm not sure there is, but if you can explain the scenario you're trying to achieve and what you're currently seeing that is different from that ... well that might help.

Take for example the current developer-tech-preview Apple Passkey implementation. If I initiate a navigator.credentials.get operation (without an allowCredentials list), and already have a passkey registered, Safari will automatically default to using the passkey. Similarly with Chrome, if I have a discoverable platform credential created (at least on my Mac), and initiate a navigator.credentials.get operation, that is automatically preferred. Note that these are browser implementation decisions, not something controlled by options supplied by the RP, but I think that's behaving the way you want?

james-d-elliott commented 2 years ago

The spec doesn't currently have an authenticatorSelection option at all on a PublicKeyCredentialRequestOptions object.

Unless I'm looking at an old spec.

This can already be technically achieved using the allowCredentials option. At the time of attestation you record enough information to know this credential is of the particular criteria you want, and only populate allowCredentials during assertion with the ID's of credentials which match your selected criteria.

Firstyear commented 2 years ago

This can already be technically achieved using the allowCredentials option. At the time of attestation you record enough information to know this credential is of the particular criteria you want, and only populate allowCredentials during assertion with the ID's of credentials which match your selected criteria.

People want the ability to do finer grained selection during registration, not authentication.

For example, if we issue only usb-yubikeys to our employees, when they register the key it should only allow USB transports.

Today, as it is browsers like chrome will offer for caBLE and USB. If a user tries to use caBLE it will fail, and the RP has to explain why.

Effectively the problem is of communication. Will the Webauthn WG allow RP's to communicate to browsers/users about what devices are valid in that context, helping to add constraints and create a positive, error free user experience? Or will the WG reject this issue again, and force RP's to communicate with users "after errors occur", which is a far more difficult process and pushes RP's to have to do much more work, to account for a gap in this standard.

ChadKillingsworth commented 2 years ago

If I initiate a navigator.credentials.get operation (without an allowCredentials list), and already have a passkey registered, Safari will automatically default to using the passkey. Similarly with Chrome, if I have a discoverable platform credential created (at least on my Mac), and initiate a navigator.credentials.get operation, that is automatically preferred. Note that these are browser implementation decisions, not something controlled by options supplied by the RP, but I think that's behaving the way you want?

It is. However it makes me somewhat uncomfortable to be completely reliant on the user agent behavior. I'd much prefer the spec to address this directly.

This can already be technically achieved using the allowCredentials option. At the time of attestation you record enough information to know this credential is of the particular criteria you want, and only populate allowCredentials during assertion with the ID's of credentials which match your selected criteria.

This is true but requires you to first identify the user. The case I'm discussing is where the webauthn ceremony is initiated without any user context. In that scenario the user authenticates with the device, then chooses which pre-saved webauthn credential to send back to the server (Biometric then saved user info).

denniskniep commented 1 year ago

I would like to add another perspective from an enterprise RP. Explaining the challenge with non tech-savvy end users related to FIDO Authenticator registration and the corresponding OS/Browser UX.

Finding the correct Authenticator registration type (ie. Platform, Security Key via Usb, Roaming Authenticator via BLE initialised via QRCode/caBLE, etc.) is not easy for a non tech-savvy end user. There are many user complaints that it is too confusing.

Generally OS/Browser UX looks different for every OS & Browser combination. Furthermore the initial screen is not always deterministic. Actually the screen which is shown initially depends on several circumstances. Sometimes it starts on the page where you have to scan the QR-Code. But if the user wants to register a security key he has to navigate back and find the correct option. That is often a challenge for most non tech-savvy users (That's only an example, there are more similar issues)

Maybe it would be easier for the user to stay as long as possible on the website during FIDO Authenticator registration until the OS/Browser UX kicks in. Because then the website has the chance to guide and help the user to find the specific Authenticator registration type. The website could describe the various options specifically targeted for the applications user audience (tech-savvy, non tech-savvy, Only Security-Keys allowed etc.) The user will experience a more streamlined UX. And only the final registration step would be executed by the OS/Browser UX.

To be clear about the requirement. It is not about limiting the options for the end user. It's about better and consistent user guidance (no authenticator discrimination).

Currently webAuthN 2 gives the opportunity to control a bit of the Browser UX via authenticatorSelection.authenticatorAttachment (cross-plattform/plattform). That's it, AFAIK.

Could it be useful to add Transport hints (like usb, internal, nfc etc.) as a property to authenticatorSelection? However, I am afraid that this is not enough.

How could this challenge be solved? Any further Ideas?

Cheers, Dennis

agl commented 1 year ago

How could this challenge be solved? Any further Ideas?

This topic was raised at the 2023-04-21 face-to-face meeting. It was agreed that we would draft a change to add a "hints" parameter to requests, the first use-case of which would be allowing sites to express that they expect users to use a security key for a request. We recognise that we've hit the limits to trying to infer this from the current set of parameters and, while we try to cover the common cases, the case of enterprises using security keys (at least) is suffering.

emlun commented 1 year ago

The hints proposal is now embodied by PR #1884.

jameshartig commented 9 months ago

We would like to discourage the use of single-device authenticators because of their risk of being lost/destroyed/etc and encourage the use of iCloud, Google, 1Password, etc authenticators since they will sync across devices. We're finding the hints field to be confusing in this respect.

So we need to do UA sniffing to understand if its Windows or not and send a different hint if its Windows. Does that seem correct? Could there be a new hint added that would convey a preference for "synced" passkeys?

Firstyear commented 9 months ago

We would like to discourage the use of single-device authenticators because of their risk of being lost/destroyed/etc and encourage the use of iCloud, Google, 1Password, etc authenticators since they will sync across devices.

And we want the opposite, because all of those synced devices do not meet compliance standards for a number of high security environments, only security-keys do. But we have no way to filter pre-registration so user's can incorrectly enroll a key that we are about to reject during attestation.

So we need to do UA sniffing to understand if its Windows or not and send a different hint if its Windows. Does that seem correct?

There are similar needed UA sniffing tricks for android to get it to swap between "security-key" OR "google passkey stored in google password manager".

If you are worried about people losing devices encourage them to enroll multiple keys, and ensure you have workflows to facilitate multiple authenticator enrollments. Do not simply rely on "passkeys are synced" and then limit a user to one credential.

jameshartig commented 9 months ago

And we want the opposite, because all of those synced devices do not meet compliance standards for a number of high security environments, only security-keys do. But we have no way to filter pre-registration so user's can incorrectly enroll a key that we are about to reject during attestation.

The second part is exactly what we are trying to avoid as well.

If you are worried about people losing devices encourage them to enroll multiple keys, and ensure you have workflows to facilitate multiple authenticator enrollments. Do not simply rely on "passkeys are synced" and then limit a user to one credential.

We have support for multiple and do encourage them to add multiple but we also understand that many users will not set up multiple.

timcappalli commented 9 months ago

@jameshartig the hints feature is designed to help drive experiences (e.g. pop ups and external device dependencies). Just because an authenticator is cross-device, does not mean it creates a specific credential type (e.g. synced vs device-bound passkeys).

In many cases, a user chooses their authenticator and even its behavior. The type of passkey is returned in the response. You can (and should) parse that response and take appropriate action (ex: require the user have an additional recovery factor in the event their account only has a device-bound passkey).

So we need to do UA sniffing to understand if its Windows or not and send a different hint if its Windows. Does that seem correct? Could there be a new hint added that would convey a preference for "synced" passkeys?

No, there is no passive way to determine which type of credential an authenticator is going to create.

Let's continue this discussion either in a new issue, the passkey developer community, or FIDO-DEV, as it is not related to hints or attestation.