---
url: 'https://www.corbado.com/blog/webauthn-conditional-ui-passkeys-autofill'
title: 'WebAuthn Conditional UI (Passkeys Autofill) Technical Explanation'
description: 'Conditional UI / Conditional Mediation / Passkey Autofill is a new feature of passkeys. This article explains what it is, how it works & how to implement it'
lang: 'en'
author: 'Vincent Delitz'
date: '2023-10-20T00:00:00.000Z'
lastModified: '2026-09-08T06:01:18.701Z'
keywords: 'passkeys autofill, passkey autofill, conditional mediation'
category: 'WebAuthn Know-How'
---

# WebAuthn Conditional UI (Passkeys Autofill) Technical Explanation

## Key Facts

- **Discoverable credentials (resident keys)** are required for Conditional UI:
  authenticators don't store user-specific data for non-resident keys, making autofill
  impossible with them.
- **`isConditionalMediationAvailable()`** must be called before starting any Conditional
  UI flow to prevent user-visible errors on unsupported browsers or devices.
- The **`autocomplete="username webauthn"`** token on an HTML input field signals the
  browser to surface passkeys alongside password suggestions in the autofill dropdown.
- Setting **`mediation: "conditional"`** in the `navigator.credentials.get()` call
  activates passkey autofill without interrupting users with a blocking modal dialog.
- An **`AbortController`** is required to cancel ongoing Conditional UI requests because
  autofill dropdowns, unlike modal prompts, have no built-in cancellation button.

