Live demo of the Whirlwind template, as shippedStripe test mode: card 4242 4242 4242 4242, any future date, any CVCGet Whirlwind →

Row-Level Security

Default RLS policies and how to extend them.

Row-level security

Every table the template creates has RLS enabled, so a bug in application code cannot read another user's rows. Server routes that need to cross users, such as the Stripe webhook, use the service role key, which bypasses RLS and never reaches the browser.

The mapping

Supabase gives you auth.uid(). Template tables reference public.users.id. Policies map between them:
create policy "read own" on public.usage
  for select using (
    user_id = (select id from public.users where auth_user_id = auth.uid())
  );

Test it

The Playwright flow tests include an RLS check: a second user attempting to read the first user's usage row must get nothing back. npm run audit fails on any table without RLS enabled.