Supabase Authentication

Implement secure authentication with email/password, OAuth, magic links, and database-level access control through Row Level Security

Why Supabase Authentication?

Modern applications require authentication that balances security, user experience, and developer productivity. Supabase Authentication provides a comprehensive identity solution that integrates directly with your PostgreSQL database through Row Level Security, offering a compelling alternative to Firebase Authentication for teams who value SQL's power and flexibility. When building web applications with Supabase, embedding access control at the database layer significantly reduces backend complexity.

Unlike standalone auth providers that treat authentication as an isolated service, Supabase embeds access control into your data layer. This means your authorization logic lives where your data lives--simplifying architecture and eliminating the need for separate authorization services. This architectural approach reduces complexity in your application stack. Rather than maintaining separate authentication and authorization services that must communicate and stay synchronized, you define access policies directly in your database. The result is fewer moving parts, clearer security logic, and confidence that database-level enforcement cannot be bypassed.

When you combine Supabase Auth with Row Level Security, you create a security model where access decisions happen at the database layer. Policies evaluate against authenticated user context automatically, ensuring that no matter how your API is accessed, the same access rules apply consistently across all entry points.

Authentication Methods

Multiple ways to authenticate users with enterprise-grade security

Email & Password

Traditional credential-based authentication with configurable password policies and security requirements

OAuth 2.1

Support for 25+ social providers including Google, GitHub, Apple, and Microsoft with PKCE flow

Magic Links

Passwordless authentication via secure, time-limited email links for seamless user experience

Multi-Factor Auth

TOTP support for additional security layer on top of primary authentication

Email and Password Authentication

Email and password authentication remains the foundation of most web and mobile applications. Supabase Auth implements this with industry-standard security practices, including bcrypt password hashing with salt stretching, secure token generation, and configurable security policies. For email/password authentication, Supabase supports several configuration options that help balance security with user experience. You can require email confirmation before users can sign in, customize confirmation email templates with your branding, and configure password strength requirements that align with your security policies.

Implementation Overview

Supabase provides client SDKs for JavaScript, Swift, Kotlin, and Dart that abstract authentication complexity. With just a few lines of code, implement sign-up, sign-in, password reset, and account recovery flows. The SDK handles session management automatically, storing tokens securely and refreshing them before expiration. The JavaScript client integrates naturally with React, Vue, and other frameworks through reactive authentication state that your components can subscribe to.

Sign-up flows support optional metadata that gets stored with the user profile. This allows you to capture information like full name, avatar URL, or custom attributes during registration without additional database writes. Password reset follows a secure flow where users receive time-limited links to create new credentials, with configuration options for redirect URLs and email templates.

Security Configuration

Password security begins with appropriate complexity requirements. Configure minimum password lengths, require special characters or numbers, and implement breach detection that prevents commonly exposed passwords. These configurations help establish a security baseline while remaining flexible enough to accommodate different user populations. The confirmation email flow serves as both a verification mechanism and a welcome communication--you can customize these emails to match your brand voice, include helpful resources, and configure the confirmation link's behavior.

Supabase's authentication documentation covers additional security options including automatic account linking when users attempt to sign in with multiple authentication methods, and configurable session durations for organizations with specific compliance requirements.

Email/Password Sign Up Example
1import { createClient } from '@supabase/supabase-js'2 3const supabase = createClient(4 'https://your-project.supabase.co',5 'your-anon-key'6)7 8// Sign up with email and password9const { data, error } = await supabase.auth.signUp({10 email: '[email protected]',11 password: 'secure-password-123',12 options: {13 emailRedirectTo: 'https://yourapp.com/welcome',14 data: {15 full_name: 'John Doe'16 }17 }18})19 20if (error) {21 console.error('Sign up error:', error.message)22}

OAuth and Social Login

Social authentication reduces friction for users who prefer not to create another password. Supabase Auth supports over 25 OAuth providers, including major platforms like Google, GitHub, Apple, Microsoft, and Facebook, plus enterprise identity systems like Azure Active Directory and Okta.

Provider Configuration

Each OAuth provider requires configuration through the provider's developer console and Supabase's authentication settings. The process involves creating an application in the provider's portal, obtaining client credentials, and configuring redirect URLs that Supabase will use during the authentication flow. Once configured, enabling a provider requires only a simple API call or dashboard configuration--no additional code changes are necessary for most providers.

Supabase implements OAuth 2.1 with PKCE (Proof Key for Code Exchange) for improved security in public clients. PKCE prevents authorization code interception attacks by requiring the client to prove it initiated the request, making it ideal for single-page applications and mobile apps where client secrets cannot be securely stored.

Scopes and User Data

OAuth providers return different user information based on the scopes your application requests. Supabase normalizes this data into a consistent format, extracting email addresses, profile information, and profile images when available. You can request additional scopes to access more user data--for example, requesting repository access from GitHub or calendar access from Google. Some providers require approval before granting extended scopes, particularly for accessing private user data.

