Skip to main content
In addition to the reference documentation below, check out our end-to-end guide on how to implement passkeys in web apps using Authsignal.

Creating a passkey

Creating a passkey must be authorized by presenting a challenge with an existing method or tracking an action to obtain a short-lived token.
const response = await authsignal.passkey.signUp({
  token: "eyJhbGciOiJ...",
  username: "jane.smith@authsignal.com",
  displayName: "Jane Smith",
});

Parameters

token
string
A short-lived token obtained by tracking an action.
username
string
The primary user identifier associated with the passkey, e.g. the user’s email address.
displayName
string
An optional secondary user identifier which the browser may display in place of or alongside the username, e.g. the user’s full name.
useAutoRegister
boolean
Whether to use the automatic passkey upgrade flow. If true, the user’s password manager will be prompted to automatically create a passkey after successful authentication via password autofill.

Response

response
AuthsignalResponse<SignUpResponse>

Automatic passkey upgrades

Automatic passkey upgrades are currently only supported by Safari on macOS and iOS, and Chrome on desktop.
With passkey upgrades, your app can prompt your user’s password manager to automatically create a passkey. This works provided the user has a password saved for your app in their password manager and has recently authenticated with it. To enable this, you must set the useAutoRegister parameter to true when calling signUp.
const response = await authsignal.passkey.signUp({
  token: "eyJhbGciOiJ...",
  username: "jane.smith@authsignal.com",
  displayName: "Jane Smith",
  useAutoRegister: true,
});

Example usage

async function onSubmit(formData) {
  // Validate user on BE and return a token from `track`

  // If valid user, attempt to automatically create a passkey
  try {
    const response = await authsignal.passkey.signUp({
      token: "eyJhbGciOiJ...", // Token from `track`
      username: "jane.smith@authsignal.com",
      displayName: "Jane Smith",
      useAutoRegister: true,
    });
  } catch (error) {
    // Failed to automatically create a passkey
    console.error(error);
  }

  // Continue with post-sign-in flow
  window.location.href = "/dashboard";
}

Using a passkey

Calling signIn will present the passkey sign-in prompt. If the user successfully authenticates with their passkey, send the result token to your server to validate the challenge.
const response = await authsignal.passkey.signIn({ action: "signInWithPasskey" });

if (response.data?.token) {
  // Send the response token to your server to validate the result of the challenge
}
Check out our best practice guide for passkeys on web browsers for tips on how to implement an optimal passkey UX and avoid leading users into dead ends.

Parameters

action
string
A string which determines how the action associated with the passkey sign-in attempt will be named in the Authsignal Portal. Values are validated with the following regex: ^[a-zA-Z0-9_-]{(1, 64)}$.

Response

response
AuthsignalResponse<SignInResponse>

Using passkey autofill

This feature requires rendering a text input with the attribute autocomplete="username webauthn":
<input type="text" id="username" autocomplete="username webauthn" />
It can also be added to a password input:
<input type="password" id="password" autocomplete="current-password webauthn" />
The webauthn value must be the last value in the autocomplete attribute, otherwise the browser will not autofill the passkey.
Then when the page loads you should initialize the input for passkey autofill by running the following code.
authsignal.passkey
  .signIn({
    action: "signInWithPasskeyAutofill",
    autofill: true,
  })
  .then((response) => {
    if (response.data?.token) {
      // The user has focused your text input and authenticated with an existing passkey
      // Send the response token to your server to validate the result of the challenge
    }
  });

Passkey error handling

When any of the underlying native browser WebAuthn APIs fail, the SDK will throw a WebAuthnError. Most of these errors are benign and can be safely ignored. However, if you wish to handle them, you can do so by catching the error in a try/catch block. Common errors you will encounter during passkey authentication are:
  • ERROR_CEREMONY_ABORTED - The user cancelled the passkey ceremony. We recommend ignoring this error as it’s a normal part of the user experience.
  • ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED - The user already has a passkey registered for this authenticator (exclusive to signUp). For example, the user is trying to create an iCloud Keychain passkey but already has one registered in iCloud Keychain.
During development, you may also encounter ERROR_INVALID_RP_ID which occurs when the relying party ID is invalid for the domain.
import { WebAuthnError } from "@authsignal/browser";

try {
  const response = await authsignal.passkey.signUp({
    token: "eyJhbGciOiJ...",
    username: "jane.smith@authsignal.com",
    displayName: "Jane Smith",
  });
} catch (error) {
  if (error instanceof WebAuthnError) {
    if (error.code === "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED") {
      // The user already has a passkey registered for this authenticator
      // You can choose to handle this however you see fit
    }
  }
}