webauthn-multiple-non-resident-keys-challenges-solutionsWebAuthn Know-How

How To Handle WebAuthn Non-Resident Keys & Conditional UI

Explore challenges and solutions for handling non-resident keys in WebAuthn / passkey systems and Conditional UI (passkey autofill).

Blog-Post-Author

Vincent

Created: November 20, 2023

Updated: May 8, 2024


Introduction

Passkeys (and the underlying WebAuthn standard) offer revolutionary security and convenience. They mark a significant shift from traditional passwords to a more secure and user-friendly framework. However, the journey doesn't stop just at the decision to use passkeys for authentication (passkeys are resident keys / discoverable credentials by definition of the FIDO alliance).

Developers who have an existing authentication solutions in place often may encounter a scenario where they face that WebAuthn non-resident keys (non- discoverable credentials) are already in play. When a user now has one or more non-resident keys for a relying party (e.g. multiple hardware security keys, like YubiKeys which mostly generate non-resident keys), this can cause a problem because of the structure and functionality of non-resident keys if the WebAuthn server is not properly configured. This often could results in poor user experience and relying parties need to consider in advance how they want to set up the WebAuthn server to deal with resident-keys and non-resident keys in the right way.

What are Non-Resident Keys / Non-Discoverable Credentials?

Non-resident keys are a type of cryptographic keys used in WebAuthn that are not stored directly on the authenticator device. Instead, when a user signs up, the authenticator generates a new key pair derived from its internal master key. It then sends the public key and a credential ID, which includes a seed, to the server (Relying Party). The server links this public key with the user's account. For future logins, the authenticator recreates the private key by using the credential ID to extract the seed and combining it with the master key. This process ensures that the key exists only temporarily in the authenticator's protected memory, leading to its alternate name, "ephemeral key" in cryptographic terms (see here for a more detailed explanation).

Note that WebAuthn credentials created on Windows 10 devices are resident-keys but cannot be discovered due to browser constraints (as of November 2023).

Why Can the Wrong WebAuthn Server Setup Be a Problem for Non-Resident Keys?

Imagine a user who utilizes non-resident keys to authenticate via the WebAuthn protocol at a relying party, e.g. with a hardware security keys like a YubiKey. In the case of non-resident keys, each time the user logs in, the credential that should be used (and implicitly the credential ID) needs to be provided by the WebAuthn server.

Now, there are theoretically two scenarios how the allowCredentials can be handled in the WebAuthn server:

  • A) The WebAuthn server makes use of the allowCredentials parameter and provides a list credential IDs that exist for the supplied username.
  • B) The WebAuthn server does not make use of the allowCredentials parameter and keeps the array empty.

Option A handles multiple non-resident keys in a user-friendly way where users just need to plug in their non-resident key and, depending on further WebAuthn settings, provide proof for user presence and user verification.

Option B could cause more problems. Developers could leave the allowCredentials option empty (or not provide all credentials), e.g. for making use of Conditional UI (passkey autofill) or customizing the device management associated with allowed credentials.

Lets take a closer look at option B and see why this is a problem for non- resident keys. Initially,the credential ID was created when signing up with the non-resident key or adding the non-resident key to the relying party later on. Non-resident keys do not store the credential ID on the authenticator, so the relying party server manages them (this means the user's device doesn't retain a list of accounts or services associated with the authenticator). As the credential ID is a complex, unique sequence of characters, that can barely be remembered by a human, relying parties rather ask the user for their user handle (e.g. email address, phone number, username) during the login. The relying party servers then connect this user handle to the credential ID they obtained during account sign-up or addition of the non-resident key to the account. If the user wants to authenticate with the non-resident key but the relying party doesn't send the credential ID back that matches the non- resident key, a login is not possible.

Why Can Resident-Keys Deal with Empty AllowCredentials?

Unlike non-resident keys, resident keys' user handles and private keys are stored in the user's authenticator and are discoverable by the client device upon request. In resident-key scenarios, the user simply presents their authenticator, and the relying party can pull up the necessary credentials from the device itself (no credential ID and thus no user handle needs to set by the WebAuthn server in the allowCredentials parameter). Non-resident keys lack this feature, as during each login attempt the allowed credential IDs must be supplied.

Recommendations for WebAuthn Servers to Support Conditional UI & Non- Resident Keys

For developers tasked with implementing applications that should be able to handle ConditionalUI (passkey autofill / usernameless login) while also supporting non-resident keys, we recommend to distinguish Conditional UI logins & non-resident key logins as follow:

You should detect, either through separate API endpoints or in a different way, if a WebAuthn login start attempt was triggered via Conditional UI or via a regular WebAuthn login attempt. In the former case, you can leave the allowCredential parameter empty making it possible for the authenticator to decide which resident key (discoverable credential) to be used.

In the latter case, the user for the supplied username might have at least one non-resident key. Then, you should definitely fill the allowCredentials parameter with all credentials that exist for this user, so that the authenticator gets all credential IDs and can select the right one to let the user log in.

Conclusion

The correct setup of the allowCredentials parameter in WebAuthn servers is important. Leaving the allowCredentials empty to allow for unrestricted Conditional UI only works for resident keys. However, in non-resident key scenarios, you have to provide the credential IDs of the non-resident keys, so that the private keys can be recreated and used for authentication. We recommend to provide proper credential and device intelligence to set the WebAuthn server allowCredentials parameter correctly and maintain the security and user experience that WebAuthn promises.

Share this article


LinkedInTwitterFacebook

Table of Contents

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free