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

authentication.mddocs/

0

# WebAuthn Authentication

1

2

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

3

4

## Capabilities

5

6

### Start Authentication

7

8

Begin authenticator login via WebAuthn assertion ceremony.

9

10

```typescript { .api }

11

/**

12

* Begin authenticator "login" via WebAuthn assertion

13

* @param options Configuration object containing authentication options and settings

14

* @returns Promise resolving to authentication response suitable for server verification

15

*/

16

function startAuthentication(options: {

17

optionsJSON: PublicKeyCredentialRequestOptionsJSON;

18

useBrowserAutofill?: boolean;

19

verifyBrowserAutofillInput?: boolean;

20

}): Promise<AuthenticationResponseJSON>;

21

22

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

23

```

24

25

**Parameters:**

26

27

- `optionsJSON`: Authentication options from your server's `generateAuthenticationOptions()` call

28

- `useBrowserAutofill`: Optional boolean to initialize conditional UI for logging in via browser autofill prompts (defaults to `false`)

29

- `verifyBrowserAutofillInput`: Optional boolean to ensure a suitable `<input>` element is present when `useBrowserAutofill` is `true` (defaults to `true`)

30

31

**Usage Examples:**

32

33

```typescript

34

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

35

36

// Basic authentication

37

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

38

39

try {

40

const authenticationResponse = await startAuthentication({

41

optionsJSON: authenticationOptions,

42

});

43

44

console.log("Authentication successful:", authenticationResponse);

45

46

// Send to server for verification

47

const verificationResponse = await fetch("/webauthn/authenticate/finish", {

48

method: "POST",

49

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

50

body: JSON.stringify(authenticationResponse),

51

});

52

} catch (error) {

53

console.error("Authentication failed:", error);

54

}

55

56

// Authentication with browser autofill (conditional UI)

57

// First ensure you have an input with webauthn autocomplete

58

// <input type="text" autocomplete="username webauthn" />

59

60

try {

61

const authenticationResponse = await startAuthentication({

62

optionsJSON: authenticationOptions,

63

useBrowserAutofill: true, // Enable autofill UI

64

});

65

} catch (error) {

66

if (error.message.includes("No <input> with")) {

67

console.log("Missing required input element for autofill");

68

}

69

}

70

71

// Skip input validation for autofill (advanced usage)

72

try {

73

const authenticationResponse = await startAuthentication({

74

optionsJSON: authenticationOptions,

75

useBrowserAutofill: true,

76

verifyBrowserAutofillInput: false, // Skip input validation

77

});

78

} catch (error) {

79

console.error("Authentication failed:", error);

80

}

81

```

82

83

### Authentication Credential Type

84

85

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

86

87

```typescript { .api }

88

interface AuthenticationCredential extends PublicKeyCredentialFuture {

89

response: AuthenticatorAssertionResponse;

90

}

91

92

interface PublicKeyCredentialFuture extends PublicKeyCredential {

93

type: PublicKeyCredentialType;

94

isConditionalMediationAvailable?(): Promise<boolean>;

95

parseCreationOptionsFromJSON?(

96

options: PublicKeyCredentialCreationOptionsJSON,

97

): PublicKeyCredentialCreationOptions;

98

parseRequestOptionsFromJSON?(

99

options: PublicKeyCredentialRequestOptionsJSON,

100

): PublicKeyCredentialRequestOptions;

101

toJSON?(): PublicKeyCredentialJSON;

102

}

103

```

104

105

### Authentication Response JSON

106

107

JSON-serializable authentication response with Base64URL-encoded ArrayBuffers.

108

109

```typescript { .api }

110

/**

111

* A slightly-modified AuthenticationCredential to simplify working with ArrayBuffers that

112

* are Base64URL-encoded in the browser so that they can be sent as JSON to the server.

113

*/

114

interface AuthenticationResponseJSON {

115

id: Base64URLString;

116

rawId: Base64URLString;

117

response: AuthenticatorAssertionResponseJSON;

118

authenticatorAttachment?: AuthenticatorAttachment;

119

clientExtensionResults: AuthenticationExtensionsClientOutputs;

120

type: PublicKeyCredentialType;

121

}

122

123

interface AuthenticatorAssertionResponseJSON {

124

clientDataJSON: Base64URLString;

125

authenticatorData: Base64URLString;

126

signature: Base64URLString;

127

userHandle?: Base64URLString;

128

}

129

```

130

131

### Authentication Options

132

133

Options for WebAuthn authentication ceremony.

134

135

```typescript { .api }

136

/**

137

* A variant of PublicKeyCredentialRequestOptions suitable for JSON transmission to the browser to

138

* (eventually) get passed into navigator.credentials.get(...) in the browser.

139

*/

140

interface PublicKeyCredentialRequestOptionsJSON {

141

challenge: Base64URLString;

142

timeout?: number;

143

rpId?: string;

144

allowCredentials?: PublicKeyCredentialDescriptorJSON[];

145

userVerification?: UserVerificationRequirement;

146

hints?: PublicKeyCredentialHint[];

147

extensions?: AuthenticationExtensionsClientInputs;

148

}

149

150

interface PublicKeyCredentialDescriptorJSON {

151

id: Base64URLString;

152

type: PublicKeyCredentialType;

153

transports?: AuthenticatorTransportFuture[];

154

}

155

```

156

157

## Browser Autofill Support

158

159

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

160

161

```html

162

<!-- Required for browser autofill -->

163

<input type="text" autocomplete="username webauthn" />

164

165

<!-- Also works with -->

166

<input type="email" autocomplete="email webauthn" />

167

```

168

169

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`.

170

171

**Autofill Requirements:**

172

173

1. Browser must support conditional mediation (check with `browserSupportsWebAuthnAutofill()`)

174

2. Page must have an input with `webauthn` in its `autocomplete` attribute

175

3. `allowCredentials` in options will be automatically cleared for conditional UI

176

4. User interaction will be through browser's native autofill interface

177

178

```typescript

179

import {

180

startAuthentication,

181

browserSupportsWebAuthnAutofill

182

} from "@simplewebauthn/browser";

183

184

// Check support first

185

if (await browserSupportsWebAuthnAutofill()) {

186

const response = await startAuthentication({

187

optionsJSON: authOptions,

188

useBrowserAutofill: true,

189

});

190

}

191

```

192

193

## Error Handling

194

195

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

196

197

- **Browser not supported**: Check with `browserSupportsWebAuthn()` first

198

- **User cancellation**: User cancels the authentication prompt

199

- **No matching credentials**: No registered authenticators found

200

- **Autofill not supported**: Browser doesn't support conditional UI

201

- **Missing input element**: Required autofill input not found

202

203

```typescript

204

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

205

206

try {

207

const response = await startAuthentication({ optionsJSON });

208

} catch (error) {

209

if (error instanceof WebAuthnError) {

210

switch (error.code) {

211

case 'ERROR_CEREMONY_ABORTED':

212

console.log("User cancelled authentication");

213

break;

214

case 'ERROR_INVALID_DOMAIN':

215

console.log("Invalid domain for WebAuthn");

216

break;

217

default:

218

console.log(`Authentication error: ${error.code}`);

219

}

220

} else if (error.message.includes("Browser does not support WebAuthn autofill")) {

221

console.log("Autofill not supported, use regular authentication");

222

} else if (error.message.includes("No <input> with")) {

223

console.log("Missing required input for autofill");

224

}

225

}

226

```