Supabase RLS: a small, evidence-first pre-launch check
RLS being enabled is only the first check. A useful review asks what an anonymous request, an authenticated user, and a second tenant can actually read or write.
Five checks worth running
- List every exposed table and confirm RLS is enabled.
- Inspect both
USINGandWITH CHECK; a read policy does not automatically secure inserts or updates. - Look for policies that are intentionally broad, such as
USING (true), and confirm they are limited to the correct role and table. - Review
SECURITY DEFINERfunctions, theirsearch_path, and theirEXECUTEgrants. - Test the live database with two separate user identities. Confirm that user A cannot read or modify user B's rows, even when the request is made directly against the REST endpoint.
Example owner-scoped policy:
alter table public.orders enable row level security;
create policy "orders_select_own"
on public.orders
for select to authenticated
using (auth.uid() = user_id);
create policy "orders_insert_own"
on public.orders
for insert to authenticated
with check (auth.uid() = user_id);
Use a service-role key only in a trusted server-side path. Never put it in browser code, migrations, screenshots, or a public issue.
The free RLS isolation fixture demonstrates the two-user negative-test pattern. If you want a human second set of eyes, the 24-hour, three-table review is a focused configuration review using sanitized schema and policy SQL only.
This is a configuration review, not a penetration test or a security certification. Test only systems you own or are explicitly authorized to review.
Top comments (0)