Passkey Best Practices for Service Providers

Intended audience

This documentation is intended for developers that are implementing passkey support for service providers - web sites and services (relying parties) - using a bring-your-own authenticator model. Service providers likely won’t have any control over what authenticator a user prefers, and if the user’s preferred authenticator isn’t available for use, they may choose not to use passkeys at all. It’s even possible they’ll start using a competitor’s product that does allow them to use the authenticator of their choice - for convenience, security, or even privacy reasons - so it is paramount to make sure the passkey component is done right and empowers users to make choices.

Just as any MFA is more secure than no MFA, any phishing-resistant MFA is more secure than non-phishing resistant MFA. It follows that anything which prevents a user from using their authenticator of choice to store their passkey is likely to make a site or service less secure - as long as people can opt-out of passkeys entirely.

Developers that are building a solution for employees, contractors, or perhaps VIP clients that need to protect their accounts in a specific way for risk management or compliance reasons should be more selective about passkey authenticator use. This guidance is not intended to replace guidance for situations where the developer’s organization can choose the authenticator. To find out more about how to support passkeys for employees, contractors, and VIP clients, visit Yubico’s glossary page for passkeys.

The goal of this documentation is to guide developers down the path of making the best decisions for their end users, ensuring that they don’t unnecessarily restrict the type of authenticator or how it’s used. The WebAuthn standard, upon which passkeys are based, is very permissive by default and will allow a wide range of authenticators. In short - this document is to ensure that developers don’t do extra work only to aggravate end users.

Plan for user experience challenges

It’s important to acknowledge that the user experience for passkeys can be very inconsistent between browsers and platforms. Different messages and user interfaces can cause confusion and may tempt developers to restrict choices to tailor the experience for users. Unfortunately, with the rapid development of passkeys and seemingly constant change to the user interface offered by platforms and browsers, providing tailored experiences can be very demanding for developers and are likely to be undercut by future changes to platforms and browsers.

To help address this, Yubico’s Passkey Workshop is continually updated to include sample strategies for providing additional guidance to end users and will continue to be updated as new developments in the passkey ecosystem unfold.

Consider how users will recover from the loss of an authenticator

Because passkeys are very secure, the normal methods for creating a “backup” don’t apply. Unlike passwords or TOTP seeds, you can’t simply keep a copy of the information in a safe place. Some authenticators provide passkey recoverability by syncing them between devices or accessing them via a cloud service, but these synced passkeys are in turn vulnerable to loss of access to the cloud service that houses them. As of November 2023, no passkey providers support importing and exporting passkeys as a form of backup, although some do support sharing passkeys with other users of the same passkey provider.

It’s essential for services to support the registration of multiple passkeys to ensure that users can recover their account themselves if they lose an authenticator or lose access to a passkey provider. In addition to simply allowing multiple passkeys on separate authenticators, indicating which passkeys are synced or backup eligible in the user interface will help users determine if they will be able to recover a passkey if they lose or damage a particular device. Moreover, always give end users an opportunity to label a passkey when it is created, and advise them that this label is to help them determine which authenticator or passkey provider holds the passkey (such as a description of the authenticator type, model or its appearance). Lastly, be sure to give users a way to delete individual entries, as this will enable users to remove passkeys for lost devices or even to revoke synced or shared passkeys if they so choose.

Implementing device attestation may also help users understand where their passkeys are stored, as long as the authenticator supports attestation (more on this below).

While synced passkeys will ensure self-service account recovery for most users in most situations, they are not a silver bullet, and you must plan for how you will handle account recovery for users that are unable to access their authenticators where their passkeys reside.

Decide when to use discoverable credentials

Discoverable Credentials (previously known as resident credentials) allow a web browser or platform to enumerate the credentials available in an authenticator for a specific web site or domain and display them to the end user in order to make logging in easier. They are especially convenient for logon flows where the user doesn’t even need to enter their username, as it can be determined from the discoverable credential itself.

While the official FIDO2 definition of a passkey is a “discoverable FIDO2 credential”, in practice, discoverability hasn’t been a strict requirement in most passkey implementations. For instance, both Google and Apple support saving a non-discoverable FIDO2 credential in their respective passkey ecosystems.

