Passkey Authentication Flow
Quick reference guide for implementing the invitation-based passkey authentication flow.
Admin: Create Invitation
Section titled “Admin: Create Invitation”Create an invitation token for new user registration.
POST /api/auth/invitationsAuthorization: Bearer {admin_token}
Response:{ "token": "abc123...", "expiresAt": "2025-12-18T12:00:00Z"}Share invitation URL: https://yourdomain.com/register?invite=abc123...
New User: Registration Flow
Section titled “New User: Registration Flow”1. Validate Invitation
Section titled “1. Validate Invitation”Check if the invitation code is valid before starting registration.
GET /api/auth/invitations/{code}
Response 200: Valid invitationResponse 404: Not foundResponse 410: Already used2. Begin Registration
Section titled “2. Begin Registration”Start the passkey registration process with the invitation code.
POST /api/auth/passkey/begin?invite={code}
Response:{ "publicKey": {...}, "sessionId": "d4tc5oh6i4r3m3hbnrhg", "isRegistration": true}3. Trigger WebAuthn
Section titled “3. Trigger WebAuthn”Create the passkey credential using the browser’s WebAuthn API.
const credential = await navigator.credentials.create({ publicKey: response.publicKey});4. Complete Registration
Section titled “4. Complete Registration”Submit the credential to complete registration and receive an authentication token.
POST /api/auth/passkey/completeHeaders: { "SessionID": "d4tc5oh6i4r3m3hbnrhg" }Body: {credential}
Response: { "token": "" }Returning User: Login Flow
Section titled “Returning User: Login Flow”1. Begin Login
Section titled “1. Begin Login”Start the authentication process (no invitation needed).
POST /api/auth/passkey/begin
Response:{ "publicKey": {...}, "sessionId": "c9i50ub6ffgg008va1d0", "isRegistration": false}2. Trigger WebAuthn (Discoverable)
Section titled “2. Trigger WebAuthn (Discoverable)”Retrieve the credential using discoverable credentials (no username required).
const credential = await navigator.credentials.get({ publicKey: response.publicKey});3. Complete Login
Section titled “3. Complete Login”Submit the credential to authenticate and receive a session token.
POST /api/auth/passkey/completeHeaders: { "SessionID": "c9i50ub6ffgg008va1d0" }Body: {credential}
Response: { "token": "" }Session cookie is automatically set by the gateway/middleware.
Testing
Section titled “Testing”Use the backend test page for quick testing:
- Registration:
/api/auth/signin?invite={code} - Login:
/api/auth/signin
Cleanup
Section titled “Cleanup”To reset test accounts:
- Run
TRUNCATE adminin your database - Delete the passkey from your authenticator (e.g., 1Password)
Implementation Notes
Section titled “Implementation Notes”- No email required - Passkey-only accounts don’t require an email address
- Auto-generated display name - Format:
user-{external_id[:8]} - Invitation expiry - Invitations expire after 7 days
- Credential storage - WebAuthn credentials are stored on the device and in NATS KV
Next Steps
Section titled “Next Steps”- Passkey Setup Guide - Detailed implementation guide
- Authentication Overview - Learn about auth concepts
- API Reference - Complete API documentation