RowShield

Comparisons / Postgres linters

RowShield vs plpgsql_check: function internals vs posture monitoring

The short version

  • plpgsql_check is a free, open-source Postgres extension that statically analyses PL/pgSQL function bodies — resolving embedded SQL against the catalog and reporting defects before runtime. RowShield is a scheduled monitor over policy posture, live anon behaviour and drift across a Supabase project.
  • Choose plpgsql_check when you want the deepest available static diagnostics on function code, run when you choose, at no cost.
  • Choose RowShield whenyou want the surfaces that actually leak — policies, buckets, keys — watched on a schedule, with regressions named as regressions.

Head to head: plpgsql_check vs RowShield

Capabilityplpgsql_checkRowShieldEdge
Object of studyFunction bodies: every embedded SQL statement is resolved against the catalog.Project posture: policies, buckets, key exposure and anon reachability across the database.Parity
Depth in its domainUnmatched: type mismatches, unresolved references, unused variables found before runtime.Does not read function bodies at all; the limitation is documented, not implied away.plpgsql_check
When it runsWhen you invoke it — session, CLI or CI — whenever someone remembers.Scheduled scans: daily on Free, hourly on Indie, every 15 minutes on Team.RowShield
Behaviour verificationStatic only; nothing is executed as a caller.A GET-only probe exercises PostgREST as the anon caller and records the result.RowShield
Time axisEach run is isolated; there is no memory between invocations.Snapshots are diffed scan to scan; changes are classified created, resolved or regressed.RowShield
IntegrationAn extension on the server; also the engine behind `supabase db lint`.A hosted scanner over a catalog-read connection, plus a CLI with CI-safe exit codes.Parity
Cost profileFree and open source under its own license, sustained by community maintenance.Free probe tier; monitoring plans are listed on the pricing page.plpgsql_check

Column claims about plpgsql_check 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 plpgsql_check does

plpgsql_check is an open-source Postgres extension that performs static analysis of PL/pgSQL. It resolves every embedded SQL statement in a function body against the catalog, and reports defects before runtime: arguments and return types that disagree, references that do not resolve, variables that are declared and never used, and related problems. It also ships profiling aids, and it is the analyser behind Supabase's `db lint` command.

It is maintainer-led, free, and authoritative in its domain. Nothing on this page should be read as advice against running it; the question is whether function-body analysis is the question your project needs answered this month.

Where the scopes differ

The object of study differs first. plpgsql_check reads code: function bodies, deeply. RowShield reads state: the policy landscape, storage configuration and key exposure of a live project, plus what the API actually returns to an anonymous caller. The two barely overlap, and each is blind where the other sees clearly — a function can lint clean while the policy beside it is always true, and a project can pass every posture rule while one function carries a latent type error.

Mapped onto RowShield's three lenses: plpgsql_check holds posture only narrowly (function internals, not the policy landscape), holds no behaviour evidence (static analysis never issues a request), and holds no time axis (each invocation is isolated). RowShield holds the broader posture, the GET-only probe, and snapshot diffing that names regressions.

The honest asymmetry runs the other way too: RowShield does not analyse function contents at all, and the manifest documents that limitation rather than implying coverage. Teams with heavy PL/pgSQL need both instruments, in both directions.

Why Supabase teams choose RowShield over plpgsql_check

When the leaking surface is the policy layer rather than the function layer, static function analysis does not ask the questions that matter: is RLS enabled, is the predicate always true, does every INSERT policy carry WITH CHECK, is the auth.uid() call wrapped so it can use an index, is the bucket public, can the anon key read the table, is a service_role key riding in a client bundle? RowShield asks all of those, on a schedule, with nine rule-backed checks.

Scheduled means the answer is current without anyone remembering to ask: daily on Free, hourly on Indie, every fifteen minutes on Team. Alerts fire on transitions only, remediation SQL is generated from your real columns, and the CLI preserves the CI gate habit that linters earn their keep with.

Where plpgsql_check is the right choice

For RPC-heavy APIs, trigger factories and any codebase with serious PL/pgSQL, plpgsql_check belongs in the pipeline before every deploy — directly or through `supabase db lint`. Its diagnostics are deeper than anything RowShield offers in that domain, it is free, and it needs no third-party service. For function-code correctness alone, this page does not compete with it.

Using both

They are a natural pair divided along the code/state line: plpgsql_check for compile-time correctness of functions, RowShield for runtime posture of the project. When they disagree — a clean lint beside a probe reporting an anon-readable table — investigate before dismissing either; each is telling the truth about the layer it can see.

Frequently asked

Is RowShield affiliated with the plpgsql_check maintainers?
No. RowShield is an independent product by Veristria, unaffiliated with the plpgsql_check project and its maintainers. plpgsql_check is referenced descriptively and remains the mark of its project.
Is RowShield a good plpgsql_check alternative?
For function-body static analysis, no — plpgsql_check is the stronger instrument and costs nothing. For policy posture, anon behaviour and drift, RowShield covers ground plpgsql_check does not touch, which is why the two are best used together.
Does RowShield analyse the contents of my functions?
No. RowShield reads catalog metadata and probes the API surface; it does not perform static analysis of function bodies. That limitation is documented in the manifest rather than implied away, and plpgsql_check fills exactly that gap.

Check your project in about ten seconds

Paste a URL. No signup, no writes, nothing stored.

Run the free audit

Sources reviewed for this page

plpgsql_check is a trademark of plpgsql_check maintainers (open source). RowShield is an independent product by Veristria, unaffiliated with and neither endorsed nor sponsored by plpgsql_check maintainers (open source). Comparisons are based on publicly available documentation reviewed on 2026-08-23.