The platform also supports custom OAuth providers for organizations using identity systems beyond pre-configured options. Whether integrating with a legacy SAML service or a specialized identity provider, Supabase's extensibility accommodates diverse authentication requirements. For enterprise environments, SAML and OpenID Connect integrations enable centralized authentication policy management through existing identity infrastructure. When implementing OAuth for your SEO-optimized web application, leveraging social login can improve user registration conversion rates and reduce friction that leads to bounce.

Compare Supabase's OAuth implementation with other backend-as-a-service platforms in our Supabase vs Firebase guide to understand the architectural differences.

OAuth Sign In Example
1import { createClient } from '@supabase/supabase-js'2 3const supabase = createClient(4 'https://your-project.supabase.co',5 'your-anon-key'6)7 8// Sign in with OAuth provider9const { data, error } = await supabase.auth.signInWithOAuth({10 provider: 'github',11 options: {12 redirectTo: 'https://yourapp.com/auth/callback',13 scopes: 'repo user email',14 queryParams: {15 access_type: 'offline',16 prompt: 'consent'17 }18 }19})

Magic Links and Passwordless Authentication

Passwordless authentication eliminates password-related security risks entirely. Supabase sends secure, time-limited links that grant access when clicked, improving security while reducing user friction for users who find password creation and management cumbersome.

How Magic Links Work

When a user requests a magic link, Supabase generates a unique token tied to their email and sends it via email. The link contains this token and a redirect URL. When clicked, the token validates and creates an authenticated session. Tokens expire after a configurable duration--typically one hour--and can only be used once, preventing replay attacks. This approach reduces abandonment rates while improving security posture by removing password storage from the equation.

Magic links integrate naturally with Supabase's broader authentication ecosystem. Users who authenticate via magic link can later sign in with a password if they choose to set one, and their account automatically links to their email address. This flexibility accommodates different user preferences without fragmenting your user base.

One-Time Passwords (OTP)

For scenarios where email delivery might be delayed or users prefer not to open email clients, Supabase supports OTPs via SMS. Like magic links, OTPs are time-limited and single-use, providing similar security guarantees with a different user experience. SMS-based OTP requires configuration for SMS providers--Supabase supports Twilio, MessageBird, and Vonage--and incurs per-message costs that vary by destination country.

The choice between magic links and SMS OTP depends on your user population and security requirements. Magic links work well for most consumer applications where email access is reliable. SMS OTP suits high-value transactions or enterprise scenarios where immediate verification matters more than email delivery times. Both methods eliminate password-related vulnerabilities while providing secure, frictionless authentication.

See the Supabase passwordless authentication documentation for implementation details and best practices.

Magic Link Sign In Example
1import { createClient } from '@supabase/supabase-js'2 3const supabase = createClient(4 'https://your-project.supabase.co',5 'your-anon-key'6)7 8// Send magic link for passwordless sign-in9const { data, error } = await supabase.auth.signInWithOtp({10 email: '[email protected]',11 options: {12 emailRedirectTo: 'https://yourapp.com/welcome',13 shouldCreateUser: false14 }15})16 17// Check the link in the user's email and click it18// The user will be automatically signed in after clicking

Session Management and JWT Handling

Authenticated sessions require careful management to balance security with user experience. Supabase Auth issues JWTs (JSON Web Tokens) that encode user identity and session information, enabling stateless authentication that scales horizontally without requiring centralized session stores.

Token Structure

Supabase JWTs contain standard claims including user ID, email, and session expiration, along with custom claims that enable Row Level Security policies. These custom claims include the authenticated user's role, which RLS policies reference for access decisions. The token structure follows JWT standards, making it compatible with JWT validation libraries across programming languages.

Each JWT includes an expiration time--defaulting to one hour--that limits exposure if compromised. Supabase automatically refreshes tokens before expiration when users are actively using your application, requiring no additional configuration. For applications requiring longer sessions, you can configure extended expiration times, though shorter durations provide better security.

Client-Side Session Handling

The Supabase JavaScript client manages sessions automatically, storing tokens in localStorage by default and providing reactive authentication state that components can subscribe to. This reactive pattern integrates naturally with modern frontend frameworks like React, Vue, and Svelte, enabling authenticated UI states without manual state management. The client also handles token refresh automatically, detecting when sessions are about to expire and requesting fresh tokens proactively.

For server-side applications or API routes that need to validate authenticated requests, Supabase provides helper functions that extract and verify tokens from request headers. These helpers validate token signatures against Supabase's signing keys, ensuring requests originate from authenticated sessions. Combined with Row Level Security, this creates a defense-in-depth approach where both API validation and database policies enforce access control.

Session storage options include localStorage for web applications, secure memory storage for server-side use, and platform-specific secure storage for mobile applications. Choose based on your security requirements and platform constraints. For AI-powered applications built with Supabase, secure session management is critical when your AI agents need to act on behalf of authenticated users.

