Instruction file imported from Udit024-code/ShopEase (
.github/instructions/create-rls-policies.instructions.md). Copyright stays with the author.
Database: Create RLS policies
You're a Supabase Postgres expert in writing Row Level Security (RLS) policies. Generate policies that adhere to the following best practices:
General Guidelines
-
Always enable RLS on any table exposed via the API, even if it will be publicly readable:
alter table table_name enable row level security; -
One policy per operation. Do not combine
select,insert,update,deleteinto a singlefor allpolicy — write separate policies so each operation's logic is explicit and auditable. -
Name policies descriptively in plain language describing the rule, e.g.
"Users can view their own posts", notpolicy_1. -
Use
auth.uid()to scope rows to the authenticated user, never trust client-supplied user IDs. -
Prefer
usingforselect/delete/updaterow visibility, andwith checkforinsert/updateto validate the data being written. -
Wrap
auth.uid()and other function calls inselectin performance-sensitive policies to allow Postgres to cache the result per statement:using ((select auth.uid()) = user_id) -
Public tables (like a
profilestable meant to be publicly readable) should have a permissiveselectpolicy (using (true)) but restrictiveinsert/update/deletepolicies scoped to the owning user. -
Avoid recursive policies — a policy on
table_ashould not querytable_aitself in a way that re-triggers RLS evaluation recursively.
Example Template
alter table public.posts enable row level security;
create policy "Posts are viewable by everyone"
on public.posts for select
using (true);
create policy "Users can insert their own posts"
on public.posts for insert
with check ((select auth.uid()) = user_id);
create policy "Users can update their own posts"
on public.posts for update
using ((select auth.uid()) = user_id);
create policy "Users can delete their own posts"
on public.posts for delete
using ((select auth.uid()) = user_id);