CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-simplewebauthn--browser

A comprehensive TypeScript library providing both client-side and server-side WebAuthn functionality for implementing passwordless authentication with passkeys and other WebAuthn-compatible authenticators

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

SimpleWebAuthn

SimpleWebAuthn is a comprehensive TypeScript library providing both client-side and server-side WebAuthn functionality for implementing passwordless authentication with passkeys and other WebAuthn-compatible authenticators. It consists of two complementary packages that work together to provide a complete WebAuthn implementation.

Package Information

  • Package Name: @simplewebauthn/browser and @simplewebauthn/server
  • Package Type: npm (also available on JSR for Deno)
  • Language: TypeScript
  • Installation:
    • Browser: npm install @simplewebauthn/browser or deno add jsr:@simplewebauthn/browser
    • Server: npm install @simplewebauthn/server or deno add jsr:@simplewebauthn/server

Core Imports

Browser Package:

import {
  startRegistration,
  startAuthentication,
  browserSupportsWebAuthn,
  platformAuthenticatorIsAvailable,
  browserSupportsWebAuthnAutofill,
  type RegistrationResponseJSON,
  type AuthenticationResponseJSON,
} from "@simplewebauthn/browser";

Server Package:

import {
  generateRegistrationOptions,
  verifyRegistrationResponse,
  generateAuthenticationOptions,
  verifyAuthenticationResponse,
  MetadataService,
  SettingsService,
} from "@simplewebauthn/server";

// Server helpers for advanced use cases
import {
  generateChallenge,
  generateUserID,
  convertAAGUIDToString,
  decodeAttestationObject,
  parseAuthenticatorData,
  isoBase64URL,
  isoUint8Array,
} from "@simplewebauthn/server/helpers";

Basic Usage

Complete Registration and Authentication Flow:

// === CLIENT SIDE (Browser) ===
import { 
  startRegistration, 
  startAuthentication, 
  browserSupportsWebAuthn 
} from "@simplewebauthn/browser";

// Check WebAuthn support
if (!browserSupportsWebAuthn()) {
  console.log("WebAuthn not supported");
  return;
}

// Registration
const registrationOptions = await fetch("/webauthn/register/begin").then(r => r.json());
const registrationResponse = await startRegistration({
  optionsJSON: registrationOptions,
});
await fetch("/webauthn/register/finish", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(registrationResponse),
});

// Authentication  
const authOptions = await fetch("/webauthn/authenticate/begin").then(r => r.json());
const authResponse = await startAuthentication({
  optionsJSON: authOptions,
});
await fetch("/webauthn/authenticate/finish", {
  method: "POST", 
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(authResponse),
});

// === SERVER SIDE ===
import {
  generateRegistrationOptions,
  verifyRegistrationResponse,
  generateAuthenticationOptions,
  verifyAuthenticationResponse,
} from "@simplewebauthn/server";

// Registration endpoints
app.post('/webauthn/register/begin', async (req, res) => {
  const options = await generateRegistrationOptions({
    rpName: "My App",
    rpID: "example.com",
    userName: req.user.email,
    userDisplayName: req.user.name,
  });
  req.session.challenge = options.challenge;
  res.json(options);
});

app.post('/webauthn/register/finish', async (req, res) => {
  const verification = await verifyRegistrationResponse({
    response: req.body,
    expectedChallenge: req.session.challenge,
    expectedOrigin: "https://example.com",
  });
  
  if (verification.verified) {
    // Save credential to database
    res.json({ verified: true });
  }
});

// Authentication endpoints  
app.post('/webauthn/authenticate/begin', async (req, res) => {
  const options = await generateAuthenticationOptions({
    rpID: "example.com",
  });
  req.session.challenge = options.challenge;
  res.json(options);
});

app.post('/webauthn/authenticate/finish', async (req, res) => {
  const verification = await verifyAuthenticationResponse({
    response: req.body,
    expectedChallenge: req.session.challenge,
    expectedOrigin: "https://example.com",
    credential: storedCredential,
  });
  
  if (verification.verified) {
    // User authenticated
    res.json({ verified: true });
  }
});

Architecture

SimpleWebAuthn is built around several key components:

Browser Package:

  • Core WebAuthn Methods: High-level startRegistration and startAuthentication functions
  • Browser Detection: Capability detection for WebAuthn support and platform authenticators
  • Data Encoding Utilities: Base64URL conversion for handling WebAuthn's ArrayBuffer data
  • Error Handling: Comprehensive error classification with WebAuthnError
  • Abort Service: Request management for concurrent WebAuthn operations

