SaaS Authentication Systems
A production SaaS authentication system combines email/password and OAuth providers for login, JWT tokens in httpOnly cookies for sessions, and role-based access control (RBAC) enforced at the database, API, and UI layers simultaneously. Auth is the security foundation of the entire product — it must be designed before any feature is built.
4Byte Agency uses Supabase Auth across all 45+ SaaS products — it handles JWT management, OAuth, magic links, and MFA out of the box, eliminating weeks of custom auth infrastructure.
▸ Authentication Methods
Four auth methods for SaaS — which ones to ship and when
Not every auth method is appropriate at every stage. Here are the four primary methods — with honest pros, cons, and a clear recommendation for each.
Email & Password
Always — this is the minimum viable auth method for any SaaS product.
The baseline authentication method. Users register with an email address and password. Requires email verification, secure password storage (bcrypt), and a password reset flow.
Advantages
- Universal — every user knows how to use it
- No dependency on third-party OAuth provider uptime
- Full control over the credential lifecycle
Trade-offs
- Users must remember another password
- Higher support overhead for password resets
- Requires email verification flow
OAuth Providers
Ship Google OAuth at minimum alongside email/password. GitHub OAuth for developer-facing products. LinkedIn for B2B sales tools.
Users authenticate via a trusted third-party identity provider — Google, GitHub, LinkedIn, Microsoft. The provider handles credential management; you receive a verified identity token.
Advantages
- No password management for users
- Verified email from provider
- Higher signup conversion rates
- Provider handles MFA and security
Trade-offs
- Dependency on provider availability
- Users may have multiple identities across providers
- Account linking complexity when same email exists
Magic Links
Excellent for low-friction B2B signups and internal tools where users accept email-based workflows.
Passwordless authentication via a time-limited, single-use link sent to the user's email. The user clicks the link and is authenticated without a password.
Advantages
- Zero password management
- High conversion for new signups
- No brute-force attack surface
- Verified email implicit in flow
Trade-offs
- Dependent on email deliverability
- Users must access email to log in
- Not suitable for environments without reliable email
SSO (SAML / Enterprise)
Required for enterprise-tier SaaS plans. Mid-market buyers frequently list SSO as a purchasing requirement.
Single Sign-On for enterprise buyers who manage identity centrally via an Identity Provider (IdP) like Okta, Azure AD, or Google Workspace. SAML 2.0 or OIDC protocol.
Advantages
- Required by IT departments of mid-market+ buyers
- Centralised user lifecycle management
- Automatic deprovisioning when employees leave
Trade-offs
- High implementation complexity
- Requires SAML or OIDC integration per provider
- Not necessary for self-serve SaaS MVPs
▸ JWT vs Sessions
JWT vs session-based auth — the definitive comparison
The JWT vs session debate is one of the most common questions in SaaS auth design. Here's the honest trade-off analysis for each dimension that matters.
4Byte verdict: Use JWT with Supabase Auth for all Next.js SaaS products. The statelessness advantage for serverless and Edge deployments, combined with native Supabase RLS integration via auth.uid(), makes JWT the clear choice. Use short expiry (1 hour) with refresh tokens stored in httpOnly cookies for security.
▸ Role-Based Access Control
The three-role RBAC model that works for 95% of SaaS products
Start with three roles — Owner, Admin, Member. This covers the vast majority of SaaS use cases. Custom roles and granular permissions are a post-launch concern for products that have proven the need for them.
Owner
The account creator and primary account holder. Has all permissions across the organisation. Can transfer ownership, delete the organisation, and manage billing.
Can Do
- All admin permissions
- Transfer organisation ownership
- Delete the organisation and all data
- Manage subscription and billing
- Create and delete API keys
- Invite and remove admins
Admin
Trusted team members with elevated privileges. Can manage the workspace, invite members, and perform all product operations. Cannot touch billing or delete the organisation.
Can Do
- All member permissions
- Invite and remove members
- Create and manage workspaces
- View all member activity
- Configure integrations
- Export organisation data
Cannot Do
- Manage billing
- Delete the organisation
- Transfer ownership
- Manage API keys
Member
Standard workspace users. Can use all product features but cannot manage the organisation, invite others, or access admin settings. The default role for invited team members.
Can Do
- Access all product core features
- Create and edit their own content
- View shared organisation content
- Update their own profile
- Use integrations configured by admin
Cannot Do
- Invite new members
- Remove other members
- Access admin settings
- View billing
- Export data
RBAC Enforcement Layers
Role checks must be enforced at three independent layers: (1) Database RLS — policies block unauthorised writes regardless of application bugs. (2) API middleware — every protected route checks role before executing. (3) UI layer — components conditionally render based on role for UX only (never for security). All three must exist. Removing any one creates a bypass vector.
▸ Auth Flows
Three critical auth flows — step by step
These are the three flows that every SaaS product must implement correctly. Each step has a defined outcome — missing any step creates a security gap or a broken user experience.
New User Signup
User submits email + password (or clicks OAuth)
Client-side validation. Password strength check. Duplicate email check via Supabase.
Supabase Auth creates user record
Hashed password stored. Confirmation email sent with verification token. Unconfirmed user created.
User verifies email
Click link in email. Token validated. User marked as confirmed. Session JWT issued.
Onboarding flow triggered
Check if user has an organisation. If not, prompt to create one or accept pending invitation.
Organisation and membership created
Create organisation record. Create membership record with role 'owner'. Provision free plan subscription.
User lands in dashboard
Auth context loaded. Organisation context loaded. Feature flags applied based on plan.
Team Member Invitation
Admin sends invitation
Invitation record created with token, role, email, and 48-hour expiry. Email sent via Resend.
Invitee clicks invitation link
Token validated against invitations table. Expiry checked. Already-accepted check.
Account creation or login
If new user — show signup form with email pre-filled. If existing user — show login prompt. OAuth allowed.
Membership created
Membership record created with organisation_id and role from invitation. Invitation marked as accepted_at = now().
User enters organisation workspace
Auth context includes new organisation. Organisation switcher available if user belongs to multiple orgs.
Protected Route Access
Request hits Next.js middleware
JWT extracted from cookie. Supabase client verifies signature. Expired tokens trigger automatic refresh.
User identity confirmed
auth.uid() extracted from verified JWT. No database lookup required — stateless validation.
Organisation context loaded
Membership record fetched: SELECT * FROM memberships WHERE user_id = auth.uid(). Role extracted.
Route-level authorisation check
Required role compared against user's role for this organisation. Admin-only routes reject member-role requests.
Plan-level feature gate
Subscription status checked. Feature flag evaluated against plan tier. Upgrade prompt shown if gated.
Request proceeds to handler
All database queries automatically scoped by RLS policies — no manual organisation_id filtering in handlers.
▸ Middleware Patterns
Six auth middleware patterns every SaaS API needs
These six middleware layers are stacked in sequence for every protected route. Each one handles a specific access concern — skipping any one creates a gap.
Public Route Guard
Marketing pages and auth pages are public. Authenticated users visiting /login are redirected to their dashboard — they're already in.
// Allow: /, /login, /signup, /pricing, /blog/*
// Redirect to /dashboard if already authenticatedProtected Route Guard
All dashboard routes require a valid, non-expired JWT and email verification. Unauthenticated requests redirect to login with the intended path preserved.
// Require: valid JWT + confirmed email
// Redirect to /login?next={currentPath} if unauthenticatedRole Guard
Admin-only routes (settings, billing, member management) check the user's role in the current organisation before allowing access.
// Require: role IN ('owner', 'admin') for /settings/*
// Return 403 Forbidden if role is 'member'Plan Guard
Feature-gated routes check subscription status and plan tier. Free and trial users see upgrade prompts instead of the gated feature.
// Require: subscription.status = 'active' for paid features
// Show upgrade prompt if status = 'trialing' or 'free'Org Context Guard
Multi-organisation setups verify that the user is actually a member of the organisation referenced in the URL — not just authenticated globally.
// Require: valid orgSlug in URL params
// Verify user is a member of that specific organisationAPI Rate Limit Guard
API routes enforce per-token rate limits. Auth endpoints enforce per-IP rate limits using Upstash Redis to prevent brute force and abuse.
// Limit: 100 req/min per user token for /api/*
// Limit: 10 req/15min per IP for /auth/*▸ Multi-Factor Authentication
MFA for SaaS — three methods and when to use each
MFA reduces account takeover risk by 99.9%. Here are the three methods available for SaaS products — with implementation detail and guidance on which to prioritise.
TOTP (Time-Based One-Time Password)
Users scan a QR code with an authenticator app (Google Authenticator, Authy, 1Password). The app generates a 6-digit code that rotates every 30 seconds.
How It Works
Server generates a shared secret. User scans QR. App derives codes from secret + timestamp. Server validates submitted code against current and previous time window.
Best For
All SaaS products — the standard MFA method. Supabase Auth supports TOTP out of the box.
Email OTP
A 6-digit one-time code sent to the user's registered email address as a second factor. Less secure than TOTP (depends on email account security) but lower friction for non-technical users.
How It Works
Server generates a short-lived code (5-minute expiry). User receives email with code. User submits code alongside password. Server validates against stored hash.
Best For
Consumer-facing SaaS where users are unlikely to use authenticator apps. Good fallback when TOTP device is unavailable.
WebAuthn / Passkeys
Biometric or hardware key-based authentication using the WebAuthn standard. Users authenticate with Face ID, Touch ID, or a physical security key (YubiKey). Phishing-resistant by design.
How It Works
Browser generates public/private key pair. Public key stored server-side. Private key stays on device. Each login signed by device — cryptographically bound to the domain.
Best For
Security-conscious B2B SaaS and enterprise products where phishing resistance is a requirement. Growing adoption as passkeys become mainstream.
Make MFA available in account settings but do not require it. Encourage it with a setup prompt but never block access.
Prompt admin and owner roles to enable MFA. Show a security score or warning in settings. Do not block access but make it visible.
Enforce MFA for all users in the organisation. Block access until MFA is configured. Org-level setting controllable by owner.
▸ Security Hardening
Six security controls every SaaS auth system must implement
These six controls address the most common auth vulnerabilities in SaaS products. Each one eliminates a specific attack vector — and all six are implemented by default in every 4Byte build.
httpOnly Cookies for Token Storage
What It Does
JWT access tokens and refresh tokens are stored in httpOnly cookies — not localStorage or sessionStorage. httpOnly cookies are inaccessible to JavaScript, eliminating XSS-based token theft.
Implementation
Set-Cookie: sb-access-token=...; HttpOnly; Secure; SameSite=Lax; Path=/Short JWT Expiry with Refresh Tokens
What It Does
Access tokens expire after 15–60 minutes. Refresh tokens issue new access tokens automatically and silently. This limits the window of exposure if a token is somehow compromised.
Implementation
Supabase default: 1-hour access token, 7-day refresh token with rotation on each use.Email Verification Before Access
What It Does
New accounts cannot access the product until their email address is verified. Prevents fake account creation, reduces spam, and ensures a valid contact point for all users.
Implementation
Supabase Auth sends verification email on signup. Route middleware checks email_confirmed_at IS NOT NULL.Rate Limiting on Auth Endpoints
What It Does
Login, signup, magic link, and password reset endpoints are rate-limited by IP address. Prevents brute force attacks, credential stuffing, and email bombing of the reset endpoint.
Implementation
10 attempts per IP per 15 minutes on login. 3 magic link sends per email per hour. Upstash Redis for distributed rate limiting.Session Rotation on Privilege Change
What It Does
When a user's role changes, their password is reset, or they upgrade to a higher-privilege plan, the current session is invalidated and a new one is issued. Prevents privilege escalation from stale sessions.
Implementation
Call supabase.auth.signOut() then re-authenticate, or use admin API to invalidate sessions for a specific user.PKCE Flow for OAuth
What It Does
OAuth flows use PKCE (Proof Key for Code Exchange) instead of the implicit flow. PKCE prevents authorization code interception attacks by binding the code exchange to the original request.
Implementation
Supabase Auth uses PKCE by default for all OAuth flows. No additional configuration required.▸ Auth Mistakes
Auth mistakes that create serious security vulnerabilities
These six mistakes appear regularly in SaaS products that were built quickly without security-first thinking. Every one is preventable and expensive to fix after launch.
Storing JWT tokens in localStorage
Security Risk
localStorage is accessible to any JavaScript on the page — including injected scripts from XSS attacks. A single XSS vulnerability exposes every active user's session token.
4Byte Security Standard
Always store JWTs in httpOnly, Secure, SameSite=Lax cookies. These are inaccessible to JavaScript by design. Supabase Auth handles this correctly by default when using SSR.
Not verifying email before granting product access
Security Risk
Unverified emails allow anyone to create accounts using someone else's email address. The real owner is locked out, and the account may be used for spam or abuse.
4Byte Security Standard
Block product access until email_confirmed_at is set. Redirect unverified users to a 'check your email' page. Provide a resend verification option with rate limiting.
Enforcing permissions only in the UI layer
Security Risk
UI-only guards (hiding buttons, disabling links) are trivially bypassed by making direct API calls. A member-role user can perform admin operations by crafting HTTP requests.
4Byte Security Standard
Enforce all role checks at the API layer via middleware, independent of what the UI shows. The database RLS layer adds a third enforcement point. UI guards are UX only — never security.
Implementing custom password hashing
Security Risk
Rolling custom password storage (MD5, SHA-256, or custom bcrypt) introduces implementation errors that cause mass credential exposure. This is the leading cause of high-profile breaches.
4Byte Security Standard
Never implement custom password storage. Use Supabase Auth, NextAuth.js, or another battle-tested auth library. These implement bcrypt with appropriate cost factors and salt generation.
No rate limiting on password reset endpoint
Security Risk
Unprotected password reset endpoints can be exploited to send hundreds of reset emails to any address — causing email spam abuse and potential account enumeration.
4Byte Security Standard
Rate limit password reset to 3 requests per email address per hour. Rate limit by IP as well. Return a generic success message regardless of whether the email exists — never confirm account existence.
Not invalidating sessions on password change
Security Risk
If a user's password is changed (by them or via admin reset), old sessions remain valid. An attacker who had gained session access retains it even after the password change.
4Byte Security Standard
On password change or admin-initiated reset, invalidate all existing sessions for that user via Supabase Admin API and force re-authentication. Issue a new session only after the new credentials are confirmed.
▸ FAQ
Frequently asked questions about SaaS authentication
What is the best authentication method for a SaaS product?+
For most SaaS products in 2025, the best authentication approach combines email/password login with OAuth providers (Google, GitHub) and magic link options. Managed auth via Supabase Auth handles JWT token management, session refresh, and multi-provider support out of the box — eliminating weeks of custom auth infrastructure build.
Should a SaaS use JWT or session-based authentication?+
Most SaaS products use JWT (JSON Web Tokens) because they are stateless, work well with serverless and Edge deployments, and integrate natively with row-level security in PostgreSQL. Session-based auth is a valid alternative for monolithic deployments where immediate token revocation is a hard requirement. Supabase Auth uses JWTs with automatic refresh — the recommended approach for Next.js SaaS products.
What is role-based access control (RBAC) in a SaaS product?+
RBAC (Role-Based Access Control) is a permission model where users are assigned roles (owner, admin, member) and each role has a defined set of allowed actions. In a SaaS product, RBAC is implemented at three levels: the database layer (RLS policies check role), the API layer (middleware verifies role before executing operations), and the UI layer (components render based on role).
How do you implement OAuth in a SaaS product?+
OAuth in a SaaS product is implemented via an auth provider (Supabase Auth, NextAuth.js, or Clerk) that handles the OAuth flow with Google, GitHub, LinkedIn, or other providers. The provider handles the redirect, token exchange, and user creation. Your application receives a user record with a verified email — you then create or link the user to their organisation and membership record.
Should a SaaS product require multi-factor authentication (MFA)?+
MFA should be optional (user-configurable) in most SaaS products at MVP stage and mandatory for admin and owner roles in enterprise-tier plans. Supabase Auth supports TOTP-based MFA (Google Authenticator, Authy) out of the box. Enforce MFA at the API middleware level for sensitive operations regardless of whether the UI has enforced it.
How does 4Byte Agency implement authentication in SaaS products?+
4Byte Agency uses Supabase Auth as the primary authentication layer for all SaaS products. This provides email/password, OAuth (Google, GitHub), magic links, and TOTP MFA out of the box. JWTs are used for session management with automatic refresh. RBAC is implemented at both the database level (RLS policies) and API middleware level. Auth is set up in the first week of every build.
▸ Ship auth correctly from day one
Need your SaaS auth system built securely and fast?
We implement the full auth stack — email/password, OAuth, magic links, RBAC, MFA, and all six security controls — in the first week of every build. Using the exact patterns from this guide, refined across 45+ products.