Authentication
Flowstate uses passwordless authentication for all user logins and OpenID Connect for admin access. This approach eliminates password-related vulnerabilities while providing a seamless user experience.
Passwordless Magic Links
Section titled “Passwordless Magic Links”Users authenticate by receiving a magic link via email. The flow is simple:
- User enters their email address on the login page
- System generates a single-use token and sends it via email
- User clicks the link in their email
- System validates the token and creates an authenticated session
- User is redirected to the canvas
Magic links expire in 15 minutes. After expiration, users must request a new link. This short window limits the risk of intercepted or forwarded links being used maliciously.
Why Passwordless?
Section titled “Why Passwordless?”Traditional password authentication introduces several risks:
- Password reuse: Users often reuse passwords across services, so a breach elsewhere compromises your platform
- Weak passwords: Users choose memorable passwords that are easy to guess or crack
- Credential stuffing: Attackers use leaked credentials from other breaches to try logging in
- Phishing: Users can be tricked into entering passwords on fake login pages
- Storage vulnerabilities: Even hashed passwords can be cracked if the hashing algorithm is weak or the database is compromised
Magic links eliminate all of these risks. There’s no password to reuse, no password to guess, and no password to store. The only attack vector is email account compromise, which is outside the platform’s control and typically protected by the email provider’s security measures.
Magic Link Security
Section titled “Magic Link Security”Each magic link contains a cryptographically random token that’s:
- Single-use: Once validated, the token is immediately invalidated
- Time-limited: Tokens expire in 15 minutes
- Unpredictable: Generated using a secure random number generator
- Hashed before storage: The database stores a hash of the token, not the token itself
If an attacker intercepts a magic link, they have a 15-minute window to use it. Once used or expired, the link becomes worthless. The short expiration window and single-use nature make magic links significantly more secure than long-lived passwords.
Rate Limiting Magic Link Requests
Section titled “Rate Limiting Magic Link Requests”Magic link requests are rate-limited to 10 per minute per email address. This prevents:
- Email bombing: Attackers can’t flood a user’s inbox with login emails
- Enumeration attacks: Attackers can’t rapidly test which email addresses have accounts
- Resource exhaustion: The email sending service isn’t overwhelmed by malicious requests
The rate limit applies to the email address, not the IP address. This prevents shared-IP false positives (like users on corporate networks or VPNs) while still protecting against abuse.
JWT Token Sessions
Section titled “JWT Token Sessions”Once authenticated via magic link, users receive a JWT (JSON Web Token) that represents their session. The token contains:
- User ID: Identifies the authenticated user
- Email: User’s email address
- Issued at: When the token was created
- Expiry: When the token becomes invalid (7 days from issuance)
Tokens are signed using a secret key known only to the backend. This signature prevents tampering. If an attacker modifies the token (for example, changing the user ID), the signature becomes invalid and the backend rejects the token.
Token Expiry and Renewal
Section titled “Token Expiry and Renewal”Tokens expire after 7 days. This limits the window of opportunity if a token is stolen. However, requiring users to re-authenticate every 7 days would be disruptive.
To balance security and usability, tokens automatically renew when they have less than 2 days remaining. The renewal process:
- User makes an authenticated request with a token that expires in less than 2 days
- Backend validates the token and processes the request
- Backend generates a new token with a fresh 7-day expiry
- Backend includes the new token in the response (via Set-Cookie header for web, or response body for desktop)
- Client stores the new token and uses it for subsequent requests
This approach provides long-lived sessions without compromising security. If a token is stolen, it’s only valid for a maximum of 7 days. If the legitimate user is actively using the platform, their token renews regularly and the stolen token becomes outdated.
Token Storage
Section titled “Token Storage”Tokens are stored differently depending on the client:
Web Application:
- Stored in an httpOnly cookie
- Cookie is secure (HTTPS-only in production)
- Cookie has sameSite=lax to prevent CSRF attacks
- JavaScript cannot access the cookie (prevents XSS token theft)
Desktop Application:
- Stored in Electron’s secure storage (encrypted at rest)
- Sent via Authorization header:
Authorization: Bearer <token> - Never exposed to the renderer process (main process handles it)
RPC Gateway:
- Desktop app sends token via Authorization header
- Gateway validates the token before processing RPC calls
- Token is never logged or exposed in error messages
Session Management
Section titled “Session Management”Each login creates a tracked session in the database. Sessions record:
- User ID: Who the session belongs to
- Device info: User agent string (browser/OS/device type)
- IP address: Where the session was created
- Created at: When the session started
- Last active: When the session was last used
- Token hash: Hashed version of the JWT token
Sessions enable several security features:
- Active session listing: Users can see all their active sessions
- Remote logout: Users can revoke sessions from other devices
- Suspicious activity detection: Unusual login locations or devices can trigger alerts
- Session expiry: Sessions can be forcibly expired if compromised
Session tokens are hashed before storage using a one-way hash function. If the database is compromised, attackers can’t use the stored hashes to impersonate users. They would need the original token, which only exists in the user’s browser or desktop app.
Login Request Polling (Desktop)
Section titled “Login Request Polling (Desktop)”The desktop app supports a “request on one device, approve on another” flow:
- User opens the desktop app on a new device
- Desktop app generates a login request ID and displays a QR code
- User scans the QR code with their phone (where they’re already logged in)
- Phone app approves the login request
- Desktop app polls the backend for approval status
- Once approved, desktop app receives a token and authenticates
This flow enables:
- Seamless multi-device setup: No need to enter email or click magic links on devices without easy email access
- Secure approval: The approving device must already be authenticated
- Time-limited requests: Login requests expire in 5 minutes
Login requests are stored in Redis with a short TTL (time to live). Once approved or expired, they’re automatically deleted.
Admin Authentication via Cognito
Section titled “Admin Authentication via Cognito”Admin users authenticate through Amazon Cognito using OpenID Connect (OIDC). This provides:
- Enterprise identity management: Integrates with corporate SSO and identity providers
- Multi-factor authentication: Cognito supports MFA for admin accounts
- Centralized user management: Admins are managed in Cognito, not the application database
- Audit trails: Cognito logs all authentication events
The OIDC flow:
- Admin clicks “Admin Login” on the login page
- Browser redirects to Cognito’s hosted UI
- Admin authenticates with Cognito (username/password + MFA)
- Cognito redirects back to the application with an authorization code
- Backend exchanges the code for an ID token and access token
- Backend validates the ID token and creates an admin session
- Admin is redirected to the admin dashboard
ID tokens contain the admin’s email and Cognito user ID. The backend uses the email to look up the admin’s role and permissions in the application database.
Super Admin Auto-Promotion
Section titled “Super Admin Auto-Promotion”Super admin privileges are granted automatically to whitelisted email addresses. The whitelist is stored in an environment variable:
When an admin authenticates via Cognito, the backend checks if their email is in the whitelist. If so, they’re automatically promoted to super_admin role. This ensures the right people have full platform access from day one, without manual role assignment.
Super admins can promote other users to admin roles through the admin dashboard. All role changes are logged in the admin audit trail.
Account Deletion Confirmation
Section titled “Account Deletion Confirmation”Users can delete their accounts, but the process requires email confirmation to prevent accidental deletions:
- User clicks “Delete Account” in settings
- System sends a confirmation email with a single-use token
- Token expires in 30 minutes
- User clicks the link in the email
- System validates the token and permanently deletes the account
The confirmation token is:
- Single-use: Once validated, the token is invalidated
- Time-limited: Expires in 30 minutes
- Hashed before storage: Database stores a hash, not the token itself
- Tied to the user: Only valid for the user who requested deletion
If the user doesn’t click the confirmation link within 30 minutes, the deletion request is cancelled and the account remains active.
Account deletion is permanent and irreversible. All user data (canvas positions, sessions, uploaded files, etc.) is deleted. The user’s email address is also removed, so they can create a new account with the same email if desired.
Authentication Error Handling
Section titled “Authentication Error Handling”Authentication errors are handled carefully to avoid leaking information:
Magic Link Requests:
- Always return success, even if the email doesn’t exist
- This prevents enumeration attacks (testing which emails have accounts)
- Users receive an email if the account exists, nothing if it doesn’t
Token Validation:
- Invalid tokens return 401 Unauthorized
- Error message is generic: “Invalid or expired token”
- No details about why the token is invalid (prevents information leakage)
Rate Limiting:
- Exceeded rate limits return 429 Too Many Requests
- Response includes Retry-After header with seconds until reset
- Error message explains the rate limit and when to retry
Session Errors:
- Expired sessions return 401 Unauthorized
- Client is redirected to the login page
- No details about why the session expired (could be timeout, logout, or revocation)
Generic error messages prevent attackers from learning about the system’s internal state. For example, if an error message said “Token signature is invalid,” an attacker would know the token format is correct but the signature is wrong. A generic “Invalid token” message reveals nothing.
Authentication Security Checklist
Section titled “Authentication Security Checklist”Flowstate’s authentication system provides:
- ✅ No password storage (magic links eliminate password vulnerabilities)
- ✅ Short-lived magic links (15-minute expiry limits attack window)
- ✅ Single-use tokens (magic links and deletion tokens can’t be reused)
- ✅ Automatic token renewal (seamless long-term sessions without compromising security)
- ✅ httpOnly cookies (prevents XSS token theft on web)
- ✅ Secure token storage (encrypted at rest on desktop)
- ✅ Session tracking (users can see and revoke active sessions)
- ✅ Rate limiting (prevents brute force and enumeration attacks)
- ✅ Admin MFA (Cognito supports multi-factor authentication)
- ✅ Audit logging (all admin authentication events are logged)
- ✅ Confirmation flows (account deletion requires email confirmation)
- ✅ Generic error messages (prevents information leakage)
Future Authentication Enhancements
Section titled “Future Authentication Enhancements”Planned improvements to the authentication system:
- WebAuthn support: Passwordless authentication using biometrics or security keys
- Social login: OAuth integration with Google, GitHub, and Microsoft
- Session anomaly detection: Alert users when sessions are created from unusual locations or devices
- Forced re-authentication: Require re-authentication for sensitive actions (like changing email or deleting account)
- Session expiry policies: Configurable session timeouts for different user types
- Login notifications: Email users when new sessions are created
Authentication security is an ongoing focus. The platform evolves to incorporate new standards and best practices as they emerge.