WebAuthn Conditional UI: Technical Explanation and Implementation
With the rapid adoption of passkeys (and the underlying WebAuthn protocol), authentication has become more secure and user-friendly for many users. One of the standout advancements of passkeys has been the integration of Conditional UI, often referred to as "passkey autofill" or Conditional Mediation (in the following, we stay with the term Conditional UI).
Despite its recent introduction and ongoing adoption by browsers, there’s a noticeable gap in technical documentation and implementation advice for Conditional UI. This article aims to bridge that gap by explaining what Conditional UI is, how it works, and how to tackle common challenges during its implementation.
What Is Conditional UI?
Conditional UI represents a new mode for passkeys/WebAuthn login processes. It selectively displays passkeys in a user interface (UI) only when a user has a discoverable credential (resident key), which is a type of passkey registered with the relying party (the online service) stored in their authenticator of a device (e.g., laptop, smartphone). The passkeys are displayed in a selection dropdown that is mixed up with auto-filled passwords, providing a seamless transition between traditional password systems and advanced passkey authentication, as users see both in the same context. This intelligent approach ensures that users aren't overwhelmed with unnecessary options and can navigate the login process more seamlessly.
The foundation of Conditional UI is built on three main pillars:
- Respect user privacy: Ensuring user privacy by preventing disclosure of available credentials or lack of user consent to reveal these credentials.
- Great user experience even if no passkey exists: Empowering relying parties to implement WebAuthn opportunistically, ensuring user experience remains good even if passkeys are not available.
- Smooth transition from passwords to passkeys: Combining passkeys with password-based authentication to smooth the transition towards passwordless authentication methods, capitalizing on users' familiar UX paradigms.
Conditional UI Benefits and Drawbacks
Benefits
- Streamlined authentication: The process is more streamlined and efficient, removing the complexities often associated with multiple authentication methods.
- Reduction in user errors: By presenting only relevant options, users are less likely to make mistakes during the authentication process.
- Enhanced user satisfaction: Removing unnecessary steps means users can log in faster and more effortlessly, leading to improved user satisfaction.
- Simple frontend integration: One of the standout features of Conditional UI is its ease of integration. Developers can seamlessly incorporate it into the front end with a few lines of code (see below).
- Passwordless and usernameless login: One of the huge benefits is that Conditional UI promotes not only passwordless authentication but also a usernameless or accountless experience. Users are spared the mental load of recalling their specific email address or user handle from sign-up. Instead, they can rely on the browser’s suggestions, which include the email address/user handle paired with the appropriate passkey in the autofill menu.
- Solving the bootstrapping dilemma: Transitioning from traditional username-password systems to passkeys can be daunting. Conditional UI addresses this transition challenge. Websites can initiate a passkey / WebAuthn call alongside a conventional password prompt without fretting over potential modal dialog errors if a device lacks the needed credentials.
Drawbacks
- Learning curve for developers: Conditional UI introduces a new paradigm, which means there's a learning curve involved for developers unfamiliar with its intricacies.
- Device/browser dependency: Conditional UI’s success hinges on the user's device or browser compatibility. Given that not all browsers or devices support it currently, this can limit its application. To test the passkey-readiness of a website, one can make use of tools like the passkeys analyzer.
- No conditional passkey register: There’s no support for using Conditional UI in the account/passkey creation process. That means you need to create passkeys the regular way, either at the account creation stage by providing some dedicated passkey creation page or in the account settings. However, there's an ongoing discourse about the potential inclusion of Conditional UI for sign-ups as well.
- Password manager disable autocomplete: Some modern password managers and their browser extensions modify the website’s DOM and disable or overwrite the autocomplete tag in input fields in favor of their own autocomplete features. This can lead to an inconsistent and unsatisfying user experience. As standards for Conditional UI are relatively new, we hope that things improve so that, e.g., not two autofill menus are overlaid or the desired one is not shown at all.
How Does Conditional UI Work?
In the following, we provide a step-by-step breakdown of the single steps of an entire Conditional UI flow:
In general, the Conditional UI process flow can be partitioned into two phases. During the page load phase, conditional UI logic happens in the background, while in the user operation phase, the user has to do something actively.
- Conditional UI availability checks: The client (browser) calls the
isConditionalMediationAvailable()
function to detect if the current browser/device combination supports Conditional UI.
Only if the response is true does the process continue; otherwise, the Conditional UI process is aborted. - Call the conditional UI endpoint: Next, the client calls the server Conditional UI endpoint in order to retrieve the
PublicKeyCredentialRequestOptions
. - Receive
PublicKeyCredentialRequestOptions
: The server returns thePublicKeyCredentialRequestOptions
which contain the challenge and more WebAuthn server options (e.g.,allowCredentials
, extensions,userVerification
). - Start the local authentication: By calling
credentials.get()
with the receivedPublicKeyCredentialOptions
and the mediation property is set to be “conditional, the process for the local authentication on the device starts. - Show autofill selection: The autofill menu for passkeys pops up. The specific styling is dependent on the browser and device (e.g., some require the user to place the cursor in the input field, and some automatically display the menu on page load; see below).
- Local user authentication: The user selects the passkey from the autofill menu that they want to use and authenticate via the authentication dialog of their device (e.g., via Face ID, Touch ID, Windows Hello).
- Send authenticator response to server: If the local user authentication was successful, the authenticator response is sent back to the server.
- User is logged in and redirected: Once the server receives the authenticator response, it validates the signature against the corresponding user account’s public key in the database. If the verification is successful, the user is granted access, logged in, and redirected to the logged-in page.
By following this process flow, Conditional UI offers a seamless and user-friendly authentication experience.
Technical Requirements for Conditional UI
General
To get Conditional UI working, some general aspects need to be considered:
- Credential specifications: Conditional UI is specifically designed to operate only with resident keys/discoverable credentials. The reason behind this is that authenticators do not store user-specific data (e.g., name, display name) for non-resident keys/non-discoverable credentials. As a result, using the latter for passkey autofill is not possible.
- Credential filtering: The
allowCredentials
feature remains supported, facilitating websites that are already aware of the user's identity (for instance, if a username was sent in the initial mediation call because it might be stored in the browser’sLocalStorage
) to refine the list of credentials showcased to users during autofill.
Client-Side
To get Conditional UI working on the client side, the following requirements must be fulfilled:
- Compatible browser: Ensure that the user uses a modern browser that supports Conditional UI (see State of Passkeys for the latest browser coverage).
- Enabled JavaScript: JavaScript must be enabled to facilitate Conditional UI operations.
- Test conditional UI availability: The relying party (the server side) should have the certainty that Conditional UI is available on the client side when it receives the WebAuthn mediation call to avoid triggering any user-visible errors in scenarios where Conditional UI isn't supported. To address this, it’s recommended to use the
isConditionalMediationAvailable()
method and check for the technical availability of Conditional UI. - HTML input field required: For Conditional UI to work, you need to have an HTML input field on your web page. If you do not have one, you need to provide support for the regular passkey/WebAuthn login process that is triggered with a user interaction, like a button click.
- Remove timeout protocols: Timeout parameters (e.g., the user is taking a very long time to decide on a passkey in the autofill menu) should be disregarded in this setup.
Server-Side
To get Conditional UI working, some requirements on the server side must be fulfilled as well:
- Running WebAuthn server: As we are still in the context of passkeys / WebAuthn, it’s required to have a WebAuthn server running that manages the authentication procedures.
- Provide mediation start endpoint: Compared to regular WebAuthn login endpoints, it’s useful to provide another endpoint that has similar functionality but can deal with an optional user handle (e.g., email address, phone number, username).
Practical Coding Tips
Since the official rollout of Conditional UI in late 2022 and earlier beta versions, we’ve been testing and working extensively with it. In the following, we want to share practical tips that helped during the implementation of Conditional UI with you.
A useful tool to debug WebAuthn registration and authentication responses is the passkeys debugger.
Full Conditional UI Example
A full, minimalistic code example for a Conditional UI method would look like this: