or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

index.mddocs/

0

# SimpleWebAuthn

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: @simplewebauthn/browser and @simplewebauthn/server

7

- **Package Type**: npm (also available on JSR for Deno)

8

- **Language**: TypeScript

9

- **Installation**:

10

- Browser: `npm install @simplewebauthn/browser` or `deno add jsr:@simplewebauthn/browser`

11

- Server: `npm install @simplewebauthn/server` or `deno add jsr:@simplewebauthn/server`

12

13

## Core Imports

14

15

**Browser Package:**

16

17

```typescript

18

import {

19

startRegistration,

20

startAuthentication,

21

browserSupportsWebAuthn,

22

platformAuthenticatorIsAvailable,

23

browserSupportsWebAuthnAutofill,

24

type RegistrationResponseJSON,

25

type AuthenticationResponseJSON,

26

} from "@simplewebauthn/browser";

27

```

28

29

**Server Package:**

30

31

```typescript

32

import {

33

generateRegistrationOptions,

34

verifyRegistrationResponse,

35

generateAuthenticationOptions,

36

verifyAuthenticationResponse,

37

MetadataService,

38

SettingsService,

39

} from "@simplewebauthn/server";

40

41

// Server helpers for advanced use cases

42

import {

43

generateChallenge,

44

generateUserID,

45

convertAAGUIDToString,

46

decodeAttestationObject,

47

parseAuthenticatorData,

48

isoBase64URL,

49

isoUint8Array,

50

} from "@simplewebauthn/server/helpers";

51

```

52

53

## Basic Usage

54

55

**Complete Registration and Authentication Flow:**

56

57

```typescript

58

// === CLIENT SIDE (Browser) ===

59

import {

60

startRegistration,

61

startAuthentication,

62

browserSupportsWebAuthn

63

} from "@simplewebauthn/browser";

64

65

// Check WebAuthn support

66

if (!browserSupportsWebAuthn()) {

67

console.log("WebAuthn not supported");

68

return;

69

}

70

71

// Registration

72

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

73

const registrationResponse = await startRegistration({

74

optionsJSON: registrationOptions,

75

});

76

await fetch("/webauthn/register/finish", {

77

method: "POST",

78

headers: { "Content-Type": "application/json" },

79

body: JSON.stringify(registrationResponse),

80

});

81

82

// Authentication

83

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

84

const authResponse = await startAuthentication({

85

optionsJSON: authOptions,

86

});

87

await fetch("/webauthn/authenticate/finish", {

88

method: "POST",

89

headers: { "Content-Type": "application/json" },

90

body: JSON.stringify(authResponse),

91

});

92

93

// === SERVER SIDE ===

94

import {

95

generateRegistrationOptions,

96

verifyRegistrationResponse,

97

generateAuthenticationOptions,

98

verifyAuthenticationResponse,

99

} from "@simplewebauthn/server";

100

101

// Registration endpoints

102

app.post('/webauthn/register/begin', async (req, res) => {

103

const options = await generateRegistrationOptions({

104

rpName: "My App",

105

rpID: "example.com",

106

userName: req.user.email,

107

userDisplayName: req.user.name,

108

});

109

req.session.challenge = options.challenge;

110

res.json(options);

111

});

112

113

app.post('/webauthn/register/finish', async (req, res) => {

114

const verification = await verifyRegistrationResponse({

115

response: req.body,

116

expectedChallenge: req.session.challenge,

117

expectedOrigin: "https://example.com",

118

});

119

120

if (verification.verified) {

121

// Save credential to database

122

res.json({ verified: true });

123

}

124

});

125

126

// Authentication endpoints

127

app.post('/webauthn/authenticate/begin', async (req, res) => {

128

const options = await generateAuthenticationOptions({

129

rpID: "example.com",

130

});

131

req.session.challenge = options.challenge;

132

res.json(options);

133

});

134

135

app.post('/webauthn/authenticate/finish', async (req, res) => {

136

const verification = await verifyAuthenticationResponse({

137

response: req.body,

138

expectedChallenge: req.session.challenge,

139

expectedOrigin: "https://example.com",

140

credential: storedCredential,

141

});

142

143

if (verification.verified) {

144

// User authenticated

145

res.json({ verified: true });

146

}

147

});

148

```

