Discover WebAuthn Level 3 client capabilities via getClientCapabilities() to improve passkey integration, enhance UX &streamline authentication flows.
Vincent
Created: October 16, 2024
Updated: May 27, 2025
Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.
WebAuthn is the modern standard behind passkeys. Instead of relying on traditional passwords, it leverages public-key cryptography, enabling users to authenticate with passkeys, which can include biometrics (like fingerprints or facial recognition) or physical security keys. This shift not only enhances security but also improves user experience by eliminating the need for password management.
The WebAuthn Level 3 standard introduces new client
capabilities (which can be retrieved via the browser API getClientCapabilities()
),
aimed at providing developers and platforms more control and flexibility when implementing
passkeys. These updates bring enhancements that simplify the process of integrating
passkeys across devices, browsers, and platforms, ensuring a smoother and more consistent
user journey.
In this blog post, we’ll be answering the following questions:
By the end, you'll understand how these features can help you create seamless, secure authentication flows that align with modern user expectations.
Recent Articles
đź“–
WebAuthn Signal API: Update & Delete Passkeys on Client-Side
đź“–
WebAuthn Conditional UI (Passkeys Autofill) Technical Explanation
đź“–
WebAuthn Passkey QR Codes & Bluetooth: Hybrid Transport
đź“–
WebAuthn Cross-Device-Authentication: Passkeys via Mobile-First Strategy
đź“–
WebAuthn User ID, User Handle, User Name & Credential ID
WebAuthn client capabilities are a set of features that allow browsers and platforms to communicate what types of WebAuthn functionalities they support. In simple terms, they act like a "feature checklist" that lets websites know which authentication methods and settings are available on a user’s device. This enables developers to tailor authentication flows based on the capabilities of the client, ensuring a smoother and more secure user experience.
For instance, if a browser signals that it supports biometric authentication (like Touch ID), developers can design their login flows to offer users the option to log in with a fingerprint. Conversely, if the browser does not support certain features, developers can provide fallback options, like a password or SMS OTP.
The WebAuthn Level 3 standard introduces several new
client capabilities that make passkey implementations more versatile and user-friendly.
The first support for the getClientCapabilities()
API call was introduced in Safari
17.4.
To detect support in the browser, the following snippet can be useful:
// Check if PublicKeyCredential is supported in the current browser if (typeof PublicKeyCredential === "undefined") { console.log("PublicKeyCredential is not supported in this browser."); } // Check if getClientCapabilities method exists on PublicKeyCredential if (typeof PublicKeyCredential.getClientCapabilities === "function") { try { let capabilities = await PublicKeyCredential.getClientCapabilities(); console.log(capabilities); } catch (error) { console.error("Error getting client capabilities:", error); } } else { console.log("getClientCapabilities is not supported in this browser"); }
getClientCapabilities()
allows websites and apps to query the client (e.g., browser or
device) to determine which WebAuthn features it supports. By understanding the client's
capabilities, developers can optimize authentication flows to leverage available features,
like biometric authentication, and provide
alternative methods if certain capabilities are absent.
Here’s a closer look at the WebAuthn client capabilities and how they impact passkey integration:
conditionalCreate
enables
automatic passkey creation based on
specific conditions. An application might use this capability to automatically create
passkey during password autofill if the
password manager has corresponding support. This
feature helps to boost passkey adoption and
subsequent usage by automatically transitioning users from passwords to passkeys.
Similar to conditionalCreate
, conditionalGet
triggers passkey logins automatically.
This is useful in scenarios where the best passkey UX should be enabled making the login
not only passwordless but also usernameless (users just click on the selected passkey in a
modal / dropdown and can authenticate). By using this capability, developers can ensure
passkey authentication only occurs when appropriate,
minimizing unnecessary prompts and enhancing user experience.
hybridTransport
ensures that passkeys can be used across different devices, enabling
seamless cross-device authentication (via QR codes and Bluetooth). For instance, a user
could use a passkey stored on their smartphone to log in to a service on their desktop.
This capability allows users to authenticate securely without the need to manually
transfer passkeys or rely on conventional login methods for each device, fostering a
unified authentication experience.
Platform authenticators, like Windows Hello, Face ID or Touch ID, are built directly into devices and offer a faster, smoother, and more secure passkey experience by enabling users to authenticate with biometrics or other device-native method (e.g. PIN pattern).
userVerifyingPlatformAuthenticator
ensures that
passkey authentication involves
user verification, such as an active fingerprint scan or
facial recognition, providing an extra layer of security.
The relatedOrigins
capability allows for seamless authentication across different
domains owned by the same organization (e.g. amazon.com and amazon.de). For instance, if a
company manages multiple domains or has different subdomains, users can log in once and
access all properties without re-authenticating on each. This capability streamlines the
user experience, reducing friction, and is especially valuable for enterprises in
international environments or with multi-service platforms.
The signalAllAcceptedCredentials(options)
method provides the complete list of
WebAuthn credential IDs for a given user. WebAuthn
Relying Parties should use this method over signalUnknownCredential()
when the user is
authenticated, as there is no risk of a privacy leak. This method offers a comprehensive
overview of a user’s public key credentials, including any recent changes that may not
have been updated on currently connected authenticators.
Let’s have a look at an example. A user (userId: A
) has 2 passkeys with Credential IDs
that Base64URL encode to X and Y. Then, the user deletes passkey X in the web service’s
(example.com
) account settings (so the public key is deleted). Now, run the following
snippet:
PublicKeyCredential.signalAllAcceptedCredentials({ rpId: "example.com", userId: "A", // WebAuthn User Handle, Base64URL. allAcceptedCredentialIds: ["Y"], });
If the authenticator is available at the time of the above code’s execution, then authenticator deletes or hides the passkey X from future authentication ceremonies. However, the authenticator may not be attached at the execution time, so it’s recommended that relying parties should periodically execute this code, e.g. on every sign in.
Passkeys not present in allAcceptedCredentialIds
will be removed or hidden, potentially
irreversibly. So, it’s important for relying parties to pay attention that valid WebAuthn
credential IDs are never removed from the list. If a valid
credential ID was accidentally remove, then the
relying party should immediately include it in another
signalAllAcceptedCredentials(options)
call as soon as possible to “unhide” the passkey.
If the passkey is not hidden but removed, then there’s nothing much to fix things.
The signalCurrentUserDetails(options)
method signlas the user’s current name and
WebAuthn Display Name. When signalCurrentUserDetails(options)
is called, the client
follows a set of defined steps to execute this action.
Let’s see an example. A user with WebAuthn User ID
A
updates their name in the account settings of a website (example.com
). Then, the
relying party can run the following code:
PublicKeyCredential.signalCurrentUserDetails({ rpId: "example.com", userId: "A", // user ID, Base64URL. name: "New user name", displayName: "New display name", });
The authenticator would then update the locally saved passkey’s metadata. The big benefit is that in future Conditional UI / passkey autofill requests, the Conditional UI selection / dropdown menu shows the updated name and WebAuthn Display Name.
The signalUnknownCredential(options)
method signals that a WebAuthn
Credential ID is not recognized by the WebAuthn
Relying Party, for instance, if the passkey was deleted by the user. Unlike
signalAllAcceptedCredentials(options)
, this method does not require providing the full
list of accepted credential IDs and the WebAuthn
User Handle, thereby preventing potential privacy
leaks to unauthenticated callers.
Let’s see an example. A user deletes a passkey with
credential ID X
on a website’s (example.com
)
account settings (so the public key is deleted). However, the private key is still
available on the user’s device. This means that in future
Conditional UI /
passkey autofill login requests (with
an empty allowCredentials
list), the passkey can be still selected. The login attempt
will fail though, as the public key is deleted already, so the
relying party should run:
PublicKeyCredential.signalUnknownCredential({ rpId: "example.com", credentialId: "X", // credential ID the user just tried, Base64URL });
The authenticator would then delete or hide passkey with
credential ID X
from future authentication
ceremonies.
As the WebAuthn Level 3 standard is still in draft status, adoption of these new client capabilities is not yet fully widespread. Different browsers have been gradually implementing these features, but support varies. Below is an updated overview of availability across the major browsers referenced above:
Browser | Version Supporting Client Capabilities | Notes |
---|---|---|
Chrome | 133 | Chrome Platform Status & Chromium Bug Tracker |
Safari | 17.4+ | First browser to ship getClientCapabilities(). As of October 2024, Safari supports features such as conditionalCreate , conditionalMediation , hybridTransport , passkeyPlatformAuthenticator , and userVerifyingPlatformAuthenticator . |
Edge | 133 | Based on Chromium 133. Chromium Bug Tracker |
Firefox | 135 | Mozilla has begun implementing WebAuthn Level 3 client capabilities in Firefox 135 and above. |
The pace of adoption will likely accelerate as Level 3 matures and more browsers ship
these features. If you want to see how many users can take advantage of
getClientCapabilities()
right now, you can check real-world data using the free
Passkeys Analyzer. Keep an eye on browser release
notes and relevant documentation to plan for broader compatibility as it evolves.
As a developer, you might ask yourself what these new WebAuthn client capability detection means for you and how you should use them in your app. In the following, you find recommendations to use them.
However, be aware that not all browsers yet support the getClientCapabilities()
API call
(as of November 2024). There is a polyfill available
here, that can be used until all
browsers catch-up.
Use getClientCapabilities()
early in your code to detect the client’s supported
features at the start of the page load / authentication flow. This will allow you to
customize the experience dynamically, and providing the
passkey features that work on the
device / browser, e.g. pushing for platform authentication when supported or offering
alternative methods (e.g., SMS OTPs or
hardware security keys) if not.
If you add passkeys to a website / app that currently uses passwords, the
conditionalCreate
feature can be a real booster for your
passkey adoption. In the background, during a
password autofill with a suitable credential manager ( only
Apple Passwords as of October 2024), a passkey is
automatically generated and will be preferred in future autofills.
To not only have a high passkey adoption, but also
a high passkey login usage, try to check if the
device / browser can use Conditional UI /
Passkey Autofill by checking for
conditionalGet
. This way you will nudge users to use the created passkey for logins, as
it’s proactively suggested by the operating system / browser and requires even less effort
than autofilling a password.
Utilize hybridTransport
to enable cross-device authentication (via
QR code and Bluetooth), allowing users to log in
seamlessly from their smartphone, even if they’re accessing your service on a desktop.
WebAuthn client capabilities represent a significant step forward in addressing currently existing passkey gaps. In this blog post, we addressed key questions about WebAuthn client capabilities:
getClientCapabilities
,
conditionalCreate
, hybridTransport
, and more.We encourage you to explore the new WebAuthn Level 3 features and stay updated on their adoption across browsers. If you’re looking to implement passkeys and take advantage of these advanced capabilities, reach out to us for expert guidance and support.
Enjoyed this read?
🤝 Join our Passkeys Community
Share passkeys implementation tips and get support to free the world from passwords.
🚀 Subscribe to Substack
Get the latest news, strategies, and insights about passkeys sent straight to your inbox.
Related Articles
Table of Contents