WebAuthn registration functionality for creating and registering new authenticators (passkeys, security keys, platform authenticators) with support for automatic registration via password manager integration.
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() calluseAutoRegister: 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");
}
}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[];
}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;
}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[];
}Registration can throw various WebAuthn-specific errors. Common error scenarios:
browserSupportsWebAuthn() firstimport { 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}`);
}
}
}