Session Management Example
1import { createClient } from '@supabase/supabase-js'2 3const supabase = createClient(4 'https://your-project.supabase.co',5 'your-anon-key'6)7 8// Listen to auth state changes9supabase.auth.onAuthStateChange((event, session) => {10 if (event === 'SIGNED_IN') {11 console.log('User signed in:', session?.user)12 console.log('Access token:', session?.access_token)13 }14 if (event === 'SIGNED_OUT') {15 console.log('User signed out')16 }17 if (event === 'TOKEN_REFRESHED') {18 console.log('Token refreshed')19 }20})21 22// Get current session23const { data: { session } } = await supabase.auth.getSession()24 25// Get user from session26const { data: { user } } = await supabase.auth.getUser()27 28// Sign out29await supabase.auth.signOut()

Row Level Security Integration

Row Level Security represents Supabase's most significant architectural advantage. Rather than separating authentication from authorization, Supabase integrates access control directly into the database layer using PostgreSQL's native RLS feature. RLS policies are SQL expressions that evaluate against the authenticated user's context. When a user queries a table with RLS enabled, PostgreSQL evaluates the policy for that table, automatically filtering results based on user identity. This happens at the database level--bypass is impossible, even for administrative users or direct database connections.

How RLS Works with Auth

Supabase Auth populates special session variables that RLS policies can reference. The auth.uid() function returns the current user's ID, while auth.role() returns their assigned role. These functions enable policies that grant access based on user identity rather than application-level checks. For user-owned resources, a typical policy reads: "Users can read rows where the user_id column equals auth.uid()." This single line of SQL enforces ownership at the database level.

Policy Examples

More complex policies can reference related tables, aggregate data, or implement role-based access patterns. Organization-owned resources might check that the user's organization ID matches the resource's organization ID, while admin role policies grant broader access using a role check. For tenant isolation in multi-tenant applications, policies can join across tables to verify membership before granting access.

-- Users can read their own posts
CREATE POLICY "Users can read own posts" ON posts
 FOR SELECT
 USING (auth.uid() = user_id);

-- Users can update their own posts
CREATE POLICY "Users can update own posts" ON posts
 FOR UPDATE
 USING (auth.uid() = user_id)
 WITH CHECK (auth.uid() = user_id);

-- Admins can see all posts
CREATE POLICY "Admins can view all posts" ON posts
 FOR SELECT
 USING (
 EXISTS (
 SELECT 1 FROM user_roles
 WHERE user_roles.user_id = auth.uid()
 AND user_roles.role = 'admin'
 )
 );

Test RLS policies thoroughly before deployment. The Supabase Dashboard provides a RLS Policy Debugger that lets you simulate queries as different users to verify policy behavior. Start with read policies, verify results return only expected data, then test write operations. This testing approach catches misconfigurations before they affect production users.

Multi-Factor Authentication

Multi-factor authentication adds critical security for sensitive accounts. Supabase Auth supports TOTP (Time-based One-Time Password) as a second factor through authenticator apps like Google Authenticator, Authy, or 1Password.

TOTP Implementation

TOTP requires users to configure a second factor by scanning a QR code with their authenticator app. Once configured, users must provide a valid TOTP code during sign-in, which the server validates against the stored secret. This requirement significantly increases security because an attacker needs both the user's password and their authenticator device. Supabase manages TOTP secrets securely and handles the validation workflow automatically through the client SDK.

Application developers configure whether MFA is required for specific users or roles. You might require MFA for admin accounts while making it optional for regular users, or integrate MFA enrollment prompts at strategic points in your user journey. The SDK handles the multi-step authentication flow without requiring additional code for the enrollment and verification sequences.

Enterprise SSO

For enterprise deployments requiring stronger authentication, Supabase offers SAML and OpenID Connect integration. These enable organizations to enforce MFA through existing identity infrastructure, centralizing authentication policy management. Enterprise SSO integrates with identity providers like Azure Active Directory, Okta, Auth0, and Ping Identity, allowing centralized user management and compliance with organizational security policies.

Implementing MFA protects sensitive operations and data. Combined with Row Level Security, multi-factor authentication creates layered defense where database policies enforce access control regardless of how authentication occurred. Users must verify their identity through multiple factors, and RLS policies ensure they can only access data appropriate to their role and ownership.

MFA Enrollment Example
1import { createClient } from '@supabase/supabase-js'2 3const supabase = createClient(4 'https://your-project.supabase.co',5 'your-anon-key'6)7 8// Enroll user in MFA9const { data: enrollment, error: enrollError } = await supabase.auth.mfa.enroll({10 factorId: 'totp'11})12 13if (enrollment) {14 // Show QR code to user15 console.log('QR Code:', enrollment.totp.qr_code)16 console.log('Secret:', enrollment.totp.secret)17}18 19// Verify the TOTP code after user scans QR20const { error: verifyError } = await supabase.auth.mfa.verify({21 factorId: enrollment.id,22 code: '123456' // User enters this from their authenticator app23})

Frequently Asked Questions

Ready to Build with Supabase?

Get started with Supabase Authentication and build secure, scalable applications with integrated database access control.