| name | supabase-rls-policies |
| description | Use when creating or modifying Row Level Security policies |
Supabase Row Level Security (RLS) Policies
Row Level Security controls which rows users can access. Always enable RLS on tables with user-specific or organization-scoped data.
Core Syntax
ALTER TABLE public.projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY "policy_name"
ON schema.table_name
FOR operation
TO authenticated
[USING (condition)]
[WITH CHECK (condition)];
Organization-Scoped Policy Pattern
CREATE POLICY "Organization members can view projects"
ON public.projects FOR SELECT TO authenticated
USING (
EXISTS (
SELECT 1 FROM public.organization_members
WHERE organization_members.organization_id = projects.organization_id
AND organization_members.user_id = (SELECT auth.uid())
)
);
Common Patterns
CREATE POLICY "Users can read own profile"
ON public.profiles FOR SELECT TO authenticated
USING ((SELECT auth.uid()) = id);
CREATE POLICY "Anyone can read" ON public.posts FOR SELECT TO public USING (true);
CREATE POLICY "Authenticated can create" ON public.posts FOR INSERT TO authenticated
WITH CHECK ((SELECT auth.uid()) = user_id);
⚠️ CRITICAL: Performance Optimization
Always wrap auth.uid() in SELECT subquery - without it, evaluated per-row (99% slower):
WHERE user_id = (SELECT auth.uid())
WHERE user_id = auth.uid()
Real-world impact: 170ms → 178,000ms on 100K rows without optimization.
Best Practices
- Always use explicit TO clause -
TO authenticated not omitted (defaults to TO public)
- Use
(SELECT auth.uid()) - wrapped in subquery for performance
- Create separate policies per operation - SELECT, INSERT, UPDATE, DELETE
- Use EXISTS subqueries for organization/membership checks
- Add indexes on policy columns - critical for performance
- Test policies - as authenticated and anonymous users
Verification
cd spark/frontend/my-vite-app && supabase db lint
Check for 0003_auth_rls_initplan warning (auth.uid() not optimized).
Docs: https://supabase.com/docs/guides/database/database-advisors?lint=0003_auth_rls_initplan