Passkey User Verification
To authenticate with a passkey, the user must have access to the passkey. Back in the day, dedicated hardware authenticators were typically used, which required the user to be in physical possession of the device.
Today we usually use smartphones, tablets or computers. The user must still have physical access to the device, but passkeys are typically synced between devices associated with the same cloud account e.g. iCloud.
Device manufacturers will typically only allow a new device to download a cloud synced passkey if approved using an existing device, thereby maintaining the requirement that the user has physical access to the passkey.
If we assume anyone using a passkey has physical access to the device, it meets the something I have requirement and is a good step towards enhanced security, certainly better than passwords. But, how can we be sure it’s our user in possession of the device?
An attacker with access could present the passkey from an unlocked device.
The WebAuthn spec introduces a concept known as user verification, which essentially asks the device to re-authenticate the user locally before presenting the passkey.
User verification options
Section titled “User verification options”Choose from one of these options:
- Preferred
This is the default during registration and authentication. The device will attempt to re-authenticate the user if technically possible, and frictionless. However if this can’t be achieved, for example a MacBook is in clamshell mode, the device will continue to present the passkey anyway.
- Required
The device will attempt to use something like FaceID/TouchID but if it can’t, it will fall back to prompting the user for their device password. Either way, the device won’t present the passkey unless the user has re-authenticated.
- Discouraged
The device won’t re-authenticate the user, so this option results in the least friction.
Checking the verification status
Section titled “Checking the verification status”When preferred is used, it’s useful to know whether the user did actually re-authenticate locally. The resulting Principal includes a passkey.userVerified: boolean property to reflect the status.
Preferred, required or discouraged? Which option to choose?
Section titled “Preferred, required or discouraged? Which option to choose?”In most cases we believe the default, preferred is best. You can always perform some additional verification e.g. sending a one time code if the user didnt re-authenticate locally.
However if the user has successfully authenticated you might choose to set a secure session cookie on their machine, in which case discouraged could strike a good balance between friction and security.
required is obviously the most secure and best used for security related operations, e.g. account or billing changes.