149

150

## Architecture

151

152

SimpleWebAuthn is built around several key components:

153

154

**Browser Package:**

155

- **Core WebAuthn Methods**: High-level `startRegistration` and `startAuthentication` functions

156

- **Browser Detection**: Capability detection for WebAuthn support and platform authenticators

157

- **Data Encoding Utilities**: Base64URL conversion for handling WebAuthn's ArrayBuffer data

158

- **Error Handling**: Comprehensive error classification with `WebAuthnError`

159

- **Abort Service**: Request management for concurrent WebAuthn operations

160

161

**Server Package:**

162

- **Options Generation**: Functions to create WebAuthn ceremony options

163

- **Response Verification**: Functions to verify client responses and attestations

164

- **Metadata Service**: FIDO Metadata Service integration for authenticator validation

165

- **Settings Service**: Configuration management for root certificates and attestation formats

166

- **Type System**: Complete TypeScript definitions for all WebAuthn interfaces

167

168

## Capabilities

169

170

### Browser Package Capabilities

171

172

#### WebAuthn Registration

173

Handles the complete WebAuthn registration flow on the client side.

174

175

```typescript { .api }

176

function startRegistration(options: {

177

optionsJSON: PublicKeyCredentialCreationOptionsJSON;

178

useAutoRegister?: boolean;

179

}): Promise<RegistrationResponseJSON>;

180

```

181

182

[WebAuthn Registration](./registration.md)

183

184

#### WebAuthn Authentication

185

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

186

187

```typescript { .api }

188

function startAuthentication(options: {

189

optionsJSON: PublicKeyCredentialRequestOptionsJSON;

190

useBrowserAutofill?: boolean;

191

verifyBrowserAutofillInput?: boolean;

192

}): Promise<AuthenticationResponseJSON>;

193

```

194

195

[WebAuthn Authentication](./authentication.md)

196

197

#### Browser Support Detection

198

Functions to detect WebAuthn capabilities and browser support.

199

200

```typescript { .api }

201

function browserSupportsWebAuthn(): boolean;

202

function platformAuthenticatorIsAvailable(): Promise<boolean>;

203

function browserSupportsWebAuthnAutofill(): Promise<boolean>;

204

```

205

206

[Browser Support Detection](./browser-support.md)

207

208

#### Data Encoding Utilities

209

Utilities for converting between Base64URL strings and ArrayBuffers.

210

211

```typescript { .api }

212

function base64URLStringToBuffer(base64URLString: string): ArrayBuffer;

213

function bufferToBase64URLString(buffer: ArrayBuffer): string;

214

```

215

216

[Data Encoding Utilities](./data-encoding.md)

217

218

#### Error Handling and Services

219

Comprehensive error handling and abort service for managing operations.

220

221

```typescript { .api }

222

class WebAuthnError extends Error {

223

code: WebAuthnErrorCode;

224

constructor(options: {

225

message: string;

226

code: WebAuthnErrorCode;

227

cause: Error;

228

name?: string;

229

});

230

}

231

232

interface WebAuthnAbortService {

233

createNewAbortSignal(): AbortSignal;

234

cancelCeremony(): void;

235

}

236

```

237

238

[Error Handling and Services](./error-handling.md)

239

240

### Server Package Capabilities

241

242

#### Registration Options Generation

243

Server-side functions for generating WebAuthn registration options.

244

245