Discoverable credentials have two main drawbacks. The first is privacy related, and the second is related to hardware FIDO2 authenticators with limited discoverable credential storage. These drawbacks may make discoverable credentials undesirable for certain services.

Additionally, discoverable credentials, as the name implies, can be enumerated by the web browser or operating system if an attacker can unlock the associated authenticator. Conversely, non-discoverable credentials don’t leave any record behind if they’re stored on a FIDO2 security key, even if the authenticator can be unlocked. While this may not be a consideration for most users, for some users with increased privacy requirements, this may mean the difference between being able to use a web service safely or not.

Another important aspect to note is that hardware authenticators have limited discoverable credential storage. For example, if a user is attempting to use a YubiKey 5, they will have only a maximum of 25 credentials that can be made discoverable. While it’s unlikely for the average user to hit this limit, it is still possible that users may have filled up all of the discoverable credential slots on their authenticator.

Users may have a privacy or technical need for a non-discoverable credential, therefore it is important to always provide a way for the user to initiate a login via username, and perform registrations with discoverable credentials set to preferred. This will allow a graceful fallback for authenticators that have already exhausted their discoverable credential storage.

Services that handle potentially sensitive information should optionally provide a method for specifically requesting a non-discoverable credential, to accommodate users with elevated privacy needs.

For an example of how to handle both discoverable and non-discoverable credentials, see the Yubico Passkey Workshop.

Decide when to request attestation

Attestation is the only way to achieve high confidence that a given credential is device-bound, and the only way to reliably determine the type of passkey being used. Services that want to be able to provide better information to users about the passkeys that are being used, or need to be able to use information about the passkey to make risk-based decisions about passkey use, should request attestation information during registration. Only device-bound passkeys can provide meaningful attestation, and users always have the option of declining to supply the attestation information. Detailed guidance on implementing attestation is provided in more detail in the Yubico Passkey Workshop’s section on attestation.

Consider approaches for detecting passkey support in the browser or platform

Websites may want to attempt to detect whether or not a browser or platform can use passkeys before showing specific user interface elements, or altering the logon flow for users depending on the level of passkey support. While support for passkeys in general can be inferred from support for WebAuthn, there are no simple, reliable ways to determine whether browsers or platforms can support a specific type of authenticator, or support specific capabilities, like user verification or discoverable credentials.

The following code snippet can be used to detect WebAuthn support in the browser, but it does not indicate that user verification, discoverable credentials, or any specific type of authenticator is available.

navigator.credentials &&
navigator.credentials.create &&
navigator.credentials.get &&
window.PublicKeyCredential

The isUserVerifyingPlatformAuthenticatorAvailable() static method of the PublicKeyCredential interface is unfortunately only occasionally helpful in determining if a browser has access to a platform authenticator, and it behaves differently on Windows and MacOS.

User agent fingerprinting may also be used to determine what sort of browser-based support is available, but it may not reliably indicate platform support. User agents can also be set by the browser, limiting the usefulness of user agent strings for determining passkey support.

The best practice for determining whether a platform supports passkeys is to first check whether it supports WebAuthn credentials via the code snippet above, and if it does, give the user an option to register a credential.

Once you know for sure (through use) that a specific device supports passkeys, consider setting a cookie so that you don’t need to do any detection on the next visit.

Be cautious about requiring optional WebAuthn features

Sometimes, the behavior that an authenticator will exhibit changes based on how it’s configured or due to a configuration change on a browser or platform. Maybe an authenticator has run out of storage, or a user hasn’t configured a PIN. It’s important to understand that the arguments passed to the WebAuthn API’s don’t always mean a credential will be created or asserted with those settings - they mean a platform will try to perform an action on an authenticator with those settings.

The only way to determine how a credential has been created or used is to evaluate the data that is returned as part of the WebAuthn call, compare that with your requirements, and inform the end user of the implications of the way their authenticator has processed the WebAuthn request. For examples, see Consider how users will recover from the loss of an authenticator and Decide when to use discoverable credentials