Skip to content
All articles

Supabase

Supabase row level security patterns I actually use

12 June 2026 · 6 min read

Storing a role column on the profiles table is the most common security mistake I see in Supabase projects. If a user can update their own profile row, they can promote themselves to admin. It is that direct.

Roles belong in their own table with a unique constraint per user and role, read through a security-definer function. Policies then call that function instead of joining the table directly, which also avoids recursive policy evaluation.

Grants are the second trap. Enabling RLS is not enough — PostgREST needs explicit grants on public schema tables, and the grants should match your policies. If every policy scopes to the authenticated user, do not grant anything to anon.

Write tests that attempt escalation from each role. A policy suite you have never tried to break is a guess, not a guarantee.

Need this done in your project?

I take on automation, integration and rescue work for teams that need it shipped properly.

Start a conversation