Comparisons / Platform-native
RowShield vs Supabase db lint: function lint vs continuous monitoring
The short version
- `supabase db lint` is a free CLI command that runs the plpgsql_check static analyser against the functions in your database and prints what it finds. RowShield is a hosted monitor that scans policy posture, probes live anon behaviour and diffs every scan against the last.
- Choose Supabase db lint when — you want a fast, developer-triggered static check of PL/pgSQL function internals before a deploy, with no third-party service to sign up for.
- Choose RowShield when — your policies, buckets and keys change independently of your functions, and you want those changes watched on a schedule with regressions named as regressions.
RowShield rules relevant here
Head to head: Supabase db lint vs RowShield
| Capability | Supabase db lint | RowShield | Edge |
|---|---|---|---|
| When it runs | When a developer invokes the command locally or in CI — point-in-time, on demand. | Scheduled scans: daily on Free, hourly on Indie, every 15 minutes on Team. | RowShield |
| Analysis focus | PL/pgSQL function bodies: embedded SQL semantics, variable use, return-type agreement. | Nine shipped rules over policy state, storage exposure and key leakage; function internals are not analysed. | Supabase db lint |
| Policy posture rules | Not the command's job — policy shapes such as tautological predicates sit outside plpgsql_check's remit. | RLS-disabled tables, tautological policies, missing WITH CHECK, unindexed predicates and bare auth.uid() calls, among others. | RowShield |
| Live behaviour as the anon caller | None — the command never issues HTTP requests. | A GET-only probe asks PostgREST what the anon key can actually fetch from each table. | RowShield |
| Drift and regressions | No memory between invocations; each run starts from nothing. | Catalog snapshots are diffed scan to scan and classified created, resolved or regressed. | RowShield |
| Alerting | Terminal output plus a nonzero exit code you can gate CI with. | Slack Block Kit, Discord embeds, HTML email and webhooks, thresholded per destination. | RowShield |
| Cost and setup | Free, bundled with the CLI, nothing to provision beyond the project itself. | Free tier covers the probe; monitoring plans are listed on the pricing page. | Supabase db lint |
Column claims about Supabase db lint are sourced below. Where the edge is theirs, the page says so — and the sections that follow explain why Supabase teams still pick RowShield.
What `supabase db lint` does
`supabase db lint` is a command in the official Supabase CLI. Invoked against a linked project, it runs the plpgsql_check static analyser over the database's functions and prints the findings: embedded SQL that disagrees with the catalog about types or columns, references that do not resolve, variables that are declared and never used, and related defects in PL/pgSQL bodies.
It is free, official and quick, and because it exits nonzero when problems are found it slots into CI as a gate. As a pre-deploy check on function code it does a specific job well. Its scope is deliberate: function bodies, examined at the moment a developer chooses to run it.
Where the scopes differ
RowShield sells three things: configuration posture, live behaviour, and drift over time. `db lint` holds a fourth, related thing — a code-level view of one category of database objects, on demand — and the difference matters in all three directions.
Posture. The command does not grade the policy landscape. Tables with row level security switched off, predicates that are always true, INSERT and UPDATE policies with no WITH CHECK clause, unindexed policy predicates: none of these are function-body questions, and the command does not ask them. RowShield's nine shipped rules ask exactly those questions on every scan.
Behaviour. Static analysis resolves SQL text against the catalog; it cannot tell you what PostgREST returns to an anonymous visitor. RowShield's probe issues GET requests as the anon caller, because deparse-checked logic and observed behaviour can disagree — an empty response can mean "filtered" or "empty".
Time. Each invocation is isolated. Between runs there is no record that a fix was reverted or that a new policy landed. RowShield snapshots the catalog on every scan, diffs against the previous one, and labels each change created, resolved or regressed.
Why Supabase teams choose RowShield over `supabase db lint`
If your worry is the policy layer rather than function internals, the lint answers a question you are not asking. RowShield watches the surfaces that actually leak: RLS-disabled tables, tautological predicates, missing WITH CHECK clauses, unindexed policy predicates, unwrapped auth.uid() calls, public buckets, tables the anon key can read and service_role keys served in client bundles.
Watching means scheduled: daily on Free, hourly on Indie, every fifteen minutes on Team. Alerts fire on transitions only, so a project sitting broken notifies once instead of hourly. Remediation SQL is generated from your real column names with one-click copy, and the CLI brings CI-safe exit codes, so the gating habit `db lint` rewards carries straight over.
Where `supabase db lint` is the right choice
Teams shipping a lot of PL/pgSQL — triggers, RPC-heavy APIs, data pipelines in functions — should run plpgsql_check, directly or through this command, before every deploy. Its diagnostics on function internals are deeper than anything RowShield offers, because RowShield does not read function bodies at all. It is free, official and needs no third-party account; for function-code correctness alone, nothing on this page competes with it.
Using both
They divide cleanly along the compile/runtime line: `db lint` in CI for function correctness, RowShield on a schedule for posture, behaviour and drift. When the two disagree — a clean lint alongside a probe reporting an anon-readable table — investigate before dismissing either. They examine different layers of the same stack, and each is telling the truth about the layer it can see.
Frequently asked
- Is RowShield affiliated with Supabase?
- No. RowShield is built by Veristria, an independent company, and is unaffiliated with Supabase, Inc. Supabase and db lint are referenced descriptively and remain trademarks of their owner.
- Is RowShield a good `supabase db lint` alternative?
- For policy posture, anon behaviour and drift, yes: RowShield covers those continuously and `db lint` does not address them at all. For static analysis of function internals, no — plpgsql_check is the stronger instrument there, and the two are best used together.
- Does `supabase db lint` check my RLS policies?
- No. Through plpgsql_check it examines function bodies rather than grading policy predicates. Policy-shape checks such as tautology detection belong to the dashboard linter and to RowShield.
Check your project in about ten seconds
Paste a URL. No signup, no writes, nothing stored.
Run the free audit