Scan rule · RSC-SEC-066
RLS policy checks only that someone is signed in
Finds policies using `auth.role() = 'authenticated'` or `auth.uid() is not null` without binding to the row owner.
Why this matters
This is the most common tenant-isolation leak in AI-built Supabase apps, and the least visible one. The policy requires that somebody is signed in, but not that the row belongs to them. Anyone who creates an account reads everyone else's data.
From the outside it is invisible: the anonymous role gets nothing from this policy, the table returns zero rows and looks clean in any external scan. Only a signed-in account reveals the difference, which is why this slips past almost every check.
Fix: bind every condition to auth.uid(), typically `auth.uid() = user_id`. For shared records, check a membership table rather than the bare role. Do it per operation — SELECT, INSERT, UPDATE and DELETE have separate conditions.
Scan tier
How to fix it
Bind the condition to identity: `using (auth.uid() = user_id)`.