Skip to main content
Row Level Security (RLS) is PostgreSQL’s built-in authorization system that controls which rows users can access in database tables. Supabase leverages RLS to provide fine-grained access control.

Why Use RLS?

RLS provides several advantages:
  • Security at the Database Level: Policies are enforced by PostgreSQL, not your application
  • Fine-Grained Control: Control access per row based on user identity
  • Automatic Enforcement: Works automatically with all Supabase client libraries
  • Zero Trust: Even compromised API keys can’t bypass RLS
Always enable RLS on tables containing user data. Without RLS, anyone with your anon key can access all data.

Enable RLS

Enable Row Level Security on a table:
When RLS is enabled without any policies, no one (except service role) can access the table. You must create policies to allow access.

Basic Policies

Public Read Access

Allow anyone to read all rows:

User-Specific Access

Users can only read and update their own data:

Helper Functions

Supabase provides helper functions for RLS policies:

auth.uid()

Returns the current user’s ID:

auth.jwt()

Access the full JWT token:

Policy Examples

Authenticated Users Only

Owner-Based Access

Team-Based Access

Users can access data belonging to their team:

Time-Based Access

Hierarchical Access

Advanced Policies

Policy with Joins

Multiple Conditions

Separate Policies by Operation

Bypass RLS

Service Role

The service role key bypasses RLS:
Never expose the service role key in client-side code. Only use it in secure server environments.

Security Definer Functions

Create functions that run with elevated privileges:

Testing RLS Policies

Test as Different User

Using Supabase Client

Debugging RLS

Check which policies apply:
Enable query logging to see RLS in action:

Common Patterns

Public Read, Authenticated Write

Soft Deletes with RLS

Admin Override

Performance Considerations

Always index columns used in RLS policies:
Complex subqueries in policies can slow down queries. Consider denormalizing data or using materialized views.
Security definer functions bypass RLS and can be security risks if not carefully written.

Best Practices

Enable RLS Always

Enable RLS on all tables with user data

Test Thoroughly

Test policies as different users and roles

Keep Policies Simple

Simple policies are easier to understand and debug

Document Policies

Add comments explaining complex policy logic

Next Steps

Storage Security

Apply RLS concepts to file storage

Database Guide

Learn more about PostgreSQL features