```typescript { .api }

246

function generateRegistrationOptions(options: {

247

rpName: string;

248

rpID: string;

249

userName: string;

250

userID?: Uint8Array;

251

challenge?: string | Uint8Array;

252

userDisplayName?: string;

253

timeout?: number;

254

attestationType?: 'direct' | 'enterprise' | 'none';

255

excludeCredentials?: {

256

id: Base64URLString;

257

transports?: AuthenticatorTransportFuture[];

258

}[];

259

authenticatorSelection?: AuthenticatorSelectionCriteria;

260

extensions?: AuthenticationExtensionsClientInputs;

261

supportedAlgorithmIDs?: COSEAlgorithmIdentifier[];

262

preferredAuthenticatorType?: 'securityKey' | 'localDevice' | 'remoteDevice';

263

}): Promise<PublicKeyCredentialCreationOptionsJSON>;

264

```

265

266

#### Registration Response Verification

267

Server-side functions for verifying WebAuthn registration responses.

268

269

```typescript { .api }

270

function verifyRegistrationResponse(options: {

271

response: RegistrationResponseJSON;

272

expectedChallenge: string | ((challenge: string) => boolean | Promise<boolean>);

273

expectedOrigin: string | string[];

274

expectedRPID?: string | string[];

275

expectedType?: string | string[];

276

requireUserPresence?: boolean;

277

requireUserVerification?: boolean;

278

supportedAlgorithmIDs?: COSEAlgorithmIdentifier[];

279

}): Promise<VerifiedRegistrationResponse>;

280

```

281

282

#### Authentication Options Generation

283

Server-side functions for generating WebAuthn authentication options.

284

285

```typescript { .api }

286

function generateAuthenticationOptions(options: {

287

rpID: string;

288

allowCredentials?: {

289

id: Base64URLString;

290

transports?: AuthenticatorTransportFuture[];

291

}[];

292

challenge?: string | Uint8Array;

293

timeout?: number;

294

userVerification?: 'required' | 'preferred' | 'discouraged';

295

extensions?: AuthenticationExtensionsClientInputs;

296

}): Promise<PublicKeyCredentialRequestOptionsJSON>;

297

```

298

299

#### Authentication Response Verification

300

Server-side functions for verifying WebAuthn authentication responses.

301

302

```typescript { .api }

303

function verifyAuthenticationResponse(options: {

304

response: AuthenticationResponseJSON;

305

expectedChallenge: string | ((challenge: string) => boolean | Promise<boolean>);

306

expectedOrigin: string | string[];

307

expectedRPID?: string | string[];

308

credential: {

309

id: Base64URLString;

310

publicKey: Uint8Array;

311

counter: number;

312

transports?: AuthenticatorTransportFuture[];

313

};

314

requireUserPresence?: boolean;

315

requireUserVerification?: boolean;

316

advancedFIDOConfig?: {

317

userVerification?: 'required' | 'preferred' | 'discouraged';

318

};

319

}): Promise<VerifiedAuthenticationResponse>;

320

```

321

322

#### Metadata and Settings Services

323

Services for managing authenticator metadata and root certificates.

324

325

```typescript { .api }

326

interface MetadataService {

327

initialize(options?: {

328

verificationMode?: VerificationMode;

329

mdsServers?: string[];

330

statements?: MetadataStatement[];

331

}): Promise<void>;

332

getStatement(aaguid: string): Promise<MetadataStatement | undefined>;

333

getStatements(): Promise<MetadataStatement[]>;

334

}

335

336

interface SettingsService {

337

setRootCertificates(opts: {

338

identifier: RootCertIdentifier;

339

certificates: (Uint8Array | string)[];

340

}): void;

341

getRootCertificates(opts: {

342

identifier: RootCertIdentifier;

343

}): string[];

344

}

345

```

346

347

[Server Package Documentation](./server.md)

348

349

## Types

350

351

### Response Types

352

353

