I made a free tool that proves your Supabase RLS actually isolates tenants — as a test in your CI
Row-level security is the thing everyone knows they should have and it's the thing that quietly gets forgotten on one table, or shipped as USING (true), or bypassed by a service-role client. You don't find out until someone reads another tenant's data.
I built a small MIT-licensed tool for exactly this footgun, and I wanted to share it here since it's Supabase-shaped:
npx tenant-guard
Two parts:
- Static guards (zero-dependency, run in CI) that flag the classic leak shapes: an authenticated route that loads a row by bare
idwith noorganization_idfilter, and newSECURITY DEFINERfunctions left callable byanonover PostgREST (revoking fromanonalone is a no-op, it catches that). - A runtime RLS proof, point it at a seeded test/branch database and it drops to the
authenticatedrole, assumes one tenant's identity via your JWT claims, and asserts that session can't see another tenant's rows, table by table. If a policy is missing or wrong, the build fails.
There's a demo you can run in 10 seconds with no infra (it uses an embedded Postgres): it passes a correct policy and fails a leaky one.
Honest disclosure: I built it, it's free, no signup/telemetry, and I'm posting because I think it's genuinely useful for this community, not selling anything. It's sharp for Supabase/Postgres specifically. Feedback on the becomeTenant config (how it assumes a tenant's identity for your policies) would be especially useful, that's the part that varies most between apps.
It might not work on any project but it did work on the projects I tested it on