I kept writing RLS tests by hand and realized most weren't proving much.
The problem is the data, not the test. Run a SELECT as an authenticated user with no row your policy would actually let through, and the test passes against nothing. The deny case is worse: "0 rows returned" looks like a pass but proves zero. So a green RLS suite can quietly be running against empty tables.
So I built rlsautotest. You point it at your database, it reads your policies from the catalog, and here's what it does:
supabase test db runs it. It's basejump-aware, with a --no-helpers self-contained mode.Being upfront about the limits: it proves your RLS does what your policies say, not that your policies are the right ones (that call stays with you). And if a policy calls a permission function it can't see into, you get proof it's wired in, not a test of the logic inside.
Open source, pip install rlsautotest. I'm mostly after feedback on policy patterns it doesn't handle yet, so if you point it at a real schema and it chokes, that's exactly what I want to hear. Happy to drop the repo link below.
The user has developed a tool named 'rlsautotest' that generates pgTAP RLS tests and seed data from database policies. The tool is designed to ensure tests run against actual data, covering various user roles and preventing common security oversights. The user seeks feedback on policy patterns that the tool may not handle effectively.
Repo: https://github.com/unitautogen/rlsautotest - if it can't handle a policy on a real schema, reply here or open an issue. That's the feedback I'm after.
Proving that the rules you wrote are the rules that are enforced isn't very useful. You said your tests 'weren't proving much', how is this proving more? You need smarter tests, not more of them. That said, access matrix is nice.
"Enforced as written" isn't trivial in RLS. What's actually enforced is every permissive and restrictive policy combined, plus whether RLS is even on. You can write a clean per-user policy and still have a second permissive one quietly making every row readable. Reading your policies misses that; asserting the real behavior catches it.
And hand-written tests don't prove much because they run against empty rows. This generates the data plus a real different-tenant user for the deny case, so the test can actually fail. That negative control is the smarter test you're asking for. No tool proves you wrote the policy you meant, but "does my DB actually enforce what I wrote" is where the leaks are.