## 1. Introduction

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](https://www.corbado.com/glossary/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](https://www.corbado.com/glossary/conditional-ui). This article aims to bridge that gap by
explaining what [Conditional UI](https://www.corbado.com/glossary/conditional-ui) is, how it works and how to
tackle common challenges during its implementation.

## 2. 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](https://www.corbado.com/blog/webauthn-resident-key-discoverable-credentials-passkeys)
(resident key), which is a type of passkey, registered with the
[relying party](https://www.corbado.com/glossary/relying-party) (the online service) stored in their
[authenticator](https://www.corbado.com/glossary/authenticator) of a device (e.g. laptop, smartphone). The
passkeys are displayed in a selection dropdown that is mixed up with autofilled 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:

1. **Respect User Privacy:** Ensuring
   [user privacy](https://www.corbado.com/faq/ensure-gdpr-compliance-with-passkeys) by preventing disclosure of
   available credentials or lack of user consent to reveal these credentials.
2. **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.
3. **Smooth Transition From Passwords To Passkeys:** Combining passkeys with
   password-based authentication to smooth the transition towards
   [passwordless authentication](https://www.corbado.com/glossary/passwordless-authentication) methods,
   capitalizing on users' familiar UX paradigms.

![WebAuthn passkey login conditional ui](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/Web_Authn_passkey_login_conditional_ui_8c8e7b0de5.png)

## 3. Conditional UI Benefits and Drawbacks

### 3.1 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 frontend 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](https://www.corbado.com/glossary/passwordless-authentication)
  but also a usernameless or accountless experience. Users are spared the mental load of
  recalling their specific email address or
  [user handle](https://www.corbado.com/blog/webauthn-user-id-userhandle) from sign-up. Instead, they can rely on
  the browsers suggestions, which include the email
  address/[user handle](https://www.corbado.com/blog/webauthn-user-id-userhandle) 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.

### 3.2 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 UIs 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.
- **Password Manager Disable Autocomplete:** Some modern password managers and their
  browser extensions modify the websites 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.

## 4. 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:

![WebAuthn Conditional UI Process Flow](https://www.corbado.com/website-assets/653274ad0332e7d69c77e199_webauthn_conditional_ui_process_flow_chart_6a1709e56d.png)

In general, the Conditional UI process flow can be partitioned in two phases. During the
page load phase, Conditional UI logic happens in the background, while in the user
operation phase, the user has to actively do something.

1. **Conditional UI Availability Check:** The client (browser) calls the
   `isConditionalMediationAvailable()` function to detect if the current browser / device
   combination supports Conditional UI. Only if the response is true, the process
   continues, otherwise the Conditional UI process is aborted.
2. **Call the Conditional UI Endpoint:** Next, the client calls the servers Conditional UI
   endpoint in order to retrieve the
   [PublicKeyCredentialRequestOptions](https://www.corbado.com/glossary/publickeycredentialrequestoptions).
3. **Receive PublicKeyCredentialRequestOptions:** The server returns the
   [PublicKeyCredentialRequestOptions](https://www.corbado.com/glossary/publickeycredentialrequestoptions) which
   contain the challenge and more
   [WebAuthn server options](https://www.corbado.com/blog/webauthn-server-options-overview) (e.g.
   [allowCredentials](https://www.corbado.com/glossary/allowcredentials), extensions,
   [userVerification](https://www.corbado.com/glossary/user-verification)).
4. **Start the Local Authentication:** By calling `credentials.get()` with the received
   [PublicKeyCredentialRequestOptions](https://www.corbado.com/glossary/publickeycredentialrequestoptions) and
   the `mediation` property set to be conditional, the process for the local
   authentication on the device starts.
5. **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, some automatically display the menu on page load, see
   below).
6. **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](https://www.corbado.com/faq/is-face-id-passkey), Touch ID,
   [Windows Hello](https://www.corbado.com/glossary/windows-hello)).
7. **Send Authenticator Response to Server:** If the local user authentication was
   successful, the [authenticator](https://www.corbado.com/glossary/authenticator) response is sent back to the
   server.
8. **User is Logged in and Redirected:** Once the server receives the
   [authenticator](https://www.corbado.com/glossary/authenticator) response, it validates the signature against
   the corresponding user accounts public key in the database. If the verification
   success, 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](https://www.corbado.com/faq/passkey-user-experience-benefits-non-technical-audience)
experience.

## 5. Technical Requirements for Conditional UI

### 5.1 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 is that
  [authenticators](https://www.corbado.com/glossary/authenticator) 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 ](https://www.w3.org/TR/webauthn-2/#dom-publickeycredentialrequestoptions-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 browsers LocalStorage) to refine the list of credentials
  showcased to users during autofill.

### 5.2 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
  [here ](https://caniuse.com/mdn-api_publickeycredential_isconditionalmediationavailable_static)for
  the latest browser coverage).
- **Enabled JavaScript:** JavaScript must be enabled to facilitate Conditional UI
  operations.
- **Test Conditional UI Availability:** The [relying party](https://www.corbado.com/glossary/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 avoid triggering any
  user-visible errors in scenarios where Conditional UI isn't supported. To address this,
  its recommend to use the `isConditionalMediationAvailable()` method and check for the
  technical availability of Conditional UI ( see [below ](#browser-compatibility-check)for
  more details).
- **HTML Input Field Required:** For Conditional UI to work, you need to have an HTML
  input field in 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 for a passkey in the autofill menu) should be disregarded in this setup.

### 5.3 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, its
  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](https://www.corbado.com/blog/webauthn-user-id-userhandle) (e.g. email address, phone
  number, username).

## 6. 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 with you
practical tips that helped during the implementation of Conditional UI.

### 6.1 Full Conditional UI Example

A full, minimalistic code example for a Conditional UI method would look like this:

```html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Conditional UI</title>
    </head>
    <body>
        <input type="text" id="username" autocomplete="username webauthn" />

        <script>
            async function passkeyLogin() {
                try {
                    // retrieve the request options (incl. the challenge) from the WebAuthn server
                    let options = await WebAuthnClient.getPublicKeyRequestOptions();

                    const credential = await navigator.credentials.get({
                        publicKey: options.publicKeyCredentialRequestOptions,
                        mediation: "conditional",
                    });

                    const userData = await WebAuthnClient.sendSignedChallenge(credential);
                    window.location.href = "/logged-in";
                } catch (error) {
                    console.log(error);
                }
            }

            passkeyLogin();
        </script>
    </body>
</html>
```

### 6.2 Browser Compatibility Check

Implement Conditional UI detection that ensures that Conditional UI is only employed when
the current device / browser combination supports it. This should work without presenting
user-visible errors in the absence of Conditional UI support. Incorporating the
`isConditionalMediationAvailable()` method within the user interface addresses this
concern. If Conditional UI support is given, the Conditional UI login process can be
started.

```javascript
// source: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/isConditionalMediationAvailable#examples

// Availability of `window.PublicKeyCredential` means WebAuthn is usable.
if (window.PublicKeyCredential && PublicKeyCredential.isConditionalMediationAvailable) {
    // Check if conditional mediation is available.
    const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
    if (isCMA) {
        // Call WebAuthn authentication start endpoint

        let options = await WebAuthnClient.getPublicKeyRequestOptions();

        const credential = await navigator.credentials.get({
            publicKey: options.publicKeyCredentialRequestOptions,
            mediation: "conditional",
        });
        /*
        ...
        */
    }
}
```

### 6.3 WebAuthn Autocomplete Token in Input Fields

The input field should receive a webauthn HTML autofill token. This signals the client to
populate passkeys to the ongoing request. Besides passkeys, other autofill values might be
showcased as well. These autofill tokens can be paired with other existing tokens, e.g.:

- `autocomplete="username webauthn"`: Besides displaying passkeys, this also suggests
  username autofill.
- `autocomplete="current-password webauthn"`: Besides displaying passkeys, this further
  prompts for [password autofill](https://www.corbado.com/blog/webauthn-autocomplete).

```html
<label for="name">Username:</label>
<input type="text" name="name" autocomplete="username webauthn" />
<label for="password">Password:</label>
<input type="password" name="password" autocomplete="current-password webauthn" />
```

For further details, we recommend to read this blog post which provides more details on
autofill / autocomplete tokens for passkeys and passwords.

### 6.4 Mediation Property in WebAuthn API Get Call

To retrieve available passkeys after having received the PublicKeyCredentialRequestOptions
object, the `navigator.credentials.get()` function should be called (which serves both
passkeys and passwords). The PublicKeyCredentialRequestOptions object needs to have the
mediation parameter set to conditional to activate Conditional UI on the client. For cases
where you want a modal passkey prompt instead, see
[immediate mediation](https://www.corbado.com/blog/webauthn-immediate-mediation).

```javascript
const credential = await navigator.credentials.get({
    publicKey: options.publicKeyCredentialRequestOptions,
    mediation: "conditional",
});
```

### 6.5 Cancellation of Conditional UI Flow

If there's no available passkey, or the user neglects the suggested passkeys and enters
their email, the Conditional UI flow is stopped. This underscores the importance of always
supporting the standard passkey / WebAuthn login via a modal as well.

A critical point to emphasize here is the potential need to halt an ongoing Conditional UI
request. Contrary to modal experiences, autofill dropdowns lack a cancellation button. As
per WebAuthn's design, only a
[single active credential request](https://github.com/w3c/webappsec-credential-management/issues/206)
should be in progress at any given moment. The WebAuthn standard suggests utilizing an
[AbortController ](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)to
cancel a WebAuthn process, applicable to both regular and Conditional UI login processes
(see [here ](https://w3c.github.io/webauthn/#sctn-sample-aborting)for details).

In production telemetry, this cancellation path is often an expected control-flow outcome,
not a system failure. If you see high volumes of errors you need to classify expected vs
unexpected cases by operation type and timing before treating them as regressions (see
[WebAuthn errors](https://www.corbado.com/blog/webauthn-errors)).

The Conditional UI login process gets activated as soon as a user lands on the page. The
initial task should be to create a globally-scoped `AbortController` object. This will act
as a signal for your client to terminate the autofill request, especially if the user
decides to do the regular [passkey login](https://www.corbado.com/blog/passkey-login-best-practices) process.
Reassure that the `AbortController` can be invoked by other functions and is reset if the
Conditional UI process has to restart. Employ the signal property within the
`navigator.credentials.get()` call, incorporating your `AbortController` signal as its
value. This signals to the passkey / WebAuthn function that the request must be halted if
the signal gets aborted. Remember to set up a fresh `AbortController` each time you
trigger Conditional UI. Using an already-aborted `AbortController` will lead to an instant
cancellation of the passkey / WebAuthn function. The remaining steps align with a regular
[passkey login](https://www.corbado.com/blog/passkey-login-best-practices) process. In the following, you see a
code example of the mentioned steps:

```html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Conditional UI</title>
    </head>
    <body>
        <input type="text" id="username" autocomplete="username webauthn" />

        <script>
            async function passkeyLogin() {
                try {
                    // retrieve the request options (incl. the challenge) from the WebAuthn server
                    let options = await WebAuthnClient.getPublicKeyRequestOptions();

                    const credential = await navigator.credentials.get({
                        publicKey: options.publicKeyCredentialRequestOptions,
                        mediation: "conditional",
                    });

                    const userData = await WebAuthnClient.sendSignedChallenge(credential);
                    window.location.href = "/logged-in";
                } catch (error) {
                    console.log(error);
                }
            }

            passkeyLogin();
        </script>
    </body>
</html>
```

In the absence of Conditional UI support, direct users towards the regular
[passkey login](https://www.corbado.com/blog/passkey-login-best-practices) process. Offering this path is
important for users relying on
[hardware security keys](https://www.corbado.com/blog/best-fido2-hardware-security-keys) (e.g.
[YubiKeys](https://www.corbado.com/glossary/yubikey)) or those compelled to use non-resident keys /
non-discoverable credentials due to authenticator constraints.

### 6.6 Conditional UI in Native Apps

When you develop a [native app](https://www.corbado.com/blog/native-app-passkeys), e.g. for
[iOS](https://www.corbado.com/blog/webauthn-errors) or [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android),
Conditional UI works as well. It doesn't matter if you implement it natively in
[Flutter](https://www.corbado.com/blog/flutter-passkeys-package), Kotlin or Swift, or if you decide to go with
Chrome Custom Tabs [CCT](https://www.corbado.com/blog/native-app-passkeys) or
[SFSafariViewController](https://www.corbado.com/blog/native-app-passkeys) or
[SFAuthenticationSession](https://www.corbado.com/blog/native-app-passkeys) /
[ASWebAuthenticationSession](https://www.corbado.com/blog/native-app-passkeys). Both approaches support
Conditional UI.

#### 6.6.1 Conditional UI in iOS Apps

In general, we found almost no documentation on how to implement Conditional UI support
for [iOS](https://www.corbado.com/blog/webauthn-errors) apps. During our research, however, we discovered two
ways of adding Conditional UI support to an [iOS](https://www.corbado.com/blog/webauthn-errors) app, as the user
experience will also differ.

**Type A: Overlay / Popup over Almost Entire Screen**

The first type A shows an overlay / popup that spans almost over the entire screen. Here,
you'll see all available passkeys for this [relying party](https://www.corbado.com/glossary/relying-party). A
prominent example that implements Conditional UI this way is
[KAYAK](https://www.corbado.com/blog/kayak-passkeys). The overlay / popup emerges automatically, when the user
opens the right screen.

![Conditional UI iOS App Popup](https://www.corbado.com/website-assets/65fd93a0a95c16b286ab7bc1_conditional_ui_ios_app_popup_00d4f8124a.jpg)

**Type B: Keyboard Autofill**

The second type B displays a suitable passkey in the autofill section of the keyboard
(where also passwords are suggested for autofill). Clicking on the suggest value will
perform the [Face ID](https://www.corbado.com/faq/is-face-id-passkey) authentication and lets you log in. In the
current iOS app version of the Corbado developer panel, we have implemented it this way
(see the Sign in with passkey for `<relying party ID>` message together with the WebAuthn
username). To show up, the user needs to tap into the input field:

![Conditional UI iOS app Keyboard Autofill](https://www.corbado.com/website-assets/65fd93ae3406831e812dcae2_conditional_ui_ios_app_keyboard_autofill_98e9550aab.jpg)

This passkey autofill feature in the keyboard section might have issues when the iOS is
freshly installed as apparently some kind of caching happens in the background that looks
up all the available passkeys for this relying party.

Clicking on the key icon on the right of the suggested passkey leads to the known site for
choosing passwords / passkeys in iOS:

![Conditional UI iOS app Keyboard Autofill Details](https://www.corbado.com/website-assets/65fd952b9e058d8bf2ae011c_conditional_ui_ios_app_keyboard_autofill_details_582133a5e0.jpg)

Please note that we have not found official documentation, and our insights are based on
our experiences and hypotheses rather than concrete proof of the proper implementation.

#### 6.6.2 Conditional UI in Android Apps

In [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android), the story for Conditional is a bit
clearer, as there is only one type for Conditional UI / passkey autofill that leverages
the [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) Credential Manager API (see the
documentation [here](https://developer.android.com/training/sign-in/passkeys)). Because
Android providers can differ, monitor
[Credential Manager passkey errors](https://www.corbado.com/blog/webauthn-errors) separately from browser-only
WebAuthn failure patterns.

Opening the page where Conditional UI is implemented shows the following screen, where
you'll find different ways to sign in:

![Conditional UI Android app ](https://www.corbado.com/website-assets/65fd953866efb99383ecadff_conditional_ui_android_app_d9744622dc.jpg)

Clicking on **More saved sign-ins** provides more options to choose for the sign-in
(including [cross-device authentication](https://www.corbado.com/blog/proximity-exchange-protocol-pxp) and the
selection of a different passkey sync platform, e.g. [Samsung](https://www.corbado.com/blog/samsung-passkeys)
Pass or [1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis)):

![Conditional UI Android app details](https://www.corbado.com/website-assets/65fd954176d4bacee21bd397_conditional_ui_android_app_details_bb2b567121.jpg)

## 7. Conditional UI Examples in Different Devices / Browser

To illustrate how Conditional UI looks like for the end user, we added several screenshots
of a Conditional UI autofill menu using [https://passkeys.eu](https://passkeys.eu).

### 7.1 Conditional UI in Windows 11 (22H2) + Chrome 118

![Conditional UI Windows Chrome](https://www.corbado.com/website-assets/653274d5f112bcb90551666f_conditional_ui_windows_chrome_f6be9c714b.png)

### 7.2 Conditional UI in macOS Ventura (13.5.1) + Chrome 118

![Conditional UI macOS Chrome](https://www.corbado.com/website-assets/653274ef4711bafab8f9337e_conditional_ui_macos_chrome_b577291109.png)

### 7.3 Conditional UI in macOS Ventura (13.5.1) + Safari 16.6

![Conditional UI macOS Safari](https://www.corbado.com/website-assets/6532750a0dd891b360beef99_conditional_ui_macos_safari_e27787adb9.png)

### 7.4 Conditional UI in Android 13 + Chrome 118

![Conditional UI Android Chrome](https://www.corbado.com/website-assets/6532752344d30f53cb09b9b6_conditional_ui_android_chrome_25ff68bcb5.jpg)

### 7.5 Conditional UI in iOS 17.1 + Safari 17.1

![Conditional UI iOS Safari](https://www.corbado.com/website-assets/65327537f112bcb90551b96b_conditional_ui_ios_safari_87cd12b54e.PNG)

## 8. Conditional UI in Edge Cases

Let's have a look at some common scenarios in real-life applications.

### 8.1 Conditional UI if no Passkey is available

If no passkey is saved for a site, the Conditional UI will behave differently depending on
browser and OS.

#### 8.1.1 Conditional UI without Passkeys in Chrome on macOS

On **Chrome on macOS**, clicking into the input field shows an empty autofill dropdown:

![conditional ui no passkey macos chrome](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_no_passkey_macos_chrome_8cb107283f.png)

#### 8.1.2 Conditional UI without Passkeys in Safari on macOS

On **Safari on macOS**, no dropdown is shown - just a subtle icon in the input field:

![conditional ui no passkey macos safari](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_no_passkey_macos_safari_1be2b7f264.png)

#### 8.1.3 Conditional UI without Passkeys on Android or iOS

On **Android or iOS**, the autofill interface appears only if the user taps into the field
and the OS finds matching credentials.

This variability is intentional and part of the privacy model of WebAuthn: websites cannot
detect whether the user has a passkey unless the user actively selects one.

### 8.2 Conditional UI and Multiple Credential Managers / Passkey Providers

If a user has multiple [passkey providers](https://www.corbado.com/blog/passkey-providers) installed (e.g.
[iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain),
[Google Password Manager](https://www.corbado.com/blog/how-to-use-google-password-manager),
[1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis)), the browser or OS will
typically default to the user’s primary credential manager.

For a list of different [passkey providers](https://www.corbado.com/blog/passkey-providers) / credential managers
that support passkeys, we recommend to take a look at the following
[GitHub link](https://passkeydeveloper.github.io/passkey-authenticator-aaguids/explorer/).

#### 8.2.1 Conditional UI and Multiple Credential Managers on Android

On Android, Credential Manager exposes different providers like
[Samsung](https://www.corbado.com/blog/samsung-passkeys) Pass or
[1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis).

1. When clicking on the user identifier input field, this menu comes up where the user can
   select a passkey.

![conditional ui multiple credential managers android choose passkey](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_android_choose_passkey_1f5be7736f.png)

2. If the user clicked on "More passkeys" in the screen before, a preselection of other
   [passkey providers](https://www.corbado.com/blog/passkey-providers) / credential managers and passkeys
   appears:

![conditional -ui multiple credential managers android choose sign in](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_android_choose_sign_in_d91c861fca.png)

3. If the user clicked on "More svaed sign-ins" in the screen before, an entire list of
   available comes where the user can select a passkey from.

![conditional ui multiple credential managers android choose sign in details](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_android_choose_sign_in_details_e9d9526da9.png)

#### 8.2.2 Conditional UI and Multiple Credential Managers on iOS

On iOS, the key icon opens the full list of passkeys from various sources.

1. At first, on [iOS 18](https://www.corbado.com/blog/ios-18-passkeys-automatic-passkey-upgrades)+, the regular
   Conditional UI with the default [passkey provider](https://www.corbado.com/blog/passkey-providers) comes.

![conditional ui multiple credential managers ios](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_ios_4c1fd3eaa7.png)

2. When clicking on the keyboard icon, the following selection menu appears.

![conditional ui multiple credential managers ios select provider](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_ios_select_provider_737870e35b.png)

3. After selecting a credential manager / [passkey provider](https://www.corbado.com/blog/passkey-providers), the
   user can select the passkey to be used.

![conditional ui multiple credential managers ios select passkey](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_ios_select_passkey_568b192b3f.png)

> As an app or website, you cannot control which credential manager is used - the OS
> manages that choice to preserve
> [user privacy](https://www.corbado.com/faq/ensure-gdpr-compliance-with-passkeys).

## 9. How Corbado can help

A site cannot tell whether the autofill dropdown appeared, whether it appeared empty or
whether the user ignored it and typed an email address. Section 8.1 states that
measurement problem outright. All three paths end in a login that eventually succeeds, so
a Conditional UI implementation that quietly stopped working looks the same as one that
works.

[Corbado Observe](https://www.corbado.com/observe), the
[authentication observability](https://www.corbado.com/blog/authentication-observability) layer, tracks the
identifier step and the Conditional UI ceremony as one subflow. Its browser SDK ships a
dedicated provide-identifier-with-CUI operation that reports the `getOptions` call, the
ceremony result and the input events on the field itself, so every attempt carries a label
for how it ended: completed through Conditional UI, completed through browser autofill or
completed manually because the user typed.

[Video: Subflow explorer](https://www.corbado.com/videos/features/subflow-explorer.mp4) ([See Subflow Explorer in Corbado Observe](https://www.corbado.com/observe/subflow-explorer))

- **Subflow Explorer** reports completion rate, outcome and step duration for the
  identifier subflow. That is where the Conditional UI share of your sign-ins becomes
  visible, and where a drop after a browser update shows up.
- **Client Capabilities** charts `conditionalGet` and `conditionalCreate` support as a
  share of your login sessions over time, filterable by operating system and touchpoint.
  `conditionalGet` is the `getClientCapabilities()` equivalent of
  `isConditionalMediationAvailable()` resolving to true, so the requirements in section
  5.2 can be checked against your own traffic rather than against a compatibility table.
- **Passkey Errors** keeps the cancellation path from section 6.5 in its own bucket. The
  SDK reports a `cancel_detected` outcome for the Conditional UI ceremony, so an expected
  abort stops inflating your error rate.
- **Login Methods** carries passkey, password and social as three rows, each with its
  share of sign-ins, its completion rate, its error rate and its duration, and each
  measured against the same flows run without that method. Read next to the identifier
  subflow above, that is the number that says whether Conditional UI earns its
  implementation cost.

Sections 3.2 and 6.5 come down to the same maintenance problem: the autocomplete token,
the conditional `get()` call and the abort handling only work while all three agree, and
in most codebases they live in three different places. [Corbado Connect](https://www.corbado.com/connect) ships
them as one login component, so a [password manager](https://www.corbado.com/blog/passkeys-vs-password-managers)
extension rewriting the field underneath stays a component-level fix.

## 10. Conclusion

Passkeys, with its Conditional UI / passkey autofill capability, are the new way to
authenticate online. As we transition to an era where passwords are more and more replaced
by passkeys, the need for robust and user-friendly transition mechanisms is undeniable.
This article has helped to understand how to correctly implement Conditional UI, a great
help in the transition process, and which aspects to pay special attention to.

## Frequently Asked Questions

### How do I check if a browser supports Conditional UI before starting the passkey autofill flow?

Call `PublicKeyCredential.isConditionalMediationAvailable()` and only proceed if it
returns true. This check prevents user-visible errors on unsupported browser and device
combinations. The method should be evaluated on every page load before calling
`navigator.credentials.get()` with `mediation: "conditional"`.

### Why does Conditional UI only work with discoverable credentials and not all passkeys?

Authenticators only store user-specific data such as name and display name for resident
keys (discoverable credentials). Non-resident keys do not retain this information, so the
autofill menu cannot populate account details for the user to select.

### What happens in Conditional UI when a user has no passkey registered for a site?

Behavior varies by platform. Chrome on macOS shows an empty autofill dropdown, Safari on
macOS shows only a subtle icon in the input field, and on Android or iOS the autofill
interface only appears if the OS finds matching credentials after the user taps the field.
This variability is intentional and part of WebAuthn's privacy model: websites cannot
detect whether a passkey exists unless the user actively selects one.

### How do I cancel an ongoing Conditional UI request when a user switches to modal passkey login?

Create a globally-scoped `AbortController` and pass its signal to
`navigator.credentials.get()`. Call `.abort()` on the controller when the user initiates a
modal login flow. Always instantiate a fresh `AbortController` each time Conditional UI
restarts, because reusing an already-aborted controller causes immediate cancellation of
the WebAuthn request.

### Does Conditional UI work in native iOS and Android apps or only in web browsers?

Conditional UI works in both native iOS and Android apps. iOS supports two variants: a
full-screen overlay popup and a keyboard autofill suggestion. Android uses the Credential
Manager API, which can surface passkeys from multiple providers such as Samsung Pass or
1Password.
