WebAuthn / passkey registration + authentication (SEC-004).
Implements FIDO2 / WebAuthn Level 2 via @simplewebauthn/server. Users
can register multiple credentials (phone passkey, hardware key, laptop
biometric) and use any of them as a second factor — or as the primary
factor when no TOTP secret is set.
Endpoints (all under /api/v1/auth/webauthn)
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /register/options |
requireAuth | Generate registration challenge. |
| POST | /register/verify |
requireAuth | Verify attestation, store credential. |
| POST | /authenticate/options |
public (login) | Generate assertion challenge. |
| POST | /authenticate/verify |
public (login) | Verify assertion, issue auth cookie. |
| GET | /credentials |
requireAuth | List user's credentials. |
| DELETE | /credentials/:id |
requireAuth | Remove credential (password confirm). |
Pre-auth endpoints (authenticate/*) are authenticated by the
pendingToken issued by /auth/login — same pattern as /mfa/verify.
Configuration
| Env var | Default | Description |
|---|---|---|
WEBAUTHN_RP_ID |
req.hostname |
Relying Party ID (the domain). |
WEBAUTHN_RP_NAME |
"Sentri" |
Display name in passkey prompts. |
WEBAUTHN_ORIGIN |
derived from request | Expected origin (CSV for multi). |
Optional dependency
@simplewebauthn/server is in optionalDependencies so a self-hoster who
does not need passkeys can omit the install via npm install --omit=optional.
When the module is unavailable every endpoint returns 503 instead of
crashing the server.
- Source: