Good catch on the "the an ecommerce business apps" collision too. Writing the cleaned post now with all four grammatical artifacts fixed, the project codename replaced with its function, the Supabase project ID stripped, and "Obsidian-Intel" replaced.
TLDR:
rls_enabled_no_policylooks scary. Whether it IS scary depends entirely on how your app connects to Postgres. Know your connection architecture first, then decide.
The Setup
I ran the Supabase database linter on my internal vendor intelligence tool and got a wall of red.
Errors. Warnings. Info flags.
My first instinct was classic developer panic: drive everything to zero.
That instinct was wrong — and almost broke two other projects in the process.
The Warning That Looks Bad But Isn't (Sometimes)
The one that jumped out hardest: rls_enabled_no_policy.
RLS (row-level security, Postgres's per-table access control) enabled, but no policies defined. Sounds like a gaping hole, right?
On my law firm client project (a practice-management app), I had this on every single app table — intentionally.
Here's why: Prisma (my ORM) connects as the table owner role. In Postgres, owners bypass RLS entirely. Full read/write through Prisma. And PostgREST (Supabase's REST layer, the thing supabase-js actually talks to) is blocked by the absence of any policy — RLS on with no policies = deny-all by default.
It's honestly kind of GENIUS. Full Prisma access. Zero PostgREST exposure. Nothing to maintain.
So for a law firm client: the warning is a feature, not a bug.
The Same Warning That Actually IS Bad
Then I checked a family of KOL CRM apps for an ecommerce business on a shared Supabase project.
These apps use supabase-js — which goes through PostgREST as the anon or authenticated role.
Those roles don't bypass RLS. They hit it head-on.
So: new table created, Supabase auto-enables RLS (it does this now on every CREATE TABLE), no policy added… and every query from supabase-js comes back as { data: [], error: null }.
Zero rows. No error. No indication anything is wrong.
You're staring at a table that looks empty. The database is fine. The app is lying to you.
That's the kind of silent failure that has you questioning your sanity at 11pm.
The Triage That Actually Works
After going through this across three separate projects, here's what I keep:
Always fix these, no debate:
rls_disabled_in_public(ERROR) — a table where RLS isn't even turned on. Prisma'sCreateTabledoesn't add it automatically. You needALTER TABLE "X" ENABLE ROW LEVEL SECURITY;by hand. In the law firm client repo, commitfe30cabhad to retrofit four tables that drifted after April migrations:Chunk,RagIndexStatus,MatterMilestone,ClientTask.function_search_path_mutable(WARN) — a real vulnerability. Fix by recreating the function withSET search_path = pg_catalog, publicpinned explicitly.
Context-dependent (check your connection architecture first):
rls_enabled_no_policy(INFO) — intentional if you're Prisma-as-owner. A silent disaster if you'resupabase-js.extension_in_publicforpgvector(WARN) — moving it out ofpublicbreaks unqualified::vectorand<=>in raw SQL. I accepted that trade-off knowingly.
Why This Matters to Me
The linter gives you the same label for two completely different situations.
Blindly driving it to zero would have broken the law firm client project. Ignoring it would have left a silent data-denial bug in the ecommerce KOL CRM apps.
The right move: understand how your runtime connects to Postgres first, then read the warnings through that lens.
A linter doesn't know your architecture. You do.
P.S. The supabase-js silent-failure pattern —
{ data: [], error: null }with no rows and no error — is probably the most insidious debugging trap in the whole Supabase ecosystem. If your table looks empty and you can't figure out why, check RLS policies before you check anything else.