From d0d867318c799446b62cf0ee4024e07e768a1a23 Mon Sep 17 00:00:00 2001 From: StealthEyeLLC <247854506+StealthEyeLLC@users.noreply.github.com> Date: Sat, 4 Jul 2026 22:22:50 +0000 Subject: [PATCH] docs: document WebAuthn conditional create --- .../api/credentialscontainer/create/index.md | 37 +++++++++++++++++++ .../getclientcapabilities_static/index.md | 3 +- .../web/api/web_authentication_api/index.md | 31 ++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/files/en-us/web/api/credentialscontainer/create/index.md b/files/en-us/web/api/credentialscontainer/create/index.md index ec2623f0bffe661..fee1632c105061f 100644 --- a/files/en-us/web/api/credentialscontainer/create/index.md +++ b/files/en-us/web/api/credentialscontainer/create/index.md @@ -31,6 +31,8 @@ create(options) - : An object that contains options for the requested new `Credentials` object. It can contain the following properties: - `signal` {{optional_inline}} - : An {{domxref("AbortSignal")}} object instance that allows an ongoing `create()` operation to be aborted. An aborted operation may complete normally (generally if the abort was received after the operation finished) or reject with an `AbortError` {{domxref("DOMException")}}. + - `mediation` {{optional_inline}} + - : A string indicating how user mediation should be handled for the credential creation request. For public key credentials, a value of `"conditional"` requests [automatic passkey creation](#creating_a_passkey_conditionally) when the user agent and passkey provider support it, and the user has recently signed in with a saved password. Each of the following properties represents a _credential type_ being created. One and only one of them must be specified: - `federated` {{optional_inline}} @@ -169,6 +171,41 @@ Some of this data will need to be stored on the server for future authentication > [!NOTE] > See [Creating a key pair and registering a user](/en-US/docs/Web/API/Web_Authentication_API#creating_a_key_pair_and_registering_a_user) for more information about how the overall flow works. +### Creating a passkey conditionally + +_Automatic passkey creation_, also known as _conditional create_, lets a relying party (RP) request passkey creation without requiring the user to explicitly choose a "create a passkey" control. +It is intended to help users upgrade from passwords to passkeys: for example, a site can call `create()` with `mediation: "conditional"` immediately after the user signs in successfully with a saved password. + +Before requesting conditional creation, check whether the WebAuthn client supports the feature using {{domxref("PublicKeyCredential.getClientCapabilities_static", "PublicKeyCredential.getClientCapabilities()")}}: + +```js +let conditionalCreateAvailable = false; + +if (window.PublicKeyCredential?.getClientCapabilities) { + const capabilities = await PublicKeyCredential.getClientCapabilities(); + conditionalCreateAvailable = capabilities.conditionalCreate === true; +} +``` + +If the feature is supported, pass `mediation: "conditional"` in the `create()` call, alongside the usual `publicKey` creation options supplied by your server: + +```js +if (conditionalCreateAvailable) { + const publicKeyCredential = await navigator.credentials.create({ + publicKey, + mediation: "conditional", + }); + + // Send publicKeyCredential to the server to complete registration. +} +``` + +A conditional creation request can fail when the user agent or selected passkey provider cannot satisfy the request — for example, if the user did not recently sign in using a saved password, or if a matching passkey already exists. +Handle those failures silently and continue the signed-in session without interrupting the user. + +> [!NOTE] +> If your sign-in page has an ongoing conditional {{domxref("CredentialsContainer.get()", "get()")}} request for passkey autofill, abort it before starting conditional creation. Only one WebAuthn operation can be active at a time. + ## Specifications {{Specifications}} diff --git a/files/en-us/web/api/publickeycredential/getclientcapabilities_static/index.md b/files/en-us/web/api/publickeycredential/getclientcapabilities_static/index.md index 3430b75c93bb918..0066449e36a9d19 100644 --- a/files/en-us/web/api/publickeycredential/getclientcapabilities_static/index.md +++ b/files/en-us/web/api/publickeycredential/getclientcapabilities_static/index.md @@ -29,7 +29,7 @@ A {{jsxref("Promise")}} that resolves to an object where the property names are The WebAuthn client capability strings are: - `"conditionalCreate"` - - : The client is capable of creating [discoverable credentials](/en-US/docs/Web/API/Web_Authentication_API#discoverable_and_non-discoverable_credentials). + - : The client is capable of [automatic passkey creation](/en-US/docs/Web/API/Web_Authentication_API#automatic_passkey_creation) using {{domxref("CredentialsContainer.create()")}} with `mediation: "conditional"`. - `"conditionalGet"` - : The client is capable of [conditional mediation](/en-US/docs/Web/API/Web_Authentication_API#autofill_ui). This capability is equivalent to [`isConditionalMediationAvailable()`](/en-US/docs/Web/API/PublicKeyCredential/isConditionalMediationAvailable_static) resolving to `true`. @@ -75,6 +75,7 @@ For example, support for the `userVerifyingPlatformAuthenticator` capability ind A web application could use this to display a fingerprint icon if the capability is supported, or a password input if it is not. If biometric login is required, then it could instead provide notification that the site cannot authenticate using this browser or device. Similarly, `conditionalGet` indicates that the client supports conditional mediation when signing in a user, which means the browser can provide auto-filled discoverable credentials in a login form (for example an autocompleting text field or a drop-down list), along with a sign-in button. +The `conditionalCreate` capability indicates support for conditional creation, which means a website can request passkey creation after a successful password sign-in by calling {{domxref("CredentialsContainer.create()")}} with `mediation: "conditional"`. If the value of a given capability is present in the returned object, then `true` indicates that the capability is currently supported, and `false` indicates that it is not. However, if a key is not present for a particular capability, no assumptions can be made about the availability of the associated feature. diff --git a/files/en-us/web/api/web_authentication_api/index.md b/files/en-us/web/api/web_authentication_api/index.md index 83722e10457c771..a426c72410c6cbc 100644 --- a/files/en-us/web/api/web_authentication_api/index.md +++ b/files/en-us/web/api/web_authentication_api/index.md @@ -205,6 +205,37 @@ This essentially enables a website to provide a unified autofill, including both > [!NOTE] > Note that only [discoverable credentials](#discoverable_and_non-discoverable_credentials) are included in calls that use conditional mediation, because the browser needs to request applicable credentials without knowing the credential ID values for them. +### Automatic passkey creation + +Automatic passkey creation, also known as _conditional create_, lets an RP ask the browser to create a passkey after the user has already signed in with a password. +This can reduce passkey adoption friction: the user signs in as usual, and the browser can create a passkey when the user agent and passkey provider determine that the request is appropriate. + +Use {{domxref("PublicKeyCredential.getClientCapabilities_static", "PublicKeyCredential.getClientCapabilities()")}} to check for the `conditionalCreate` capability before offering this flow. +If it is supported, call {{domxref("CredentialsContainer.create()")}} with: + +- The usual [`publicKey`](/en-US/docs/Web/API/CredentialsContainer/create#publickey) creation options from the RP server. +- [`mediation: "conditional"`](/en-US/docs/Web/API/CredentialsContainer/create#mediation). + +```js +if (window.PublicKeyCredential?.getClientCapabilities) { + const capabilities = await PublicKeyCredential.getClientCapabilities(); + + if (capabilities.conditionalCreate) { + const credential = await navigator.credentials.create({ + publicKey: optionsFromServer, + mediation: "conditional", + }); + + // Send the credential to the server to complete registration. + } +} +``` + +Call this flow soon after a successful password-based sign-in, while the user is still signed in. +Conditional creation may fail if the required conditions are not met, so handle failures without showing errors to the user. + +If the page also started a conditional {{domxref("CredentialsContainer.get()")}} request for [autofill UI](#autofill_ui), abort the `get()` request before calling `create()`. + ### Discoverable credential synchronization methods It is possible for the information stored in a user's authenticator about a discoverable credential to go out sync with the relying party's server. This might happen when the user deletes a credential or modifies their user/display name on the RP web app without updating the authenticator.