Tools for server ↔ client WebAuthn ceremony orchestration.
Quickprompt · Install · Usage Walkthrough · API Reference · License
Prompt your agent:
Add passkey authentication to my app using https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/SKILL.md, and add it to my skills.
npm i webauthxpnpm i webauthxbun i webauthxRegister a new passkey credential for a user. The server generates a challenge, the client creates the credential, and the server verifies it.
import { Registration } from 'webauthx/server'
app.post('/register/options', async (request) => {
const { name } = await request.json()
// Generate a challenge and WebAuthn options for the client.
const { challenge, options } = Registration.getOptions({
name,
rp: { id: 'example.com', name: 'Example' },
})
// Persist challenge for verification in the next step.
await store.storeChallenge(challenge)
// Send WebAuthn options to the client.
return Response.json({ options })
})import { Registration } from 'webauthx/client'
// Fetch WebAuthn options from the server.
const { options } = await fetch('/register/options', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'alice' }),
}).then((r) => r.json())
// Prompt the user to create a passkey.
const credential = await Registration.create({ options })
// Send the credential to the server for verification.
await fetch('/register/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ credential }),
})import { Registration } from 'webauthx/server'
app.post('/register/verify', async (request) => {
const { credential } = await request.json()
// Consume the stored challenge (single-use).
const challenge = await store.consumeChallenge(request)
// Verify attestation & extract the public key.
const result = Registration.verify(credential, {
challenge,
origin: 'https://example.com',
rpId: 'example.com',
})
// Persist the credential for future authentication.
await store.storeCredential(result.credential)
})Authenticate a returning user with their existing passkey. The server generates a challenge, the client signs it, and the server verifies the signature.
import { Authentication } from 'webauthx/server'
app.post('/auth/options', async (request) => {
const { credentialId } = await request.json()
// Generate a challenge and WebAuthn options for the client.
const { challenge, options } = Authentication.getOptions({
credentialId,
rpId: 'example.com',
})
// Persist challenge for verification in the next step.
await store.storeChallenge(challenge)
// Send WebAuthn options to the client.
return Response.json({ options })
})import { Authentication } from 'webauthx/client'
// Fetch WebAuthn options from the server.
const { options } = await fetch('/auth/options', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ credentialId }),
}).then((r) => r.json())
// Prompt the user to sign the challenge with their passkey.
const response = await Authentication.sign({ options })
// Send the response to the server for verification.
await fetch('/auth/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ response }),
})import { Authentication } from 'webauthx/server'
app.post('/auth/verify', async (request) => {
const { response } = await request.json()
// Consume the stored challenge (single-use).
const challenge = await store.consumeChallenge(request)
// Look up the stored public key for this credential.
const credential = await store.getCredential(response.id)
// Verify the P-256 signature.
const valid = Authentication.verify(response, {
challenge,
publicKey: credential.publicKey,
origin: 'https://example.com',
rpId: 'example.com',
})
})Signs a challenge via navigator.credentials.get. Accepts WebAuthn options from the server and returns a response ready to send back.
import { Authentication } from 'webauthx/client'
const response = await Authentication.sign({ options })| Parameter | Type | Description |
|---|---|---|
getFn |
function |
Custom credential request function (for testing). |
options |
CredentialRequestOptions |
WebAuthn options from Authentication.getOptions. |
Promise<Authentication.Response>
Response to send to the server.
Creates a new WebAuthn credential via navigator.credentials.create. Accepts WebAuthn options from the server and returns a credential ready to send back.
import { Registration } from 'webauthx/client'
const credential = await Registration.create({ options })| Parameter | Type | Description |
|---|---|---|
createFn |
function |
Custom credential creation function (for testing). |
options |
CredentialCreationOptions |
WebAuthn options from Registration.getOptions. |
Promise<Registration.Credential>
Credential to send to the server.
Generates PublicKeyCredentialRequestOptions for authentication. A random 32-byte challenge is generated if one isn't provided.
import { Authentication } from 'webauthx/server'
const { challenge, options } = Authentication.getOptions({
credentialId: storedCredential.id,
rpId: 'example.com',
})| Parameter | Type | Description |
|---|---|---|
challenge |
Hex |
Optional challenge. A random 32-byte hex value is generated if omitted. |
credentialId |
string | string[] |
Credential ID(s) to allow. |
rpId |
string |
Relying party ID. |
timeout |
number |
Timeout in milliseconds. |
userVerification |
string |
User verification requirement. |
{ challenge: Hex; options: CredentialRequestOptions }
Challenge to store and the WebAuthn options to send to the client.
Verifies an authentication response from the client. Validates the rpIdHash, origin, challenge, and P-256 signature.
import { Authentication } from 'webauthx/server'
const valid = Authentication.verify(response, {
challenge,
publicKey: credential.publicKey,
origin: 'https://example.com',
rpId: 'example.com',
})| Parameter | Type | Description |
|---|---|---|
options.challenge |
Hex |
Expected challenge. |
options.origin |
string | string[] |
Expected origin(s). |
options.publicKey |
Hex |
The stored P-256 public key (hex). |
options.rpId |
string |
Expected relying party ID. |
response |
Authentication.Response |
The authentication response from the client. |
boolean
true if the signature is valid.
Generates PublicKeyCredentialCreationOptions for registration. A random 32-byte challenge is generated if one isn't provided.
import { Registration } from 'webauthx/server'
const { challenge, options } = Registration.getOptions({
name: 'alice',
rp: { id: 'example.com', name: 'Example' },
})| Parameter | Type | Description |
|---|---|---|
attestation |
string |
Attestation conveyance preference. |
authenticatorSelection |
object |
Authenticator selection criteria. |
challenge |
Hex |
Optional challenge. A random 32-byte hex value is generated if omitted. |
excludeCredentialIds |
string[] |
Credential IDs to exclude (prevent re-registration). |
name |
string |
Display name for the credential (shorthand for user.name). |
rp |
{ id: string; name: string } |
Relying party identifier and display name. |
timeout |
number |
Timeout in milliseconds. |
user |
{ name: string; displayName?: string; id?: BufferSource } |
User account descriptor. Alternative to name. |
{ challenge: Hex; options: CredentialCreationOptions }
Challenge to store and the WebAuthn options to send to the client.
Verifies a registration credential from the client. Validates the attestation, rpIdHash, challenge, and origin, and extracts the P-256 public key.
import { Registration } from 'webauthx/server'
const result = Registration.verify(credential, {
challenge,
origin: 'https://example.com',
rpId: 'example.com',
})| Parameter | Type | Description |
|---|---|---|
credential |
Registration.Credential |
The credential from the client. |
options.challenge |
Hex | Uint8Array | ((challenge: string) => boolean) |
Expected challenge value or async validator function. |
options.origin |
string | string[] |
Expected origin(s) (e.g. "https://example.com"). |
options.rpId |
string |
Relying party ID (e.g. "example.com"). |
options.userVerification |
string |
User verification requirement. Default: 'required'. |
Registration.Response
MIT