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

registration.mddocs/

WebAuthn Registration

WebAuthn registration functionality for creating and registering new authenticators (passkeys, security keys, platform authenticators) with support for automatic registration via password manager integration.

Capabilities

Start Registration

Begin authenticator registration via WebAuthn attestation ceremony.

/**
 * Begin authenticator "registration" via WebAuthn attestation
 * @param options Configuration object containing registration options and settings
 * @returns Promise resolving to registration response suitable for server verification
 */
function startRegistration(options: {
  optionsJSON: PublicKeyCredentialCreationOptionsJSON;
  useAutoRegister?: boolean;
}): Promise<RegistrationResponseJSON>;

type StartRegistrationOpts = Parameters<typeof startRegistration>[0];

Parameters:

  • optionsJSON: Registration options from your server's generateRegistrationOptions() call
  • useAutoRegister: Optional boolean to attempt silent passkey creation with the password manager the user just signed in with (defaults to false)

Usage Examples:

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

// Basic registration
const registrationOptions = await fetch("/webauthn/register/begin").then(r => r.json());

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

// Auto-registration with password manager
try {
  const registrationResponse = await startRegistration({
    optionsJSON: registrationOptions,
    useAutoRegister: true, // Try silent passkey creation
  });
} catch (error) {
  if (error.code === 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE') {
    console.log("Auto-registration failed, user needs manual interaction");
  }
}

Registration Credential Type

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

interface RegistrationCredential extends PublicKeyCredentialFuture {
  response: AuthenticatorAttestationResponseFuture;
}

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

interface AuthenticatorAttestationResponseFuture extends AuthenticatorAttestationResponse {
  getTransports(): AuthenticatorTransportFuture[];
}

Registration Response JSON

JSON-serializable registration response with Base64URL-encoded ArrayBuffers.

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

interface AuthenticatorAttestationResponseJSON {
  clientDataJSON: Base64URLString;
  attestationObject: Base64URLString;
  // Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
  authenticatorData?: Base64URLString;
  // Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
  transports?: AuthenticatorTransportFuture[];
  // Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
  publicKeyAlgorithm?: COSEAlgorithmIdentifier;
  publicKey?: Base64URLString;
}

Registration Options

Options for WebAuthn registration ceremony.

/**
 * A variant of PublicKeyCredentialCreationOptions suitable for JSON transmission to the browser to
 * (eventually) get passed into navigator.credentials.create(...) in the browser.
 */
interface PublicKeyCredentialCreationOptionsJSON {
  rp: PublicKeyCredentialRpEntity;
  user: PublicKeyCredentialUserEntityJSON;
  challenge: Base64URLString;
  pubKeyCredParams: PublicKeyCredentialParameters[];
  timeout?: number;
  excludeCredentials?: PublicKeyCredentialDescriptorJSON[];
  authenticatorSelection?: AuthenticatorSelectionCriteria;
  hints?: PublicKeyCredentialHint[];
  attestation?: AttestationConveyancePreference;
  attestationFormats?: AttestationFormat[];
  extensions?: AuthenticationExtensionsClientInputs;
}

interface PublicKeyCredentialUserEntityJSON {
  id: string;
  name: string;
  displayName: string;
}

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

Error Handling

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

  • Browser not supported: Check with browserSupportsWebAuthn() first
  • User cancellation: User cancels the registration prompt
  • Authenticator errors: Hardware issues or unsupported operations
  • Invalid options: Malformed registration options from server
  • Duplicate credential: Attempting to register an already-registered authenticator
import { startRegistration, WebAuthnError } from "@simplewebauthn/browser";

try {
  const response = await startRegistration({ optionsJSON });
} catch (error) {
  if (error instanceof WebAuthnError) {
    switch (error.code) {
      case 'ERROR_CEREMONY_ABORTED':
        console.log("User cancelled registration");
        break;
      case 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED':
        console.log("This authenticator is already registered");
        break;
      case 'ERROR_INVALID_DOMAIN':
        console.log("Invalid domain for WebAuthn");
        break;
      default:
        console.log(`Registration error: ${error.code}`);
    }
  }
}