Webauthn: First factor authenticator selection

Created on 12 Oct 2017  路  13Comments  路  Source: w3c/webauthn

Depending on the use cases of RP, some RP may only allow first factor authenticators. For this, there should be a certain parameter to set this option for create() function.
Do we have such parameters or options?
If there is no such thing, the RP allowing first factor authenticator only should reject the attestation generated by a second factor authenticator by getting authenticator characteristics from meta data.
As a result, RP declines registration after the user confirms authenticator registration to the RP.
This is bad user experience.
So, we need to add something to _MakePublicKeyCredentialOptions_ to provide better UX.

Discuss impl-cons

Most helpful comment

So, at #createCredential (aka navigator.credentials.create() aka [[Create]]) time, the RP will need to set both options.authenticatorSelection.requireResidentKey and options.authenticatorSelection.requireUserVerification to true in order to stipulate use of a first-factor (aka "passwordless") authenticator, yes?

this is because by definition a first-factor authenticator is one that is capable of user verification.

It will be helpful to address issue #422 and get the authenticator taxonomy formally defined.

All 13 comments

Resident key support in the authenticator is a requirement in first factor situations. You can use an AuthenticatorSelectionCriteria with requireResidentKey set to true.

This far from obvious though.

Indeed requireResidentKey seems to be the way to go here.

Actually, requireResidentKey is not for first factor authentication. It's about key storage. E.g., secret key such as Yubikey can store a credential private key even if it is a second factor authenticator.

There is no such requirement that the second factor authenticator must not store user private keys. So if the RP sets requireResidentKey to true, some second factor authenticators may not reject the request.
You can refer following U2F Spec.

A U2F device allows for this. The Key Handle issued by the U2F device does not have to be an index to the private key stored on board the U2F device secure element chip. Instead, the Key Handle can 'store' (i.e., contain) the private key for the origin and the hash of the origin encrypted with a 'wrapping' key known only to the U2F device secure element. When the Key Handle goes back to the secure element it 'unwraps' it to 'retrieve' the private key and the origin that it was generated for.

Thus, the RP can only confirm the fact that the platform selects the 2nd factor authenticator when it sets _requireResidentKey_ to false. But, it cannot make sure that the selected authenticator is a first factor authenticator in case _requireResidentKey_ is true.

We need to clarify the way to allow only first factor authenticator registration for some RPs.

The U2F behaviour is overridden by the Webauthn spec, see 搂4.1.3. Create a new credential, step 21:

If options.authenticatorSelection is present, iterate through _currentlyAvailableAuthenticators_ and do the following for each authenticator:

  1. If aa is present and its value is not equal to _authenticator_鈥檚 attachment modality, _continue_.
  2. If rk is set to true and the _authenticator_ is not capable of storing a Client-Side-Resident Credential Private Key, _continue_.
  3. If uv is set to true and the _authenticator_ is not capable of performing user verification, _continue_.
  4. Append _authenticator_ to _selectedAuthenticators_.

Thus requesting credential creation with requireResidentKey: true will make authenticator create a resident key, and the authenticator will also be able to use that key in response to an assertion request with no allowCredentials - i.e. the resulting key would be usable as a first factor credential. See 搂4.1.4. Use an existing credential to make an assertion, step 16:

Note: In this case, the Relying Party did not supply a list of acceptable credential descriptors. Thus the authenticator is being asked to exercise any credential it may possess that is bound to the Relying Party, as identified by _rpId_.

Of course the credential will _also_ be usable as a second factor if the RP so wishes, but as I understand your need it's enough that the RP can be guaranteed that the credential will be usable as a first factor credential. Correct?

Yeah, technically you are right.
I don't know current U2F deployment and authenticators in market.
Is there any U2F device that stores user private key on it?
If there are such devices in market, are theses devices can be used as first factor authenticator even if the authenticator implemented U2F only?
Actually, I was wondering that the U2F devices can be first-factor authenticators.
It would be better to add some descriptions for readers to understand these operations easily.

Is there any U2F device that stores user private key on it?

From having looked at the size and structure of the key handles created by a number of U2F devices, I'm not aware of any that appear to store generated keys internally. I understand that early versions of the U2F Zero may have, but that the behaviour was changed for current versions.

Yes, some better descriptions of this would probably be good.

@agl Thanks for the information.
@emlun currently, there is no way for RPs to set requireResidentKey for get() operation. #583 issue is related to this one. To provide selection for authentication, the authenticationSelection member should be added to PublicKeyCredentialRequestOptions dictionary.

requireResidentKey is not needed for get(), because if allowCredentialsis not set then only resident credentials can be used for the response.

@Kieun U2F authenticators can never be first factor as they do not allow storage of a User ID. What is more, whether or not the actual key is a resident key is not relevant in a U2F context: the key handle supplied by the RP is the only link between the user account and the signature. Even if an authenticator would support returning an assertion based on AppID (U2F speak for the RPID), the returned signature does not contain any indication of which credential was used to generate it. The only way to identify the account for such a signature would be to validate it against all public keys stored by the RP...

I believe U2F authenticators should never be selected when requireResidentKey is set.

So, at #createCredential (aka navigator.credentials.create() aka [[Create]]) time, the RP will need to set both options.authenticatorSelection.requireResidentKey and options.authenticatorSelection.requireUserVerification to true in order to stipulate use of a first-factor (aka "passwordless") authenticator, yes?

this is because by definition a first-factor authenticator is one that is capable of user verification.

It will be helpful to address issue #422 and get the authenticator taxonomy formally defined.

Reading from this thread, I believe the use case has already been addressed by existing parameters. The only remaining issue is clarification of authenticator taxonomy, which is tracked by a separate issue and on PR. Therefore, I am closing the issue.

If we ended up believing the use case needs a new parameter, please move back to WD-07. @Kieun @jovasco @emlun

@equalsJeffH @nadalin for tracking.

Was this page helpful?
0 / 5 - 0 ratings