A wrong RLS policy doesn't throw an error, it just returns the wrong rows, so it ships untested and you find out when data leaks. rlsautotest gener...
For further actions, you may consider blocking this person and/or reporting abuse
The zero-rows versus permission-error split is a distinction most write-ups skip, glad you kept them apart. Does the generator also walk views and security definer paths? The leaks I've hit lived there, not in the table policies.
Straight answer: not yet. It walks base tables and their policies today, not views or SECURITY DEFINER paths. Both are exactly where rights get swapped for the owner's: a view without security_invoker runs as its owner and skips the base table's RLS, and a SECURITY DEFINER function runs as the definer unless it re-checks auth. A tool that stops at the table catches neither, which is why that's where I want to take it next. If you've got a sanitized example that bit you, I'd love it as a test case.
Here's a clean one to seed: a base table with per-user RLS, then a reporting view over it for some dashboard, created without security_invoker. The view runs as its owner, so PostgREST serves it straight to anon and every user's email comes back, and the base table's RLS never gets consulted. The tell you could assert on is that exact pair: a view whose base table has relrowsecurity and policies, but the view itself isn't security_invoker. Green base table, wide-open view.
Ok. I will work around your description to create the scenario. This should be mostly be fixed by next week. Will keep you posted. MEanwhile if you want to track it in github, i would encourage you to log enhancement over there. Here is the repo link- github.com/unitautogen/rlsautotest
@vollos - One ask if you are ok to answer. Do you face issues around unit testing your functions and triggers? How do you ensure proper code coverage and track the metrics?
Glad the view case is worth chasing. On your question, honest answer: coverage metrics aren't really my beat. I spend more time reviewing other people's code for security than maintaining a big suite of my own, so I'm not the one with a coverage regime to model. From the review side though, functions and triggers are the least-tested surface I see in AI-built Supabase apps, usually zero tests at all. And where there is coverage, line coverage misses the case that bites: whether the function ever ran as an identity that shouldn't be allowed. A SECURITY DEFINER function can be 100% line-covered and never once exercised against the wrong caller. So the thing I'd track is coverage by identity, not by lines.
Silent failures in RLS are definitely one of the biggest foot guns when migrating from a traditional backend to Supabase. I usually tackle this by writing custom PL/pgSQL functions that explicitly assert the expected row counts and throw exceptions if the policy logic falls short during CI. Another approach that has saved me a lot of debugging time is using the Supabase CLI to run local migrations with seed data specifically designed to trigger edge cases in the policies. Have you found a specific testing library or framework that integrates better with Jest or Vitest for mocking the auth context during these RLS tests?
Honestly, I haven't found a Jest/Vitest library I'd trust here, because there's nothing to mock. auth.uid()/auth.jwt() just read request.jwt.claims and the current role, so the only faithful way to impersonate is on a real session: SET LOCAL ROLE authenticated + set_config('request.jwt.claims', '{"sub":...}', true), query, assert, roll back. Mock it in JS and you're testing the mock, not the policy. From Vitest that's a pg client, one transaction per test, set role and claims, assert, rollback. It's also why I emit pgTAP: the assertion runs in the same session as the policy, so nothing gets faked.
Your instincts are already right, by the way. The throwing PL/pgSQL asserts are hand-rolled pgTAP, and those edge-case seeds are the part that quietly rots when a policy changes.