Most passkey rollouts stall not because the cryptography fails but because users never see the passkey option at the moment they sign in. Conditional mediation, usually called conditional UI or passkey autofill, puts passkeys into the same autofill menu that already offers saved passwords, so a user who taps the username field can pick a passkey without learning a new button or flow. This guide covers the browser and native platform mechanics in detail: the autocomplete="username webauthn" token, mediation: "conditional" for sign-in, conditional create for automatic passkey upgrades, the Signal API that keeps provider and server credential lists aligned, and the server checks that stop the convenience from weakening security. It is written for CIAM architects and front-end and identity engineers who already understand passkeys; the fundamentals live in the Passwordless and Passkeys Guide.
Source note: API behaviour and browser support below are summarised from the W3C Web Authentication Level 3 Recommendation, MDN, web.dev, Chrome, Android and Apple developer documentation as checked in November 2026; support changes often. Confirm against the official text before relying on it.
Key takeaways
- Autofill is the adoption lever. A conditional request waits silently until the user focuses a field marked
autocomplete="username webauthn", then lists passkeys beside passwords in the browser's own menu. - Detect before you call. Use
PublicKeyCredential.getClientCapabilities()and testconditionalGetandconditionalCreate; the olderisConditionalMediationAvailable()only answers for sign-in. - Conditional create upgrades password users quietly. Called straight after a successful password sign-in, it lets the password manager create a passkey with no extra prompt, but the response carries UP and UV flags set to false that the server must expect.
- One pending request at a time. Abort the conditional request with an
AbortControllerbefore starting a modal WebAuthn call or a conditional create, or the second call fails. - Keep lists in sync with the Signal API.
signalUnknownCredential,signalAllAcceptedCredentialsandsignalCurrentUserDetailsstop deleted or orphaned passkeys from appearing in autofill and failing.
How conditional mediation works
The Credential Management API's navigator.credentials.get() takes a mediation option. MDN documents four values: optional (the default), required, silent and conditional. With conditional, discovered credentials appear in a non-modal list alongside the requesting origin, which in practice means the browser autofill menu. The promise stays pending until the user picks an account; if the user interacts elsewhere, the menu closes without resolving or rejecting the promise and without a visible error.
Web Authentication Level 3, published as a W3C Recommendation dated 25 August 2026, defines the client side of this: relying parties should check the conditionalGet capability (equivalent to isConditionalMediationAvailable() resolving to true) before setting mediation to conditional. Because the browser must list credentials without knowing who the user is, the request relies on discoverable credentials, and the server sends an empty allowCredentials list so every passkey for the RP ID can be offered.
| Mediation value | What the user sees | Typical use in a passkey sign-in design |
|---|---|---|
conditional | Nothing until a marked field is focused, then passkeys in the autofill menu | Default sign-in page: runs on page load alongside the password form |
optional (default) | A modal account chooser when mediation is needed | "Sign in with a passkey" button, triggered by a user gesture |
required | Always asked to authenticate | Re-authentication before a sensitive action or when switching users |
silent | No prompt; resolves null if consent is needed | Automatic re-sign-in on page load where supported; not a passkey ceremony pattern |
MDN notes that the promise resolves with null rather than rejecting when a single credential cannot be unambiguously obtained, so client code must treat null as "no result", not as an error.
Implementing autofill sign-in on the web
The web.dev implementation guide and Apple's WWDC22 "Meet passkeys" session describe the same sequence. In order:
- Mark the field. Add
autocomplete="username webauthn"to the username input. Both tokens are needed:usernamekeeps password autofill working,webauthnadds passkeys. web.dev notes thatautofocuson the field shows the menu on page load. - Feature detect. Check
window.PublicKeyCredential, then callgetClientCapabilities()and testconditionalGet === true. Fall back toisConditionalMediationAvailable()only wheregetClientCapabilities()is missing; MDN encourages the newer call. - Fetch options from the server. A fresh, single-use challenge per attempt with a short expiry; an empty
allowCredentials;rpIdidentical to therp.idused at registration. On the client,PublicKeyCredential.parseRequestOptionsFromJSON()converts Base64URL fields. - Start the request early. Call
navigator.credentials.get({ publicKey, mediation: "conditional", signal })as soon as the page loads. Apple notes that autofill-assisted requests need no user gesture and have a much longer timeout than modal requests. - Handle the result. Serialise with
credential.toJSON()and post it to the server. TreatNotAllowedError(cancelled or nothing selected) andAbortError(your own abort) as quiet outcomes, not failures to show the user. - Keep the password path working. If the user picks a password from the same menu, the passkey promise simply does not resolve and the normal form submission continues.
Coexisting with a passkey button and identifier-first flows
Many sign-in pages keep a "Sign in with a passkey" button for users whose provider does not surface autofill, and an identifier-first step for federated or SSO routing. Both start a second WebAuthn call, so abort the conditional request first through its AbortController, run the modal call from the click handler, and restart the conditional request if the user returns to the form. Apple's guidance for native apps is the same pattern: if the user types a username that has a passkey, cancel the autofill request and present the modal sheet instead. Apple also notes that WebKit may limit modal WebAuthn calls on a page that was loaded without a user gesture, which is another reason to trigger modal calls only from clicks.
Native apps on Apple platforms and Android
Platforms are listed alphabetically. Both need the app linked to the web domain so the same passkeys work in the app and the browser.
| Platform | Domain association | Field annotation | Autofill request |
|---|---|---|---|
| Android (Jetpack Credential Manager) | App linked to the RP ID domain | Attach a request to the username and password View objects | PendingGetCredentialRequest set on each view's pendingGetCredentialRequest, combining GetPublicKeyCredentialOption and GetPasswordOption |
| Apple (AuthenticationServices) | Associated domains with the webcredentials service | textContentType = .username | ASAuthorizationController.performAutoFillAssistedRequests() with an assertion request from ASAuthorizationPlatformPublicKeyCredentialProvider |
- Android: Android's documentation describes linking views to Credential Manager requests from Android 15 Beta 2 with
androidx.credentials1.5.0-alpha01; when the user focuses a linked view, credentials from all providers appear in keyboard inline or drop-down suggestions. The page states this applies toViewobjects "at this time" and also works as a fallback when a user dismisses the Credential Manager bottom sheet and taps a field. Response handling is the same as forgetCredential. Check the current library release before relying on the alpha version string. - Apple: In the WWDC22 session, Apple shows passkeys appearing in the QuickType bar whenever a username field is focused while the request runs. Selecting one triggers Face ID or Touch ID and returns an
ASAuthorizationPlatformPublicKeyCredentialAssertionto the delegate; nothing is typed into the field. Start the request early in the view lifecycle, and cancel it if the user chooses a password. The same request also offers passkeys from a nearby device.
Conditional create: automatic passkey upgrades
Autofill sign-in only helps users who already have a passkey. Conditional create closes the gap by letting the password manager create a passkey right after a password sign-in, without a separate enrolment screen. The call is navigator.credentials.create() with normal publicKey options plus mediation: "conditional".
| Requirement or behaviour | Source and detail | Implementation consequence |
|---|---|---|
| Recent authentication for the origin | WebAuthn L3: the client must have recently mediated an authentication for the caller's origin, otherwise NotAllowedError | Call it immediately after password sign-in succeeds; Chrome's guide notes magic links, phone verification and federated sign-in do not qualify |
| UP and UV not collected | WebAuthn L3: clients set user presence and user verification requirements to false unless performed during the ceremony | Server verification must accept UP and UV false for this registration path only |
| Cross-origin calls | WebAuthn L3: a cross-origin call with conditional mediation throws NotAllowedError | Run it in the top-level first-party page, not an embedded widget |
| Existing passkey | Chrome: InvalidStateError | Send excludeCredentials with the user's existing credential IDs |
| Provider support | Chrome: the capability flag reflects only the browser; the passkey provider can still decline | Silent failure is normal; never show your own error |
Chrome's documentation lists support in Safari on macOS and all browsers on iOS through iCloud Keychain, and Chrome on desktop and Android through Google Password Manager; on iOS 18 and later and Android 14 and later, third-party providers handle the request if they implement it. The browser notifies the user only on success, so swallow InvalidStateError, NotAllowedError and AbortError silently. Abort any pending conditional sign-in request before calling conditional create.
The upgrade does not prove anything new about the user: it inherits the assurance of the password sign-in that preceded it. Make the server mark these passkeys as created by automatic upgrade, and decide in policy whether such a passkey alone may later satisfy step-up for sensitive actions or whether the first sign-in with it should collect user verification. See the Passkey Rollout Guide for enrolment policy across populations.
Server-side checks that keep autofill safe
Conditional UI changes the client experience, not the verification rules. The server still verifies every assertion against the stored public key, the challenge it issued and the expected origin and RP ID, preferably with a maintained FIDO or WebAuthn server library as web.dev recommends.
- User verification flag: With
userVerification: "preferred"(the default, and Apple's recommendation to avoid failures on devices without biometrics), web.dev warns that verification can be skipped. Read the UV bit in the authenticator data. If it is false and the action needs strong assurance, require another factor or re-run the ceremony withrequired. - Challenge hygiene: A conditional request may stay pending for minutes. Issue the challenge with a short validity and refresh it on focus or after a failed attempt rather than accepting a stale one.
- Account enumeration: Because the browser lists accounts, the page never needs to say whether a username exists. Keep responses for unknown credentials uniform, in line with OWASP ASVS 5.0 requirement V6.3.8.
- Consistent pathways: ASVS V6.3.4 asks that multiple authentication pathways are documented and enforce consistent strength. A passkey path beside an SMS fallback is only as strong as the fallback; record which method each session used.
- Cross-device sign-in: web.dev notes an
authenticatorAttachmentofcross-platformindicates a cross-device sign-in; offer passkey creation on the current device afterwards.
Keeping provider and server lists aligned with the Signal API
Autofill exposes stale state. A passkey the user deleted from their account settings, or one whose registration never reached the server, still appears in the menu and fails when chosen. WebAuthn L3 defines three signal methods; Chrome's documentation describes them as follows.
| Method | Parameters | When to call | Effect in the provider |
|---|---|---|---|
signalUnknownCredential | rpId, credentialId | After a sign-in fails because the server does not know the credential, while the user is not authenticated | The passkey should be removed |
signalAllAcceptedCredentials | rpId, userId, allAcceptedCredentialIds | After the user deletes a passkey, and on every sign-in | Passkeys not in the list are hidden; listed ones are restored |
signalCurrentUserDetails | rpId, userId, name, displayName | When username or display name changes, and on every sign-in | Stored passkeys are updated with the new details |
Chrome's support table lists all three in Chrome and Edge 132 and Safari 26, although the same page's compatibility notes say Safari support is not yet implemented, so feature-detect each method before calling it. The documented caution matters: omitting a valid credential ID from signalAllAcceptedCredentials hides that passkey and blocks the user, and an empty list can hide all of them. Build the list from the authoritative credential table, never from a cache.
Decision guidance
- Consumer and CIAM sign-in: Run conditional sign-in on every password page, add conditional create after password sign-in, and keep a passkey button for providers that do not surface autofill. Scale is where the Signal API pays back, because orphaned credentials generate support contacts. See the Customer IAM (CIAM) Guide.
- Workforce sign-in through an IdP: Autofill matters less when the IdP controls the page and policy demands specific authenticators; attestation and allow lists drive that design. See Workforce Passkeys in Entra ID and Okta.
- Small teams: Use a hosted CIAM or a maintained library that already implements conditional mediation and signals rather than hand-building the client logic.
- High-risk actions: Do not reuse the autofill session for payments or account changes; run a modal ceremony with
userVerification: "required". See Passkeys for Payments.
Detection and measurement
Log the sign-in method per session (passkey via autofill, passkey via button, password, fallback), the authenticatorAttachment, the UV flag and whether a passkey was created through conditional create. Useful measures:
- Passkey sign-in share: passkey sign-ins as a percentage of all sign-ins, split by autofill and button.
- Automatic upgrade rate: conditional create successes per password sign-in, by browser and provider.
- Unknown credential rate: assertions for credential IDs the server does not hold, which should fall once
signalUnknownCredentialis deployed. - Fallback rate after passkey selection: users who chose a passkey and then completed sign-in by password or recovery.
- UV false share: assertions without user verification, watched against step-up policy.
Common failure patterns
- Missing the
webauthntoken: the request runs but nothing appears in the menu, so the team concludes users do not want passkeys. - Two pending WebAuthn calls: the button or conditional create fails because the conditional request was never aborted.
- Rejecting automatic upgrades: server libraries configured to demand UP or UV at registration reject every conditional create response.
- Showing errors for silent outcomes: treating
NotAllowedErrororAbortErroras failures, which confuses users who saw nothing go wrong. - Stale credentials left in providers: deleted or half-registered passkeys stay in autofill and fail, pushing users back to passwords and the help desk. See Passkey account recovery.
- Weak fallbacks beside passkeys: phishing-resistant autofill does not help if an attacker can still choose the SMS or password path; adversary-in-the-middle kits target whichever path remains. See the AiTM Phishing Guide.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev. 5 | IA-2, IA-2(8), IA-5 | User authentication, replay-resistant access, authenticator management including revocation and lifecycle |
| NIST CSF 2.0 | PR.AA-03 | Users, services and hardware are authenticated |
| OWASP ASVS 5.0 | V6.2.7, V6.3.4, V6.3.8, V6.5.6 | Password managers permitted, consistent pathways, no user enumeration, revocable authenticators |
| MITRE ATT&CK | T1110.004 Credential Stuffing, T1557 Adversary-in-the-Middle, T1111 Multi-Factor Authentication Interception | Techniques that lose effect as passkey sign-in replaces passwords and OTPs |
Practitioner checklist
- Add
autocomplete="username webauthn"to every username field on sign-in pages. - Feature-detect with
getClientCapabilities()and start a conditionalget()on page load with an emptyallowCredentials. - Abort the conditional request before any modal WebAuthn call or conditional create, and restart it afterwards.
- Add conditional create immediately after password sign-in, with
excludeCredentialsset and silent error handling. - Allow UP and UV false only on the conditional create registration path, and tag those credentials.
- Check the UV flag on every assertion and step up where policy needs verified users.
- Deploy the three Signal API methods behind feature detection, built from the authoritative credential table.
- Link native apps with associated domains or Android app linking, and wire
performAutoFillAssistedRequests()orpendingGetCredentialRequest. - Track passkey sign-in share, upgrade rate and unknown credential rate per browser and provider.
Standards and references
- W3C: Web Authentication Level 3
- MDN: CredentialsContainer get() method
- MDN: PublicKeyCredential isConditionalMediationAvailable()
- web.dev: Sign in with a passkey through form autofill
- Chrome for Developers: Help users adopt passkeys with automatic passkey upgrades
- Chrome for Developers: Signal API for passkeys
- Android Developers: Integrate Credential Manager with autofill
- Apple Developer: Meet passkeys (WWDC22)
Related NHI Mgmt Group resources: Passwordless and Passkeys Guide · Passkey Rollout Guide · Top 10 Passkey Deployment Mistakes · Customer IAM (CIAM) Guide