---
url: 'https://www.corbado.com/blog/webauthn-l3-credential-manager-support'
title: 'WebAuthn L3 Support in Credential Managers'
description: 'Which WebAuthn Level 3 features third-party credential managers actually support: PRF, conditional create, Signal API and largeBlob, with sources.'
lang: 'en'
author: 'Vincent Delitz'
date: '2026-09-08T08:26:47.660Z'
lastModified: '2026-09-08T09:19:46.229Z'
keywords: 'webauthn level 3 support, credential manager passkey features, third-party passkey provider support, prf support password manager, signal api support'
category: 'WebAuthn Know-How'
---

# WebAuthn L3 Support in Credential Managers

## Key Facts

- **Passkey support is usually discussed per browser and operating system.** In practice
  the credential manager the user set as their provider decides it.
- **A missing feature has a commercial cost.** "Use Apple or Google instead" reads as a
  downgrade to users who chose their own manager.
- **The provider decides PRF, conditional create, conditional UI, largeBlob and the Signal
  API.** credProtect and credBlob are security key properties.
- **The same product behaves differently per platform.** Bitwarden returns PRF values on
  Linux with Firefox and nothing on iOS with Safari.
- **The capability check and the observed behaviour disagree.** Chrome 151 on macOS
  reported the Signal API as unsupported for Google Password Manager, and it worked anyway.

## 1. Why Browser Support Tables are not enough

