Skip to content

Authentication — Overview

Audience: Business stakeholders, product owners, analysts, new team members.

This content was migrated from Documentation/TWO_FACTOR_AUTH.md and enriched with codebase analysis of the full authentication system. Review for accuracy against the current codebase.


What This Module Does

The Authentication module manages how users prove their identity to Swisper and how their sessions are maintained. It has three layers:

  1. Cookie-based sessions — When a user logs in from a web browser, the system creates a secure, HttpOnly session cookie instead of returning a token the frontend has to manage. This protects against common attacks like cross-site scripting (XSS). Mobile apps use traditional JWT tokens instead.

  2. Session timeout and refresh — Web sessions expire after 30 minutes of inactivity (sliding window — each request resets the clock). If the user checked "Remember me," a refresh cookie (14 days, with a 90-day absolute maximum) allows the session to be renewed without re-entering credentials. The frontend shows a warning popup before the session expires so the user can extend it.

  3. Two-Factor Authentication (2FA) — Admin users (is_superuser) must verify their identity with a time-based one-time password (TOTP) from an authenticator app after entering their password. This is mandatory — admin accounts cannot skip 2FA setup. The system provides 5 single-use backup codes for recovery.

Together, these layers ensure that regular users have smooth, secure sessions, while admin users have an additional barrier against unauthorized access.


Who It Serves

  • All users who benefit from secure, cookie-based sessions that protect against token theft and XSS attacks.
  • Admin users (is_superuser = true) who are required to set up and use 2FA for access to the admin panel.
  • Product owners who need assurance that the platform meets modern security standards (CASA compliance).
  • New team members who need to understand how login, session management, and 2FA work end to end.

Key Capabilities

  • Cookie-based web authentication — HttpOnly session cookies with CSRF protection (double-submit pattern), replacing client-side JWT storage.
  • Sliding session timeout — Sessions expire after 30 minutes of inactivity; each API request resets the timer. A frontend popup warns users before expiry.
  • Remember me — Opt-in refresh cookie (14 days) that automatically renews expired sessions without re-login. Enforces a 90-day absolute maximum lifespan.
  • Token rotation with replay detection — Refresh tokens are single-use; reusing an old token revokes all sessions for the user (theft protection).
  • Mobile JWT fallback — Mobile apps use traditional Bearer token authentication since cookies don't work well on mobile platforms.
  • Mandatory admin 2FA — Superusers must set up TOTP-based 2FA on first login. Compatible with any authenticator app (Microsoft, Google, Authy, etc.).
  • Progressive session phases — After password verification, admin sessions start in a restricted phase (requires_2fa_setup or requires_2fa_login) that only allows 2FA-related endpoints until verification completes.
  • 5 single-use backup codes for 2FA recovery, stored as SHA-256 hashes.
  • Login rate limiting — Brute-force protection with per-email and per-IP rate limiting (CASA 11.1.4 compliance).
  • Session management UI — Users can view and revoke active sessions across devices.

How It Fits in the Platform

Authentication sits in front of every API endpoint in Swisper. It does not interact with the conversation pipeline (Global Supervisor, Intent Classification, etc.) — it controls access to the platform itself. The session middleware validates the session cookie on every request and extends the sliding timeout. CSRF tokens are verified on state-changing requests. The 2FA module integrates with the login flow by adding a session "phase" that gates access until verification is complete. TOTP secrets are stored encrypted in PostgreSQL using pgcrypto.


Limits and Edge Cases

  • Admin-only 2FA: Regular end users do not have 2FA. The feature is scoped to is_superuser = true.
  • Mobile admins must use web: Superuser accounts cannot log in from mobile apps — they must use the web interface for 2FA.
  • Lost device + lost backup codes: If an admin loses both their authenticator device and all backup codes, recovery requires direct database intervention (see Operations guide).
  • Session timeout is per-device: The sliding window is tracked per session cookie, not globally. Opening Swisper in a new browser creates a new session.
  • No TOTP rate limiting (yet): Rate limiting for failed TOTP code attempts is planned but not yet implemented. The totp_last_used_at field exists for this purpose.

FAQ

Q: Why did Swisper move from JWT to cookies? A: Cookie-based sessions with HttpOnly and Secure flags are more resistant to XSS attacks than storing JWTs in localStorage or sessionStorage. The browser manages the cookie automatically — JavaScript cannot access it, which eliminates a common attack vector. Mobile apps still use JWTs because cookies don't work reliably on mobile platforms.

Q: What happens when my session expires? A: If you checked "Remember me" during login, the system automatically refreshes your session using the refresh cookie — you stay logged in seamlessly. If you didn't check "Remember me," you'll see a warning popup 5 minutes before expiry with a "Stay Logged In" button. If you don't respond, you're logged out after 30 minutes of inactivity.

Q: Which authenticator apps work with Swisper 2FA? A: Any TOTP-compatible app: Microsoft Authenticator, Google Authenticator, Authy, 1Password, Bitwarden, etc. The standard is RFC 6238.

Q: What happens if I lose my phone? A: Use one of your 5 backup codes to log in. Each backup code is single-use. Once logged in, you can regenerate new backup codes or disable and re-enable 2FA with a new device.

Q: Can someone reuse a stolen refresh token? A: No. Refresh tokens are single-use with rotation — each refresh issues a new token and invalidates the old one. If someone attempts to reuse an old token, the system detects this as a potential theft and revokes all sessions for the user immediately.