← ClaudeAtlas

webauthnlisted

WebAuthn/FIDO2 passwordless authentication. Passkeys, registration and authentication ceremonies, SimpleWebAuthn library, resident credentials, and platform/cross-platform authenticators. USE WHEN: user mentions "WebAuthn", "FIDO2", "passkey", "passwordless", "biometric login", "security key", "fingerprint login", "SimpleWebAuthn" DO NOT USE FOR: password-based auth - use `jwt` or `oauth2`; magic links - different flow; OAuth social login - use `oauth2`
claude-dev-suite/claude-dev-suite · ★ 33 · AI & Automation · score 80
Install: claude install-skill claude-dev-suite/claude-dev-suite
# WebAuthn / Passkeys ## Server Setup (SimpleWebAuthn) ```typescript import { generateRegistrationOptions, verifyRegistrationResponse, generateAuthenticationOptions, verifyAuthenticationResponse, } from '@simplewebauthn/server'; const rpName = 'My App'; const rpID = 'myapp.com'; const origin = 'https://myapp.com'; ``` ## Registration Flow ### Server: Generate Options ```typescript app.post('/api/auth/register/options', auth, async (req, res) => { const user = req.user; const existingCredentials = await db.credential.findMany({ where: { userId: user.id }, }); const options = await generateRegistrationOptions({ rpName, rpID, userName: user.email, userDisplayName: user.name, excludeCredentials: existingCredentials.map((c) => ({ id: c.credentialId, transports: c.transports, })), authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred', }, }); // Store challenge for verification await db.challenge.upsert({ where: { userId: user.id }, create: { userId: user.id, challenge: options.challenge }, update: { challenge: options.challenge }, }); res.json(options); }); ``` ### Server: Verify Registration ```typescript app.post('/api/auth/register/verify', auth, async (req, res) => { const user = req.user; const { challenge } = await db.challenge.findUnique({ where: { userId: user.id } }); const verification = await verifyRegistrationResponse({ resp