Server Package:

  • Options Generation: Functions to create WebAuthn ceremony options
  • Response Verification: Functions to verify client responses and attestations
  • Metadata Service: FIDO Metadata Service integration for authenticator validation
  • Settings Service: Configuration management for root certificates and attestation formats
  • Type System: Complete TypeScript definitions for all WebAuthn interfaces

Capabilities

Browser Package Capabilities

WebAuthn Registration

Handles the complete WebAuthn registration flow on the client side.

function startRegistration(options: {
  optionsJSON: PublicKeyCredentialCreationOptionsJSON;
  useAutoRegister?: boolean;
}): Promise<RegistrationResponseJSON>;

WebAuthn Registration

WebAuthn Authentication

Handles the complete WebAuthn authentication flow with support for conditional UI.

function startAuthentication(options: {
  optionsJSON: PublicKeyCredentialRequestOptionsJSON;
  useBrowserAutofill?: boolean;
  verifyBrowserAutofillInput?: boolean;
}): Promise<AuthenticationResponseJSON>;

WebAuthn Authentication

Browser Support Detection

Functions to detect WebAuthn capabilities and browser support.

function browserSupportsWebAuthn(): boolean;
function platformAuthenticatorIsAvailable(): Promise<boolean>;
function browserSupportsWebAuthnAutofill(): Promise<boolean>;

Browser Support Detection

Data Encoding Utilities

Utilities for converting between Base64URL strings and ArrayBuffers.

function base64URLStringToBuffer(base64URLString: string): ArrayBuffer;
function bufferToBase64URLString(buffer: ArrayBuffer): string;

Data Encoding Utilities

Error Handling and Services

Comprehensive error handling and abort service for managing operations.

class WebAuthnError extends Error {
  code: WebAuthnErrorCode;
  constructor(options: {
    message: string;
    code: WebAuthnErrorCode;
    cause: Error;
    name?: string;
  });
}

interface WebAuthnAbortService {
  createNewAbortSignal(): AbortSignal;
  cancelCeremony(): void;
}

Error Handling and Services

Server Package Capabilities

Registration Options Generation

Server-side functions for generating WebAuthn registration options.

function generateRegistrationOptions(options: {
  rpName: string;
  rpID: string;
  userName: string;
  userID?: Uint8Array;
  challenge?: string | Uint8Array;
  userDisplayName?: string;
  timeout?: number;
  attestationType?: 'direct' | 'enterprise' | 'none';
  excludeCredentials?: {
    id: Base64URLString;
    transports?: AuthenticatorTransportFuture[];
  }[];
  authenticatorSelection?: AuthenticatorSelectionCriteria;
  extensions?: AuthenticationExtensionsClientInputs;
  supportedAlgorithmIDs?: COSEAlgorithmIdentifier[];
  preferredAuthenticatorType?: 'securityKey' | 'localDevice' | 'remoteDevice';
}): Promise<PublicKeyCredentialCreationOptionsJSON>;

Registration Response Verification

Server-side functions for verifying WebAuthn registration responses.

function verifyRegistrationResponse(options: {
  response: RegistrationResponseJSON;
  expectedChallenge: string | ((challenge: string) => boolean | Promise<boolean>);
  expectedOrigin: string | string[];
  expectedRPID?: string | string[];
  expectedType?: string | string[];
  requireUserPresence?: boolean;
  requireUserVerification?: boolean;
  supportedAlgorithmIDs?: COSEAlgorithmIdentifier[];
}): Promise<VerifiedRegistrationResponse>;

Authentication Options Generation

Server-side functions for generating WebAuthn authentication options.

function generateAuthenticationOptions(options: {
  rpID: string;
  allowCredentials?: {
    id: Base64URLString;
    transports?: AuthenticatorTransportFuture[];
  }[];
  challenge?: string | Uint8Array;
  timeout?: number;
  userVerification?: 'required' | 'preferred' | 'discouraged';
  extensions?: AuthenticationExtensionsClientInputs;
}): Promise<PublicKeyCredentialRequestOptionsJSON>;

Authentication Response Verification

Server-side functions for verifying WebAuthn authentication responses.