```typescript { .api }

354

interface RegistrationResponseJSON {

355

id: Base64URLString;

356

rawId: Base64URLString;

357

response: AuthenticatorAttestationResponseJSON;

358

authenticatorAttachment?: AuthenticatorAttachment;

359

clientExtensionResults: AuthenticationExtensionsClientOutputs;

360

type: PublicKeyCredentialType;

361

}

362

363

interface AuthenticationResponseJSON {

364

id: Base64URLString;

365

rawId: Base64URLString;

366

response: AuthenticatorAssertionResponseJSON;

367

authenticatorAttachment?: AuthenticatorAttachment;

368

clientExtensionResults: AuthenticationExtensionsClientOutputs;

369

type: PublicKeyCredentialType;

370

}

371

```

372

373

### Options Types

374

375

```typescript { .api }

376

interface PublicKeyCredentialCreationOptionsJSON {

377

rp: PublicKeyCredentialRpEntity;

378

user: PublicKeyCredentialUserEntityJSON;

379

challenge: Base64URLString;

380

pubKeyCredParams: PublicKeyCredentialParameters[];

381

timeout?: number;

382

excludeCredentials?: PublicKeyCredentialDescriptorJSON[];

383

authenticatorSelection?: AuthenticatorSelectionCriteria;

384

hints?: PublicKeyCredentialHint[];

385

attestation?: AttestationConveyancePreference;

386

attestationFormats?: AttestationFormat[];

387

extensions?: AuthenticationExtensionsClientInputs;

388

}

389

390

interface PublicKeyCredentialRequestOptionsJSON {

391

challenge: Base64URLString;

392

timeout?: number;

393

rpId?: string;

394

allowCredentials?: PublicKeyCredentialDescriptorJSON[];

395

userVerification?: UserVerificationRequirement;

396

hints?: PublicKeyCredentialHint[];

397

extensions?: AuthenticationExtensionsClientInputs;

398

}

399

```

400

401

### Verification Response Types

402

403

```typescript { .api }

404

interface VerifiedRegistrationResponse {

405

verified: boolean;

406

registrationInfo?: {

407

fmt: AttestationFormat;

408

counter: number;

409

aaguid: string;

410

credentialID: Uint8Array;

411

credentialPublicKey: Uint8Array;

412

userVerified: boolean;

413

credentialDeviceType: CredentialDeviceType;

414

credentialBackedUp: boolean;

415

};

416

}

417

418

interface VerifiedAuthenticationResponse {

419

verified: boolean;

420

authenticationInfo?: {

421

newCounter: number;

422

userVerified: boolean;

423

credentialDeviceType: CredentialDeviceType;

424

credentialBackedUp: boolean;

425

};

426

}

427

```

428

429

### Utility Types

430

431

```typescript { .api }

432

type Base64URLString = string;

433

434

type AuthenticatorTransportFuture =

435

| 'ble'

436

| 'cable'

437

| 'hybrid'

438

| 'internal'

439

| 'nfc'

440

| 'smart-card'

441

| 'usb';

442

443

type WebAuthnErrorCode =

444

| 'ERROR_CEREMONY_ABORTED'

445

| 'ERROR_INVALID_DOMAIN'

446

| 'ERROR_INVALID_RP_ID'

447

| 'ERROR_INVALID_USER_ID_LENGTH'

448

| 'ERROR_MALFORMED_PUBKEYCREDPARAMS'

449

| 'ERROR_AUTHENTICATOR_GENERAL_ERROR'

450

| 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT'

451

| 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT'

452

| 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED'

453

| 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG'

454

| 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE'

455

| 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY';

456

457

type CredentialDeviceType = 'singleDevice' | 'multiDevice';

458

459

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

460

461

type AttestationFormat =

462

| 'fido-u2f'

463

| 'packed'

464

| 'android-safetynet'

465

| 'android-key'

466

| 'tpm'

467

| 'apple'

468

| 'none';

469

470

type VerificationMode = 'permissive' | 'strict';

471

472

type RootCertIdentifier = AttestationFormat | 'mds';

473

```