I’m currently working on an authentication flow based in web authentication. I’ve a yubikey 5 device for testing it.
For the authentication ceremony, I’m using the following settings:
- allowCredentials: [] (an empty array, as I want to use discoverable credentials)
- userVerification: discouraged (in the interest of minimizing disruption to the user interaction flow)
What I see is that when using Chrome with those settings, the device PIN is always requested to the user. This behavior is different in Firefox. In that case the PIN is not being requested to the user.
This can be easily reproduced in this demo site: https://webauthn.io/
Does anybody have an idea about why the behavior is different between both browsers? Could this be a bug in Chrome?
Thank you in advance.
Note: tested with versions:
- Chrome 123.0.6312.86 (Official Build) (64-bit)
- Firefox 124.0 (64-bit)
2
Answers
When passkeys are created on a security key in Chrome with
UV
=required
orpreferred
, they are created with credProtect level 3, meaning that user verification is required when the credential is used.In this case, I’m assuming that you created the passkey with
UV
=discouraged
?Since you are not using an allowlist and the security key has UV configured, Chrome is likely forcing user verification as passkeys are meant to be a primary sign in credentials (e.g. they’re usernameless and multifactor). You don’t want a user picking up a security key off the ground and gaining full access to someone’s accounts.
Since you’re using this in more of a second factor / step up style flow, can you test with an allowlist and see if you’re still asked for UV?
There are subtle differences in how Chrome has implemented Webauthn vs how Firefox has done it. If I generate a request through Firefox Webauthn will trigger the following CTAP request
This request as seen contains what you’d expect, the request itself has
rk = true
which would make a discoverable credential on the device. The request has a token, but that only affects our creation and not the assertion afterwards.If I make the same request in Chrome however I get the following request
Almost the same request, rk is also true here among other but there is one critical difference. Chrome has added a value to key 6 which is
credProtect: 2
. CredProtect Level 2 is defined in CTAP asuserVerificationOptionalWithCredentialIDList
which means the key would only be discoverable through either some sort of User Verification (in your case, the pin), or by including it in the allowList. More info on CredProtectI strongly doubt this is a bug in Chrome, but actually something Chrome has decided they want have as part of their implementation. Webauthn in itself does very little to cover anything regarding CredProtect so this decision doesn’t affect their conformance with the specification either.
If this is the correct way to do it by Chrome becomes very opinion-based and it is not necessarily the right way as supplying
allowList
to requests comes with a lot of privacy concerns, many of whom are covered in webAuthn, especially chapter 14.6.3.So, unless Chrome changes, which I doubt, your only options here is to either maintain and supply the
allowList
or do theUserVerification
ceremony. The key generated through Firefox would however be possible to get without either as the default value for CredProtect in CTAP is 1. And it would be possible to get it on either Chrome or Firefox.