function verifyAuthenticationResponse(options: {
  response: AuthenticationResponseJSON;
  expectedChallenge: string | ((challenge: string) => boolean | Promise<boolean>);
  expectedOrigin: string | string[];
  expectedRPID?: string | string[];
  credential: {
    id: Base64URLString;
    publicKey: Uint8Array;
    counter: number;
    transports?: AuthenticatorTransportFuture[];
  };
  requireUserPresence?: boolean;
  requireUserVerification?: boolean;
  advancedFIDOConfig?: {
    userVerification?: 'required' | 'preferred' | 'discouraged';  
  };
}): Promise<VerifiedAuthenticationResponse>;

Metadata and Settings Services

Services for managing authenticator metadata and root certificates.

interface MetadataService {
  initialize(options?: {
    verificationMode?: VerificationMode;
    mdsServers?: string[];
    statements?: MetadataStatement[];
  }): Promise<void>;
  getStatement(aaguid: string): Promise<MetadataStatement | undefined>;
  getStatements(): Promise<MetadataStatement[]>;
}

interface SettingsService {
  setRootCertificates(opts: {
    identifier: RootCertIdentifier;
    certificates: (Uint8Array | string)[];
  }): void;
  getRootCertificates(opts: {
    identifier: RootCertIdentifier;
  }): string[];
}

Server Package Documentation

Types

Response Types

interface RegistrationResponseJSON {
  id: Base64URLString;
  rawId: Base64URLString;
  response: AuthenticatorAttestationResponseJSON;
  authenticatorAttachment?: AuthenticatorAttachment;
  clientExtensionResults: AuthenticationExtensionsClientOutputs;
  type: PublicKeyCredentialType;
}

interface AuthenticationResponseJSON {
  id: Base64URLString;
  rawId: Base64URLString;
  response: AuthenticatorAssertionResponseJSON;
  authenticatorAttachment?: AuthenticatorAttachment;
  clientExtensionResults: AuthenticationExtensionsClientOutputs;
  type: PublicKeyCredentialType;
}

Options Types

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 PublicKeyCredentialRequestOptionsJSON {
  challenge: Base64URLString;
  timeout?: number;
  rpId?: string;
  allowCredentials?: PublicKeyCredentialDescriptorJSON[];
  userVerification?: UserVerificationRequirement;
  hints?: PublicKeyCredentialHint[];
  extensions?: AuthenticationExtensionsClientInputs;
}

Verification Response Types

interface VerifiedRegistrationResponse {
  verified: boolean;
  registrationInfo?: {
    fmt: AttestationFormat;
    counter: number;
    aaguid: string;
    credentialID: Uint8Array;
    credentialPublicKey: Uint8Array;
    userVerified: boolean;
    credentialDeviceType: CredentialDeviceType;
    credentialBackedUp: boolean;
  };
}

interface VerifiedAuthenticationResponse {
  verified: boolean;
  authenticationInfo?: {
    newCounter: number;
    userVerified: boolean;
    credentialDeviceType: CredentialDeviceType;
    credentialBackedUp: boolean;
  };
}

Utility Types

type Base64URLString = string;

type AuthenticatorTransportFuture =
  | 'ble'
  | 'cable'
  | 'hybrid'
  | 'internal'
  | 'nfc'
  | 'smart-card'
  | 'usb';

type WebAuthnErrorCode =
  | 'ERROR_CEREMONY_ABORTED'
  | 'ERROR_INVALID_DOMAIN'
  | 'ERROR_INVALID_RP_ID'
  | 'ERROR_INVALID_USER_ID_LENGTH'
  | 'ERROR_MALFORMED_PUBKEYCREDPARAMS'
  | 'ERROR_AUTHENTICATOR_GENERAL_ERROR'
  | 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT'
  | 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT'
  | 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED'
  | 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG'
  | 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE'
  | 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY';

type CredentialDeviceType = 'singleDevice' | 'multiDevice';

type PublicKeyCredentialHint = 'hybrid' | 'security-key' | 'client-device';

type AttestationFormat =
  | 'fido-u2f'
  | 'packed'
  | 'android-safetynet'
  | 'android-key'
  | 'tpm'
  | 'apple'
  | 'none';

type VerificationMode = 'permissive' | 'strict';

type RootCertIdentifier = AttestationFormat | 'mds';

docs

authentication.md

browser-support.md

data-encoding.md

error-handling.md

index.md

registration.md

server.md

tile.json