or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

authentication.mdbrowser-support.mddata-encoding.mderror-handling.mdindex.mdregistration.mdserver.md
tile.json

authentication.mddocs/

WebAuthn Authentication

WebAuthn authentication functionality for logging in users with previously registered authenticators, including support for conditional UI (browser autofill) and multi-device authentication scenarios.

Capabilities

Start Authentication

Begin authenticator login via WebAuthn assertion ceremony.

/**
 * Begin authenticator "login" via WebAuthn assertion
 * @param options Configuration object containing authentication options and settings
 * @returns Promise resolving to authentication response suitable for server verification
 */
function startAuthentication(options: {
  optionsJSON: PublicKeyCredentialRequestOptionsJSON;
  useBrowserAutofill?: boolean;
  verifyBrowserAutofillInput?: boolean;
}): Promise<AuthenticationResponseJSON>;

type StartAuthenticationOpts = Parameters<typeof startAuthentication>[0];

Parameters:

  • optionsJSON: Authentication options from your server's generateAuthenticationOptions() call
  • useBrowserAutofill: Optional boolean to initialize conditional UI for logging in via browser autofill prompts (defaults to false)
  • verifyBrowserAutofillInput: Optional boolean to ensure a suitable <input> element is present when useBrowserAutofill is true (defaults to true)

Usage Examples:

import { startAuthentication } from "@simplewebauthn/browser";

// Basic authentication
const authenticationOptions = await fetch("/webauthn/authenticate/begin").then(r => r.json());

try {
  const authenticationResponse = await startAuthentication({
    optionsJSON: authenticationOptions,
  });
  
  console.log("Authentication successful:", authenticationResponse);
  
  // Send to server for verification
  const verificationResponse = await fetch("/webauthn/authenticate/finish", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(authenticationResponse),
  });
} catch (error) {
  console.error("Authentication failed:", error);
}

// Authentication with browser autofill (conditional UI)
// First ensure you have an input with webauthn autocomplete
// <input type="text" autocomplete="username webauthn" />

try {
  const authenticationResponse = await startAuthentication({
    optionsJSON: authenticationOptions,
    useBrowserAutofill: true, // Enable autofill UI
  });
} catch (error) {
  if (error.message.includes("No <input> with")) {
    console.log("Missing required input element for autofill");
  }
}

// Skip input validation for autofill (advanced usage)
try {
  const authenticationResponse = await startAuthentication({
    optionsJSON: authenticationOptions,
    useBrowserAutofill: true,
    verifyBrowserAutofillInput: false, // Skip input validation
  });
} catch (error) {
  console.error("Authentication failed:", error);
}

Authentication Credential Type

The raw credential returned from navigator.credentials.get().

interface AuthenticationCredential extends PublicKeyCredentialFuture {
  response: AuthenticatorAssertionResponse;
}

interface PublicKeyCredentialFuture extends PublicKeyCredential {
  type: PublicKeyCredentialType;
  isConditionalMediationAvailable?(): Promise<boolean>;
  parseCreationOptionsFromJSON?(
    options: PublicKeyCredentialCreationOptionsJSON,
  ): PublicKeyCredentialCreationOptions;
  parseRequestOptionsFromJSON?(
    options: PublicKeyCredentialRequestOptionsJSON,
  ): PublicKeyCredentialRequestOptions;
  toJSON?(): PublicKeyCredentialJSON;
}

Authentication Response JSON

JSON-serializable authentication response with Base64URL-encoded ArrayBuffers.

/**
 * A slightly-modified AuthenticationCredential to simplify working with ArrayBuffers that
 * are Base64URL-encoded in the browser so that they can be sent as JSON to the server.
 */
interface AuthenticationResponseJSON {
  id: Base64URLString;
  rawId: Base64URLString;
  response: AuthenticatorAssertionResponseJSON;
  authenticatorAttachment?: AuthenticatorAttachment;
  clientExtensionResults: AuthenticationExtensionsClientOutputs;
  type: PublicKeyCredentialType;
}

interface AuthenticatorAssertionResponseJSON {
  clientDataJSON: Base64URLString;
  authenticatorData: Base64URLString;
  signature: Base64URLString;
  userHandle?: Base64URLString;
}

Authentication Options

Options for WebAuthn authentication ceremony.

/**
 * A variant of PublicKeyCredentialRequestOptions suitable for JSON transmission to the browser to
 * (eventually) get passed into navigator.credentials.get(...) in the browser.
 */
interface PublicKeyCredentialRequestOptionsJSON {
  challenge: Base64URLString;
  timeout?: number;
  rpId?: string;
  allowCredentials?: PublicKeyCredentialDescriptorJSON[];
  userVerification?: UserVerificationRequirement;
  hints?: PublicKeyCredentialHint[];
  extensions?: AuthenticationExtensionsClientInputs;
}

interface PublicKeyCredentialDescriptorJSON {
  id: Base64URLString;
  type: PublicKeyCredentialType;
  transports?: AuthenticatorTransportFuture[];
}

Browser Autofill Support

For conditional UI (autofill) authentication, you need a properly configured input element:

<!-- Required for browser autofill -->
<input type="text" autocomplete="username webauthn" />

<!-- Also works with -->
<input type="email" autocomplete="email webauthn" />

The input must have webauthn as the last or only value in its autocomplete attribute. The library will automatically detect and validate this requirement unless verifyBrowserAutofillInput is set to false.

Autofill Requirements:

  1. Browser must support conditional mediation (check with browserSupportsWebAuthnAutofill())
  2. Page must have an input with webauthn in its autocomplete attribute
  3. allowCredentials in options will be automatically cleared for conditional UI
  4. User interaction will be through browser's native autofill interface
import { 
  startAuthentication, 
  browserSupportsWebAuthnAutofill 
} from "@simplewebauthn/browser";

// Check support first
if (await browserSupportsWebAuthnAutofill()) {
  const response = await startAuthentication({
    optionsJSON: authOptions,
    useBrowserAutofill: true,
  });
}

Error Handling

Authentication can throw various WebAuthn-specific errors. Common error scenarios:

  • Browser not supported: Check with browserSupportsWebAuthn() first
  • User cancellation: User cancels the authentication prompt
  • No matching credentials: No registered authenticators found
  • Autofill not supported: Browser doesn't support conditional UI
  • Missing input element: Required autofill input not found
import { startAuthentication, WebAuthnError } from "@simplewebauthn/browser";

try {
  const response = await startAuthentication({ optionsJSON });
} catch (error) {
  if (error instanceof WebAuthnError) {
    switch (error.code) {
      case 'ERROR_CEREMONY_ABORTED':
        console.log("User cancelled authentication");
        break;
      case 'ERROR_INVALID_DOMAIN':
        console.log("Invalid domain for WebAuthn");
        break;
      default:
        console.log(`Authentication error: ${error.code}`);
    }
  } else if (error.message.includes("Browser does not support WebAuthn autofill")) {
    console.log("Autofill not supported, use regular authentication");
  } else if (error.message.includes("No <input> with")) {
    console.log("Missing required input for autofill");
  }
}