Supabase Row Level Security (RLS)
The complete guide to implementing RLS in Supabase. Protect your data with proper policies.
Test Your RLS ConfigurationCritical: RLS is Disabled by Default
Supabase creates tables with RLS disabled by default. In January 2025, 170+ apps built with Lovable were found to have exposed databases (CVE-2025-48757) because developers didn't enable RLS. 83% of exposed Supabase databases involve RLS misconfigurations.
Quick Start: Enable RLS in 2 Minutes
1Enable RLS on Your Table
-- Enable RLS on the table
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;2Create a Policy for Authenticated Users
-- Users can only see their own data
CREATE POLICY "Users can view own data"
ON your_table
FOR SELECT
TO authenticated
USING ((select auth.uid()) = user_id);
-- Users can only insert their own data
CREATE POLICY "Users can insert own data"
ON your_table
FOR INSERT
TO authenticated
WITH CHECK ((select auth.uid()) = user_id);
-- Users can only update their own data
CREATE POLICY "Users can update own data"
ON your_table
FOR UPDATE
TO authenticated
USING ((select auth.uid()) = user_id);
-- Users can only delete their own data
CREATE POLICY "Users can delete own data"
ON your_table
FOR DELETE
TO authenticated
USING ((select auth.uid()) = user_id);Important: Use (select auth.uid()) instead of auth.uid() for better performance. The select wrapper prevents re-evaluation on every row.
3Test Your Policies
-- Test as anonymous user (should return 0 rows)
SELECT * FROM your_table;
-- Or use the Supabase Dashboard:
-- Authentication → Policies → Test your policiesCommon RLS Patterns
User-Owned Data
Most common pattern - each user can only access their own rows:
CREATE POLICY "Users own their data"
ON posts
FOR ALL
TO authenticated
USING ((select auth.uid()) = author_id);Public Read, Private Write
Anyone can read, but only owners can modify:
-- Anyone can read
CREATE POLICY "Public read access"
ON posts
FOR SELECT
TO anon, authenticated
USING (true);
-- Only owners can write
CREATE POLICY "Owners can modify"
ON posts
FOR UPDATE
TO authenticated
USING ((select auth.uid()) = author_id);Team-Based Access
Users can access data belonging to their team:
CREATE POLICY "Team members can access"
ON projects
FOR ALL
TO authenticated
USING (
team_id IN (
SELECT team_id FROM team_members
WHERE user_id = (select auth.uid())
)
);Common RLS Mistakes
Forgetting to enable RLS
Creating policies without enabling RLS does nothing. Always run:
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;Using auth.uid() without select wrapper
This causes performance issues - the function re-evaluates for every row:
-- Bad: USING (auth.uid() = user_id)-- Good: USING ((select auth.uid()) = user_id)Creating service_role policies
Service role bypasses RLS automatically. Adding a policy for it creates warnings:
-- Bad: Creates multiple_permissive_policies warning-- Good: Just use TO authenticated (service_role bypasses RLS)Enabling RLS without any policies
RLS with no policies = no one can access data, not even authenticated users. Always create at least one policy after enabling RLS.
How to Test Your RLS
Manual Testing
- Go to Supabase Dashboard → SQL Editor
- Run
SELECT * FROM your_table - As anon role, should return 0 rows (unless public)
- Test with different user JWTs
- Try INSERT/UPDATE/DELETE operations
Automated Testing
Use Vibe App Scanner to automatically test your deployed app:
- Tests real-world RLS behavior
- Attempts unauthorized data access
- Checks all tables for misconfigurations
- Provides remediation guidance
RLS Security Checklist
Frequently Asked Questions
What is Supabase Row Level Security?
Supabase Row Level Security (RLS) is a PostgreSQL feature that lets you control which rows users can access in your database. You create policies that define rules like "users can only read their own data" using SQL conditions. It's the primary way to secure your Supabase database.
Is RLS enabled by default in Supabase?
No, RLS is disabled by default when you create tables in Supabase. You must manually enable RLS on each table using ALTER TABLE table_name ENABLE ROW LEVEL SECURITY and then create policies. This is the #1 cause of security issues in Supabase apps.
What happens if I enable RLS but don't create policies?
If you enable RLS without creating any policies, no one can access the data - not even authenticated users. RLS with no policies means "deny all access by default." You must create at least one policy to allow access.
Test Your Supabase RLS Configuration
Don't guess whether your RLS is configured correctly. Scan your deployed app to find misconfigurations before attackers do.
Get Starter ScanLast updated: January 15, 2026