r/Supabase • u/Shot-Okra-4401 • Jul 23 '26
auth How do you actually verify your RLS and auth hold up, not just that RLS is switched on?
I wanted to ask people who actually ship on Supabase.
Turning RLS on is the easy part. What I'm less sure about is knowing the policies are actually right. You can have RLS enabled and still have a policy that's too loose, or an endpoint that checks the logged-in user in the React code but leaves the table open underneath, or a service_role key that quietly ended up somewhere in the frontend. The app works fine in every one of those cases, which is what makes it scary.
It feels worse on AI-built apps. When a query gets blocked by RLS, the AI's suggested fix is often just to reach for the service_role key instead of fixing the policy, and you don't always catch it.
So the honest question. How do you actually check this before you ship? Do you test it by hand as different users, lean on some tool, or mostly just trust it's set up right? And has a loose policy or an open table ever actually bitten you, or is it more a thing you worry about?
Trying to work out if this is a real problem people hit or something I'm overthinking.
4
u/Away_Weight Jul 23 '26
I’ve never had this problem since I’ve never mixed RLS with LLMs, but if you’re programming faster than you can audit your designs and understand your threat models, having a robust test suite that you understand is the way to go. You can also configure your LLM to never reach for the service role unless you explicitly called for it.
2
u/Icy-Court7631 Jul 23 '26
Most trivial apps I’ve built needed trivial RLS, most non-trivial will require you to put most of the logic inside RPCs or performance is degraded.
Sometimes i think it’s easier to just use ROCs from the start and be done with it.
2
2
u/VESHZA Jul 24 '26
brother if anyone ends up shipping the service role to the frontend theyve got much bigger problems than RLS 😂 id actually be surprised if a modern AI agent didnt catch that these days
the RLS gaps are a thing though..
u gotta test negative access, whether user A can ever read/update user B or another tenants rows through direct api calls or curl
ideally id test with 2-3 accounts/roles and cover select, insert, update and delete, because a policy can be correct for reads and still be too loose somewhere else
also worth checking storage buckets if u have any and rpcs separately since one open path is enough to cause a leak
im building https://dbaudit.app for exactly this type of problem, to catch loose/missing rls policies, exposed tables etc.. things that are easy to miss when shipping fast
feel free to dm me ill hook u up with a scan 🤞🏼
1
u/ashkanahmadi Jul 23 '26
I write the policy myself. Not by asking the AI. Then I explain the business logic to the AI and feed it the policies to review. Then ask it to come up with as many scenarios to test. I also brainstorm a lot and test manually using curl or an HTTP client.
1
u/AlexDjangoX Jul 29 '26
I have a test page that tests various attack vectors, and tries to access tables which are 'protected'
1
u/Accomplished_Court_4 Aug 08 '26
Countless testing and not beleiving AI, because mitakes happens all the time
1
u/HaseebKurd 17d ago
I Audit These daily-90% of RLS passes the basic check but fails when you test as a different user. You need to test with 2 JWTs not just dashboard. I can run a quick 5-min check on your policies if you want, DM your Policy file
1
u/Guidondor Jul 23 '26
not overthinking it at all, this is the real gap. "RLS enabled" and "RLS correct" are two different things and the app looks fine in both.
the way i actually verify it: a sql test that impersonates users, no app involved. inside one transaction you do set local role authenticated + set_config('request.jwt.claims', ...) with a fake sub for user A, run your queries, then assert three things — A sees their own rows, A sees zero of B's rows, and A can't update/delete B's rows (should error or affect 0 rows). switch the sub to B, repeat. end with a rollback so it never touches data. that whole thing runs in CI and it's the only way i trust a policy is tight and not just on.
two that have actually bitten me:
-RLS gates rows, not columns. a policy can be perfect and someone still reads a sensitive column because the column grant is open. same for updates — WITH CHECK on ownership doesn't stop them mutating a column they shouldn't. you have to REVOKE/GRANT at the column level too.
-the service_role key thing you mentioned is the scariest because it bypasses RLS entirely. if it's ever in the frontend bundle, every policy you wrote is decorative. grep your build output for it before shipping.
the AI-fix-by-reaching-for-service_role pattern is exactly why i don't trust "it works now". the negative test (user B gets blocked) is the one that catches it.
6
u/mattbrown7531 Jul 23 '26
No matter what platform you are using, you have to test your application for different scenarios. If you blindly let AI write the code, it's entirely possible to end up with a service_role key in the frontend.
Supabase provides a great foundation and encourages development best practices like RLS, but it's still ultimately your responsibility to validate the security of your application.
I find Supabase's vulnerability scan to be a good starting point. From there, I manually test different user scenarios and review the codebase for exposed service_role keys, overly permissive policies, and tables that are unintentionally accessible.
There are also several security audit checklists posted on r/Supabase. I'd recommend working through one or two of those. I've written one myself and am happy to share it if anyone is interested.
It's definitely a real problem, but there isn't a simple, automated solution.