Discover WebAuthn Level 3 client capabilities via getClientCapabilities() to improve passkey integration, enhance UX &streamline authentication flows.
Vincent
Created: October 16, 2024
Updated: February 17, 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 and 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.
Table of Contents
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.