Menu

Authentication

Local email codes, passkeys and private team invitations

Local login

The application pins oxidt-auth to v0.17.0 and uses its Topcoat login page. AUTH_MODE=local needs PostgreSQL and SMTP. Development uses the shared services, with SMTP on localhost:1025 and Mailpit at http://localhost:8025.

The browser posts an email to /auth/session/start, then verifies the code at /auth/session/otp/verify. If TOS_VERSION is set, the user accepts those terms before proceeding. Successful login establishes a signed, PostgreSQL-backed session cookie and redirects to the dashboard.

Protected Topcoat pages call web::require_user. Organization operations resolve an OrgContext on each request, so membership removal takes effect immediately. Owner, admin and member restrictions apply server-side. Logout invalidates the stored session, including previously issued copies of its cookie.

Registration and invitations

OPEN_REGISTRATION=false is the default. With empty allowlists, only the first account may register without an invitation. An unexpired invitation permits its recipient to register. ALLOWED_REGISTRATION_EMAILS and ALLOWED_REGISTRATION_DOMAINS can allow additional accounts explicitly.

Invitation links display a confirmation page. Only a signed-in recipient's POST redeems a link; visiting it does not consume it. Team membership does not require billing or a paid subscription.

Passkeys

Users enroll passkeys in Settings. The browser runs the WebAuthn ceremony against /auth/passkey/enroll/options and /auth/passkey/enroll/verify; credentials stay in this application's database. The relying-party ID comes from BASE_URL's host. Keep it stable; changing hosts requires re-enrollment. Email codes remain available as a fallback.

Configuration

Use HTTPS and SECURE_COOKIES=true in production. Generate a unique 64-byte session secret for every deployment. Set TRUST_PROXY_HEADERS=true only behind a trusted reverse proxy. Bump TOS_VERSION when users must accept updated terms; legal pages are in src/web/legal.rs and remain template placeholders.

FerrisKey support is retained upstream but is not the verified Phase 1 login path. It requires a separately managed provider; no local provider containers or bootstrap scripts are included. OAuth/MCP integration routes are disabled in the default build.