Passkeys best practice for the web
Learn how to create the best passkey experience for your users on the web.
Device-initiated authentication
Traditional passwordless sign-in methods such as email OTP are username-initiated. You enter your email address and the site looks up the associated account and then initiates a challenge to verify it belongs to you.
Username-initiated sign-in via email OTP
But passkeys represent a new paradigm of device-initiated authentication. We can display passkeys available on a given device without requiring the user to enter their username.
Device-initiated sign-in via passkey autofill
Passkey credentials are either bound to a single device or synced between multiple devices by a password manager (Apple Passwords, Google Password Manager etc). The site can present whatever credentials are available on the device and we can look up the account based on the credential selected.
Availability across devices
Passkeys may not be available on a given device for multiple reasons.
- If the user has created a passkey on one device then switched to a new device where that passkey can’t be synced.
- If the user has created a passkey and then deleted it from their password manager.
For this reason your UI should always clearly present a backup authentication option and avoid leading users into dead ends when a passkey isn’t available.
Passkeys for sign-in
Autofill
Enabling passkey autofill is an unobtrusive way to support passkeys on your sign-in page while also maintaining a familiar experience for users who haven’t setup passkeys yet.
Adding autofill to your sign-in page
Here the user will only be shown a passkey if they have already created one and it’s available on the device. Otherwise the user can manually enter their username and press “Continue” to trigger another kind of challenge (e.g. email OTP).
Sign-in button
Another approach is to include a separate passkey sign-in button which is clearly presented as an alternative sign-in option.
Presenting a passkey sign-in button as an alternative authentication option
Clicking this button will launch the browser passkey prompt regardless of whether or not there are any passkeys available on the device. If a passkey is available, then the user will be able to authenticate with it.
Clicking the 'Sign in with passkey' button when the device has a passkey available
If no passkey is available, however, then the browser has to fall back to displaying a QR code or waiting for the user to insert a hardware security key.
Clicking the 'Sign in with passkey' button when the device can't find any available passkey
This QR code prompt can be useful if the user knows what to do; for example, if they’ve previously created a passkey on their iPhone and are now on their Windows laptop, then they can scan the QR code with their iPhone in order to sign in.
However, the QR code prompt can be a jarring or confusing experience to users who aren’t familiar with the nuances of how passkeys are synced across different platforms. For this reason we strongly recommend restricting the QR code flow to a passkey sign-in button or a similar UI interaction where the user has explicitly chosen to use passkeys.
Passkeys for MFA
When using passkeys as a secondary factor, it’s important to only show passkeys for one account. If a device is shared between family members, or if a person has multiple accounts for the same site, then a device may have passkeys available for different accounts.
Multiple passkeys available for different accounts on the same device
The allowCredentials parameter is the solution here; it lets us tell the browser to restrict passkeys to a known list of credentials for a given user.
But even if you know all passkeys a user has previously created, you still can’t guarantee any will be available on the device the user is currently authenticating on.
If you pass the browser a list of allowed credentials but it doesn’t find any on that device, then it will fall back to presenting a QR code.
So even when using allowCredentials
it’s important to clearly present a backup authentication option and avoid leading users into dead ends when their device doesn’t have any passkeys available.
Because it is always launched for a specific user, the Authsignal pre-built
UI always restricts passkeys via the allowCredentials
parameter. It also provides a clear way to fall back to alternate authentication methods.
Creating passkeys
Increasing adoption
Transitioning your users from traditional sign in methods, like passwords, to passkeys can be a big change. To help with this transition, you can provide a prompt to encourage users to create a passkey when they sign in.
A user is prompted to add a passkey after signing in.
As this may be the first time your users have encountered passkeys, it’s important to provide a summary of what passkeys are and their benefits.
Improving coverage across devices
Whilst many passkeys are available across devices, like ones stored in iCloud Keychain, some passkeys are device-bound. For example, a passkey created on a desktop browser may not be available on a mobile device.
If a user authenticates on a device without a passkey, you can prompt them to create one in a similar way to the example above.
An example of a prompt to add a passkey to a device.
Depending on your needs, you can alter the frequency of these prompts to ensure they’re not too intrusive. This could be a timed cooldown or based on the user’s behaviour.
Displaying passkeys
As users may have multiple passkeys, it’s useful to display them in a distinct way. A passkey user authenticator contains
the webauthnCredential.aaguidMapping
object. The name
field will contain the name of the credential manager, e.g. iCloud Keychain, where the
passkey is stored. The svgDark
/svgLight
fields contain the SVG icons for the credential manager.
In the area of your application where user’s manage their authentication options, you can utilize these fields to display the user’s passkeys:
Displaying a list of the user's passkeys.
Whilst the webauthnCredential.aaguidMapping
object is available for most passkeys, it’s not
guaranteed to be present. As an alternative, you can use the webauthnCredential.parsedUserAgent
object to display details about the device the passkey was created on.
Next steps
Was this page helpful?