Passkey feature support is documented per browser and per operating system. That is how the
specs are written and how our own [PRF support tables](https://www.corbado.com/blog/passkeys-prf-webauthn) are
built, and for a long time it was enough, because the passkey was stored by whatever shipped
with the device.

That assumption no longer holds. Since Android 14 and recent Windows 11 builds, third-party
credential managers act as full passkey providers, which adds a third axis that the browser
and OS tables do not cover. A user on Android with a third-party manager set as the default provider is in a
different situation than the same user on the same phone with Google Password Manager. As a
relying party you usually notice the difference only when a feature returns nothing and
raises no error.

This article covers that third axis: which WebAuthn Level 3 features depend on the credential
manager, what we can verify today and where the answer is still open.

**One note on wording.** Password manager, credential manager, passkey manager and passkey
provider all mean the same thing here: the software that stores the passkey and answers the
WebAuthn call. We use the four labels interchangeably and spell out a distinction only where
it changes the answer.

## 2. Which Layer owns which Feature

The three layers have to be separated before the matrix makes sense, because most of the
confusion in this topic comes from mixing them.

- **Browser and platform layer.** `getClientCapabilities` and
  [related origin requests](https://www.corbado.com/blog/webauthn-related-origins-cross-domain-passkeys) live here.
  They depend on the browser version and, in the case of related origins, on your own
  `.well-known` file. A credential manager cannot add or remove them.
- **Credential manager layer.** The [PRF extension](https://www.corbado.com/blog/passkeys-prf-webauthn),
  [conditional create](https://www.corbado.com/blog/conditional-create-passkeys),
  [conditional UI](https://www.corbado.com/blog/webauthn-conditional-ui-passkeys-autofill), largeBlob and the
  [Signal API](https://www.corbado.com/blog/webauthn-signal-api) all need the provider to implement them. This is
  the layer the matrix covers.
- **Authenticator layer.** [credProtect](https://www.corbado.com/blog/webauthn-credprotect-security-keys), credBlob,
  minPinLength and enterprise attestation are CTAP features of hardware authenticators. A
  software credential manager does not implement them at all. They are covered in our
  [security key article](https://www.corbado.com/blog/webauthn-credprotect-security-keys) and not in the matrix
  below.

The distinction decides where you look first. "PRF does not work" can mean that the
browser does not surface it, that the provider does not implement it or that the credential
was created before the feature existed. The three have different fixes.

## 3. Features we track

| Feature | What it gives you | Deep dive |
| --- | --- | --- |
| PRF on get | Derive an encryption key from an existing passkey | [PRF extension](https://www.corbado.com/blog/passkeys-prf-webauthn) |
| PRF on create | Get the first key material already at registration | [PRF extension](https://www.corbado.com/blog/passkeys-prf-webauthn) |
| Conditional create | Upgrade a password user to a passkey without a prompt | [Conditional create](https://www.corbado.com/blog/conditional-create-passkeys) |
| Conditional UI | Passkey in the autofill dropdown | [Conditional UI](https://www.corbado.com/blog/webauthn-conditional-ui-passkeys-autofill) |
| Signal API | Keep server state and provider list in sync | [Signal API](https://www.corbado.com/blog/webauthn-signal-api) |
| largeBlob | Store a small blob next to the credential | [PRF vs largeBlob](https://www.corbado.com/blog/passkeys-prf-webauthn) |

## 4. Support Matrix: Credential Managers

The matrix has two parts. The first is the status per provider and feature, built from our own
tests, community data and vendor documentation. The second lists what we measured ourselves,
per operating system and browser, because the same manager answers differently depending on
where it runs.

### 4.1 Status per Provider

Legend: ✅ works in every combination we measured, 🟡 partial, meaning it works on some
platforms or browsers but not others or only in a share of attempts, ❌ no output in the
combinations we measured. There is no symbol for "we do not know": a provider we cannot measure
is named below the table instead of taking up a row.

**Status: August 2026.** The two PRF columns are taken from our
[PRF support article](https://www.corbado.com/blog/passkeys-prf-webauthn), which owns the detail, the per-platform
numbers and the sources for that feature.

| Credential manager | PRF on create | PRF on get | Conditional create | Conditional UI | Signal API | largeBlob | Status |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Apple Passwords (iCloud Keychain) | ✅ | ✅ | ✅ Safari 18+, macOS 15+ | ✅ | ❌ accepted, no effect | ✅ | Aug 2026, own tests plus vendor docs |
| Google Password Manager | ✅ | ✅ | ✅ Chrome 136+ Windows and Linux, 142+ Android | ✅ | ✅ applied | ✅ | Aug 2026, own tests plus vendor docs |
| Windows Hello | ✅ Chrome 147+, Firefox 148+ | ✅ 25H2, Feb 2026 update | ❌ no password store | ✅ | ❌ accepted, no effect | ❌ | Aug 2026, own tests |
| Microsoft Password Manager | ✅ | ❌ ceremony fails | ❌ | ✅ | ❌ accepted, no effect | ❌ declared, then fails | Aug 2026, own tests on Windows 11 |
| 1Password | ✅ | ✅ | ✅ | ✅ | ❌ accepted, no effect | ❌ | Aug 2026, own tests on macOS |
| Enpass | ✅ | ✅ | ✅ | ✅ | ❌ accepted, no effect | ❌ | Aug 2026, own tests on macOS |
| Bitwarden | 🟡 platform split | 🟡 platform split | ✅ | ✅ | ❌ accepted, no effect | ❌ | Aug 2026, own tests on macOS plus demo data |
| Keeper | ✅ | ✅ | ✅ | ✅ | ❌ accepted, no effect | ❌ | Aug 2026, own tests on macOS |
| NordPass | ❌ | ❌ | 🟡 runs, but not silently | ❌ no credential offered | ❌ accepted, no effect | ❌ | Aug 2026, own tests on macOS |
| Samsung Pass | ❌ | ✅ | ❌ | ✅ | ❌ accepted, no effect | ❌ | Aug 2026, own tests on Android |
| Dashlane | ❌ | ❌ | 🟡 iOS 18, macOS 15, ❌ Chrome on macOS | ✅ | ❌ accepted, no effect | ❌ | Aug 2026, own tests on macOS |
| Proton Pass | ✅ | ✅ | ✅ | ✅ | ❌ accepted, no effect | ❌ | Aug 2026, own tests on macOS |

Two providers sit below the table rather than in it. **KeePassXC** and **KeePassDX** are
covered by community data that puts both in the group returning a PRF value on the assertion,
KeePassXC only sometimes at creation, and we have run neither ourselves.

Every row in the table above is a measurement. A cell we cannot stand behind keeps the provider
out of the table rather than filling it with symbols that look like knowledge.

Sources and caveats per row:

- **Proton Pass returns a PRF value at creation and the identical value on the next
  authentication**, tested by us on macOS 26.3 with Chrome 151. That is the CTAP 2.2 shape and
  the property an encryption feature depends on, and 1Password is the only other third-party
  manager where we have measured it.
- **Enpass creates a passkey silently while the browser says it cannot.** Chrome 151 reported
  `conditionalCreate: false` for the active Enpass provider and the ceremony went through
  anyway, in two separate runs. Enpass also returns a PRF value at creation and the identical
  value on the next authentication, which puts it in the same CTAP 2.2 bracket as iCloud
  Keychain and Google Password Manager. It declined largeBlob at registration and acted on none
  of the three signal calls.
- **The PRF columns are a summary of another page.** The
  [PRF article](https://www.corbado.com/blog/passkeys-prf-webauthn) carries the per-platform numbers, the screenshots
  and the sources behind them. Where a PRF cell here disagrees with that article, the article
  is the authority.
- **Twelve rows carry our own measurements** for everything outside PRF, eight of them on macOS 26.3
  with Chrome 151 and each with the manager set as the active provider. Section 4.2 lists every
  run. Google Password Manager stored a largeBlob and returned the identical value in a second
  ceremony, and answered conditional UI from the autofill dropdown. 1Password and Enpass
  declined largeBlob at registration. iCloud Keychain stored and returned the blob.
- **All twelve accepted every Signal API call and only one acted on it.** Google Password
  Manager renamed the entry after `signalCurrentUserDetails`; the other eleven left theirs
  untouched. No call threw an error, and the reported capability contradicted the observed
  behaviour in both directions. Section 6 has the numbers.
- **Conditional create splits the field.** Chrome 151 on macOS reported
  `conditionalCreate: false` for Google Password Manager and iCloud Keychain and rejected the
  ceremony for both, which matches the version table in our
  [conditional create article](https://www.corbado.com/blog/conditional-create-passkeys): the Chrome path covers
  Windows, Linux and Android, and macOS runs the feature in Safari. 1Password, Bitwarden and
  Proton Pass created a passkey silently on the same machine. The versions in the column come
  from that article, except the Dashlane entry on iOS 18 and macOS 15, which Dashlane documents
  itself.
- **Create and get are separate capabilities**, so a single "supports PRF" answer per vendor
  can be wrong in either direction. Keeper was listed as creating the passkey and then returning
  nothing on the assertion until we ran it ourselves in August 2026: it returned a value at
  creation and the identical value on the next authentication. Either Keeper closed the gap or
  the community numbers came from a different platform. Our own run takes precedence and the row
  now says so.
- **Keeper declares almost everything and delivers less.** Chrome 151 returned twenty-four
  capability keys for the active Keeper provider with all but two set to `true`, including
  `extension:largeBlob`. Keeper then declined largeBlob at registration and acted on none of
  the three signal calls it had just reported as supported. Conditional create is the one place
  where the flag and the behaviour agree.
- **Bitwarden differs by platform.** It returns PRF on Linux with Firefox and nothing on iOS
  with Safari, and our own test on macOS with Chrome came back empty. The provider path has
  been [open since 2025](https://github.com/orgs/bitwarden/discussions/13838).
- **Dashlane** uses PRF as a relying party to unlock its own vault and still returns nothing
  to third-party sites. A vendor announcement about PRF therefore says little about what your
  own integration will receive.
- **Microsoft Password Manager and Windows Hello are two different providers.** The former is
  the manager built into Edge and reports its own AAGUID, `d3452668-01fd-4c12-926c-83a4204853aa`
  against Windows Hello's `08987058-cadc-4b81-b6e1-30de50dcbe96`. Its behaviour differs as well,
  and more sharply than we previously recorded: the assertion does not return nothing, it
  fails.
- **Microsoft Password Manager aborts the whole ceremony over an extension it cannot serve.**
  At registration it confirmed largeBlob through the extension output itself, not merely through
  a capability flag, and returned a PRF value. Every later `get()` that asked for largeBlob or
  PRF failed with a `NotAllowedError` after the user had already picked the passkey and
  confirmed. A modal `get()` for the same credential without any extension succeeded on the same
  machine in the same session, which rules out the modal ceremony as the cause. WebAuthn expects
  a client to ignore an extension it does not support. Here the request takes the login down
  with it.
- **Samsung Pass returns PRF on the assertion and nothing at registration.** The registration
  came back with no extension result at all for PRF, and the next authentication returned a
  value. That is the CTAP behaviour where `hmac-secret` is available unconditionally, and it
  means a relying party that gates its encryption feature on the registration result will write
  Samsung Pass off for a capability it actually has. Read both ends before you decide.
- **Windows Hello declares more than it delivers.** On Windows 11 with Chrome 151 the client
  reported twenty-four capability keys with all but two set to `true`.
  `extension:largeBlob` came back `true` and the registration returned no blob support at all.
  All three signal calls were reported as supported, all three were accepted and the entry
  under Settings > Accounts > Passkeys was unchanged afterwards. This is the same pattern as
  Keeper, on a platform authenticator rather than a browser extension.
- **Windows Hello** needed the February 2026 update on 25H2 to expose `hmac-secret`, which is
  the CTAP feature the PRF extension is built on. hmac-secret is not itself a Level 3 feature,
  it is the authenticator side that L3's PRF extension talks to, which is why a browser can
  support PRF while the platform still hands back nothing.
- **largeBlob is the thinnest column.** Apple documents it for
  iCloud Keychain since iOS 17, Google documents it as unsupported for Google Password Manager,
  and our own run on macOS 26.3 with Chrome 151 wrote a blob to a Google Password Manager
  passkey and read it back unchanged. We record what we measured and leave the contradiction
  visible.
- **A feature has to pass two gates before it reaches a third-party manager.** The browser or
  the platform has to forward it, and the provider has to implement it. The Signal API needs
  Chrome or Edge 132 and above, and on Android additionally Android 15 with
  `androidx.credentials 1.6.0`; Chrome's own documentation states that desktop extension
  providers then decide whether to act on the signal. Conditional create has been up to the
  provider since iOS 18 and Android 14. For every provider in the table the first gate is open,
  so each ❌ in those two columns is a decision by the provider and not a missing browser
  feature.

### 4.2 What we measured ourselves, per Platform

We put twelve providers through the same test page, eight of them on one Mac, three on a
Windows 11 machine and one on a Galaxy phone. The table grows with every provider we can reach.

| Provider | OS | Browser | Conditional create | Conditional UI | Signal API | largeBlob |
| --- | --- | --- | --- | --- | --- | --- |
| Google Password Manager | macOS 26.3 | Chrome 151 | ❌ rejected | ✅ credential returned | ✅ entry renamed | ✅ written and read back |
| 1Password | macOS 26.3 | Chrome 151 | ✅ created silently | ✅ credential returned | ❌ accepted, no effect | ❌ declined at registration |
| iCloud Keychain | macOS 26.3 | Chrome 151 | ❌ rejected | ✅ credential offered | ❌ accepted, no effect | ✅ written and read back |
| Bitwarden | macOS 26.3 | Chrome 151 | ✅ created silently | ✅ credential returned | ❌ accepted, no effect | ❌ declined at registration |
| Dashlane | macOS 26.3 | Chrome 151 | ❌ rejected | ✅ credential returned | ❌ accepted, no effect | ❌ declined at registration |
| Proton Pass | macOS 26.3 | Chrome 151 | ✅ created silently | ✅ credential returned | ❌ accepted, no effect | ❌ declined at registration |
| Enpass | macOS 26.3 | Chrome 151 | ✅ created silently | ✅ credential returned from its own overlay | ❌ accepted, no effect | ❌ declined at registration |
| Keeper | macOS 26.3 | Chrome 151 | ✅ created silently | ✅ credential returned | ❌ accepted, no effect | ❌ declined at registration |
| Windows Hello | Windows 11 | Chrome 151 | ❌ nothing to upgrade from | ✅ credential returned | ❌ accepted, no effect | ❌ declined at registration |
| Microsoft Password Manager | Windows 11 | Edge 151 | ❌ rejected with a saved password present | ✅ credential returned | ❌ accepted, no effect | ❌ declared, then NotAllowedError on write |
| NordPass | macOS 26.3 | Chrome 151 | 🟡 created, with its own confirm dialog | ❌ no credential offered | ❌ accepted, no effect | ❌ declined at registration |
| Samsung Pass | Android | Chrome 151 | ❌ rejected with a saved password present | ✅ credential returned | ❌ accepted, no effect | ❌ declined at registration |

Three results stand out:

- **Conditional create differs by provider on the same browser.** Chrome 151 on macOS reports
  `conditionalCreate: false` for Google Password Manager and iCloud Keychain and rejects the
  ceremony for both. With 1Password, Bitwarden, Proton Pass, Enpass and Keeper the same call
  created a passkey without a prompt, none of which had a saved password for the origin either.
  NordPass sits between the two: the ceremony returns a credential, but only after its own window
  asks the user to confirm, which is the opposite of the silent upgrade the feature exists for.
  Microsoft Password Manager advertises the capability, holds a password for the origin and
  still rejects the ceremony. Windows Hello advertises it too and has no password store to
  upgrade from in the first place. For Enpass the browser reported
  `conditionalCreate: false` and the ceremony still went through, so the flag and the behaviour
  disagree within a single run.
- **Conditional UI works almost everywhere, and the exception matters.** Eleven of twelve
  providers answered the autofill request with a usable credential. Extension-based managers
  serve it from their own overlay rather than the browser dropdown, so check both when you debug
  it; Enpass is the clearest case, its list replaces the Chrome dropdown entirely. NordPass is
  the one that did not answer: the listener runs, the field is focused and no credential is ever
  offered, in either surface. Without conditional UI the passkey never appears while the user
  types, and they have to open the manager by hand at every login.
- **largeBlob separates the providers most sharply.** Only iCloud Keychain and Google Password
  Manager stored a blob. All six third-party managers declined it at registration, and so did
  Windows Hello, which rules out the simple reading that shipping with the operating system is
  what decides it. Microsoft Password Manager is the one case that is worse than a decline: it
  accepted largeBlob at registration and then failed the write ceremony outright.

![Test page showing a passkey created with Google Password Manager, with the AAGUID ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4, largeBlob supported and PRF enabled at creation](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/02_gpm_registration_aaguid_7f179245ab.jpg)

_The first step of every run. The AAGUID decides which row a result belongs to, because a
dialog that falls back to the provider shipped with the OS is the easiest way to mislabel a
whole row._

![Chrome autofill dropdown on the test page showing the entry l3-test@corbado.com with the label Passkey and Google Password Manager](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/03_gpm_conditional_ui_3801d80fd2.png)

_Conditional UI, Google Password Manager on macOS 26.3 with Chrome 151. The dropdown names the
provider, so the result cannot be confused with one produced by another manager. The credential
list is fixed when the conditional request starts, so a passkey created afterwards only appears
once you restart the request._

Conditional UI stays 🟡 for the managers we have not run ourselves. A ❌ there needs a failed
run rather than a missing one. Enpass moved from 🟡 to ✅ for exactly that reason, and NordPass
is the first provider that earned the ❌ the hard way, by advertising the capability and then
offering nothing. Without
conditional UI the passkey never appears in the dropdown and the user has to open the manager
at every login, which degrades the flow without blocking it.

## 5. What to build when a Provider is missing a Feature

- **Detect capabilities, not products.** Ask
  [getClientCapabilities](https://www.corbado.com/blog/webauthn-client-capabilities) and the extension outputs, then
  branch on the answer. Sniffing the provider by AAGUID does not work as a control flow
  anyway, because you only get the AAGUID from the attestation object at registration and not
  on a login, so it is unavailable at the moment you would need it. Treat the capability answer
  as an indication and not as proof, for the reason given in
  [section 6](#6-why-the-capability-check-alone-is-not-sufficient).
- **Design the missing case first.** Decide what happens when PRF comes back empty before you
  design the path where it works. A flow that only survives with two providers is a flow for
  Apple and Google users.
- **Never let a login depend on an extension request.** An unsupported extension is supposed to
  come back empty. With Microsoft Password Manager it took the whole ceremony down instead: the
  same credential that failed a `get()` asking for PRF authenticated without complaint once the
  extension was dropped from the request. Ask for the extension in a separate ceremony, or retry
  without it when a `get()` fails and never put the extension on the request that has to
  authenticate the user.
- **Do not push the problem onto the user.** Asking people to switch credential manager is not
  an option. Keep the feature-dependent part optional, or offer a second path that works
  without it. Falling back to the provider shipped with the operating system is technically
  sound, and it still reads as a downgrade to anyone who installed their manager deliberately,
  which is the [commercial side of the same problem](https://www.corbado.com/blog/passkeys-prf-webauthn).
- **Measure it in your own traffic.** The provider distribution of your users is a property of
  your user base and not of the market, and it determines whether a feature-dependent flow is
  worth building at all.

## 6. Why the Capability Check alone is not sufficient

`getClientCapabilities()` is the standardised way to ask what the current client and provider
support, and it belongs at the start of any feature detection. It should not be the only
check.

In a run on macOS 26.3 with Chrome 151, the browser reported all three Signal API capabilities
as `false` for the active provider:

```json
{
  "signalAllAcceptedCredentials": false,
  "signalCurrentUserDetails": false,
  "signalUnknownCredential": false
}
```

We called the three methods regardless, with three different providers active on the same
machine and in the same browser. None of the calls threw an exception, and the outcomes were
not the same:

| Active provider | Capability reported | `signalCurrentUserDetails` | Effect in the provider's own list |
| --- | --- | --- | --- |
| Google Password Manager | `false` | accepted | entry renamed |
| 1Password | `false` | accepted | unchanged |
| iCloud Keychain | `false` | accepted | unchanged |
| Bitwarden | `true` | accepted | unchanged |
| Dashlane | key absent | accepted | unchanged |
| Proton Pass | `true` | accepted | unchanged |
| Enpass | `false` | accepted | unchanged |
| Keeper | `true` | accepted | unchanged |
| Windows Hello | `true` | accepted | unchanged |
| Microsoft Password Manager | `true` | accepted | unchanged |
| NordPass | `true` | accepted | unchanged |
| Samsung Pass | `true` | accepted | unchanged |

The flag is wrong in both directions. Google Password Manager reports `false` and renames the
entry anyway. Bitwarden reports `true` for all three signal methods and for PRF, and in two
runs it applied no signal and returned no PRF output at all. Keeper reports `true` for all
three signal methods as well and renamed nothing. Conditional create fails in both directions.
Chrome reported `false` for Enpass and Enpass created the passkey regardless. Edge reported
`true` for Microsoft Password Manager, and with a password for the origin sitting in that same
manager the ceremony still came back with a `NotAllowedError`. The saved password matters here:
conditional create has nothing to upgrade without one, so a rejection on an empty vault would
prove nothing. We ran it twice, once without and once with the password, and got the same
answer both times.

The shape of the answer varies too. With Google Password Manager, iCloud Keychain and
1Password active, Chrome returned eleven keys with several set to `false`. With Keeper active
it returned twenty-four keys with all but two set to `true`, including `extension:payment`,
`extension:minPinLength` and `extension:largeBlob`, and Keeper then declined largeBlob at
registration. Windows Hello on Windows 11 answered with the same twenty-four keys and the same
two exceptions, and declined largeBlob as well, so the pattern is not limited to browser
extensions. In another combination Chrome left `conditionalCreate` and the three signal keys
out of the response entirely. An absent key says
something different from `false`, and neither is a promise about behaviour. Read the capability
answer as a starting point and confirm the ones you depend on.

![Test page with Bitwarden as the active provider: every client capability including the three signal methods is green, while the registration below shows largeBlob and PRF as not supported](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/06_bitwarden_declares_all_delivers_none_553c67f119.jpg)

_Bitwarden on macOS 26.3 with Chrome 151. Every capability in the upper block is green. The
registration in the lower block returned no extension result at all for largeBlob and PRF, in
two separate runs._

![Test page with Microsoft Password Manager confirmed by AAGUID, largeBlob supported by the provider and PRF returned at creation, all green](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/mpm_01_registration_largeblob_ok_98f54b2acf.png)

_Microsoft Password Manager on Windows 11 with Edge 151. The provider confirms largeBlob through
the extension output at registration, which is a stronger statement than a capability flag._

![The same run further down the page: largeBlob write failed with a NotAllowedError and PRF on get failed with the same error](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/mpm_02_largeblob_prf_fail_856385b88a.png)

_The same run, a few ceremonies later. Both requests that carry an extension come back with a
`NotAllowedError` after the user has already picked the passkey and confirmed. A modal request
for the same credential without any extension succeeded in the same session._

Gate the feature on the capability check and you skip the calls Google Password Manager would
have executed. Trust the resolved promise instead and you record twelve successes where you got
one. Nothing in the return value separates the provider that acted from the eleven that did
not.

![Google Password Manager entry with the display name changed to L3 renamed 16:58:05 while the username stays l3-test@corbado.com](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/05_gpm_signal_rename_proof_23e8f6c394.png)

_The display name in Google Password Manager carries the value we sent through
`signalCurrentUserDetails`, on a client that had reported the capability as `false` a minute
earlier._

The silent no-op is the more dangerous of the two, because nothing in the API distinguishes it
from success. A signal call that resolves without an error shows only that the browser accepted
it, and there is no return value to inspect. Where revocation is
part of your security model, verify it in the credential manager during testing instead of
trusting the resolved promise, and keep a server-side path that does not depend on the signal
arriving.

## 7. How we checked this

The measurements were taken in August 2026. The method is documented here because it
determines how much weight a single cell can carry.

- **Our own tests** ran on macOS 26.3 with Safari 26.3 and Chrome 150 and 151, and on Windows
  11 with Chrome 151 for Windows Hello, with each credential manager set as the active provider one
  at a time. PRF was measured against our
  public [PRF demo](https://webauthn-passkeys-prf-demo.explore.corbado.com/), the other
  features against a test page that registers a passkey, reads the AAGUID to prove which
  provider answered and then runs conditional create, conditional UI, a largeBlob write and
  read, then the three signal methods in that order.
- **PRF is compared against one credential and not one provider.** The value from
  registration only means something next to the value from an authentication with the same
  credential. In an early Enpass run the vault held a second passkey created by the
  conditional-create step, the two values came back different and the obvious reading was that
  Enpass derives PRF non-deterministically. Repeating the run with a single credential in the
  vault returned the identical value. We report the second run, and the first one is the reason
  this bullet exists.
- **Every run is tied to one provider by its AAGUID.** A dialog that falls back to the provider
  shipped with the OS is the easiest way to mislabel a whole row, so the page compares the
  AAGUID against the manager under test and voids the run when the two differ.
- **Community results and vendor documentation** cover the combinations we cannot reach
  ourselves. The community numbers are per-attempt success rates from small samples and
  indicate a tendency and no more. Vendor documentation about the vault says nothing about what
  the provider returns to your site. Where we can run the combination ourselves, our own result
  takes precedence over both.
- **Each feature is documented on exactly one page.** The matrix carries one symbol per
  provider and feature; the feature article carries the browser and OS detail behind it. When a
  status changes, the feature article is updated first and the matrix follows, so the two
  cannot drift apart.
- **A resolved conditional create is not proof that it was silent.** The API returns a
  credential either way, and nothing in the response says whether the provider put a window in
  front of the user. NordPass exposed this: the ceremony succeeded and the page reported a
  silent creation, while NordPass had opened its own dialog and waited for a click. We caught it
  because someone was watching the screen. For the providers in the ✅ column we recorded the
  result and not the presence of a dialog, so read that cell as "the ceremony went through" and
  verify the silence yourself if your flow depends on it.
- **Conditional create needs a saved password to be measurable.** The ceremony upgrades an
  existing password entry, so a manager that holds none for the origin answers with a
  `NotAllowedError` whether or not it supports the feature. A silent creation is proof of
  support; a rejection only counts once the manager demonstrably holds a password for the
  origin. Every ❌ in that column comes from a run that met the second condition.
- **Open cells stay open.** A cell without a test result or a clear vendor statement keeps its
  ❓. An incorrect ✅ in a table like this can cost a team weeks of implementation work.

![Summary of one test run: provider Google Password Manager, PRF at creation yes, largeBlob supported, written and read back, conditional create rejected, conditional UI returned a credential, all three signal calls accepted while the capability reported false](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/04_gpm_run_summary_2dc808e6e0.jpg)

_One complete run, Google Password Manager on macOS 26.3 with Chrome 151. The blob written in
one ceremony returns byte for byte in the next, and the three signal rows show the
contradiction between the reported capability and the observed behaviour._

**Update rhythm.** We review this page quarterly, and additionally when a browser ships a
Level 3 feature, a credential manager announces one, a vendor sends us a correction or our
own field data contradicts a cell. Each review updates the status date even when nothing
changed, so you can see how old the answer is.

**Last checked: August 2026. Next scheduled review: November 2026.**

If you maintain a credential manager and a row here is wrong or outdated, tell us and we will
retest it. We would rather publish your result than our guess.

## 8. How Corbado can help

This matrix is hard to build from the outside because the relevant behaviour occurs in
production, on devices you do not own, with providers you did not choose.

[Corbado Observe](https://www.corbado.com/observe) turns that into data from your own login:

[Video: Authenticator inventory](https://www.corbado.com/videos/features/authenticator-inventory.mp4) ([See Authenticator Inventory in Corbado Observe](https://www.corbado.com/observe/authenticator-inventory))

- **Authenticator inventory:** see [which providers](https://www.corbado.com/observe/authenticator-inventory) your
  users bring, identified by AAGUID, instead of estimating from market share.
- **Capability outcomes:** conditional create, conditional UI, hybrid transport and signal
  support show up as real outcomes in the login flow, per platform and per provider.
- **Error root cause:** when a feature returns nothing without an error,
  [the failing step](https://www.corbado.com/observe/passkey-errors) is the starting point for debugging.
- **Per-user reconstruction:** [replay a single session](https://www.corbado.com/observe/user-debugging) when a
  customer reports that passkeys "do not work" with their credential manager.

That is also how the open cells in the matrix will be filled: with outcomes from real traffic
rather than with vendor claims.

## 9. Conclusion

The browser and OS view of passkey support is well documented, and it is no longer sufficient
on its own. The credential manager decides whether PRF returns a value, whether a silent
upgrade runs and whether a revocation ever reaches the user's credential list.

Version 1 has more open cells than closed ones, which is an accurate picture of the ecosystem.
We close them by testing what we can reach and asking the vendors for the rest.

## Frequently Asked Questions

### Which WebAuthn features depend on the credential manager?

The PRF extension, conditional create, conditional UI, largeBlob and the Signal API all need
the credential manager to implement them. Related origin requests and getClientCapabilities
are browser and relying party features, while credProtect, credBlob, minPinLength and
enterprise attestation are properties of security keys rather than of a software credential
manager.

### Why does the same passkey feature work for one user and not for another?

Because the credential manager decides, and the same manager can behave differently per
platform. Bitwarden returns PRF values on Linux with Firefox and nothing on iOS with Safari,
so a single answer per vendor would be wrong. Detect the capability at runtime instead of
inferring it from the product name.

### What should a relying party do when the credential manager lacks a feature?

Detect the capability instead of the provider, keep a working path for the case where the
feature is missing and do not ask the user to switch credential managers. Falling back to the
provider shipped with the operating system is technically sound, and vendors report that users
who installed their own manager read it as a downgrade, most often in Japan and Germany.

### How did you determine the support status?

Own tests on macOS 26.3 with Safari 26.3 and Chrome 150 and 151, the anonymous community
results from our public PRF demo and vendor documentation where it is public and specific.
Every cell carries a date and its source, and a cell with neither a test result nor a clear
statement stays open.
