Comparisons / Migration frameworks
RowShield vs golang-migrate: up/down files versus policy watch
The short version
- golang-migrate is the widely used Go migration CLI and library: paired up/down SQL files, applied in version order, embeddable in Go services. RowShield is a scheduled Supabase monitor that verifies the authorisation state those files produce — policies, buckets, keys — and alerts when any of it changes.
- Choose golang-migrate when — a Go team wants a proven migration primitive it can embed, script or ship inside its own binary.
- Choose RowShield when — your Supabase project changes faster than anyone re-reviews policies, and you want hourly-to-quarter-hourly verification with regressions named as regressions.
RowShield rules relevant here
Head to head: golang-migrate vs RowShield
| Capability | golang-migrate | RowShield | Edge |
|---|---|---|---|
| Role in the lifecycle | Applies versioned up/down files and records progress; execution is the product. | Observes the post-execution state on schedule; verification is the product. | golang-migrate |
| Interpretation of SQL | Files execute as written; authorisation consequences are not assessed. | Assessed every scan: RLS flags, policy conditions, WITH CHECK coverage, bucket visibility. | RowShield |
| Tautology detection | USING (true) is valid SQL and passes unnoticed. | RLS_TAUTOLOGY identifies constant-true predicates per table and role, with severity. | RowShield |
| Live-surface evidence | Runs only on invocation, then returns to silence between releases. | GET-only probe requests PostgREST as the anon role, listing tables that actually return rows. | RowShield |
| Interval coverage | Active only when invoked by humans or scripts. | Scheduled scans up to every fifteen minutes, catching dashboard and AI-assisted edits between invocations. | RowShield |
| Change memory | Version table records applied files, not posture history. | Snapshot history diffs every scan; changes labelled created, resolved or regressed. | RowShield |
| Embeddability in Go services | Importable library with driver support — genuinely useful in Go architectures. | Standalone product; no Go SDK. | golang-migrate |
Column claims about golang-migrate 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 golang-migrate does
golang-migrate, per its README reviewed 2026-08-23, provides database migrations as paired versioned files — an up section applying change, a down section reversing it — driven by a CLI or imported as a Go library, with drivers for many databases and source layouts. Services can embed it so migrations run at startup, and CI can drive it as a step.
It is infrastructure in the best sense: predictable, scriptable, unopinionated about content. The flip side of taking no position on your SQL is that it cannot warn when the SQL removes protections; execution fidelity and semantic safety are different properties, and the tool measures only the first.
Where the scopes differ
Go services using golang-migrate typically own their schema tightly, which paradoxically raises the stakes of the unmapped layer: the migrations are disciplined, so the remaining risk concentrates in what the versioned files never expressed — policies added by hand in the dashboard, buckets toggled in storage settings, AI-suggested SQL applied directly, or a down migration that restored structure without restoring protection.
RowShield monitors precisely that residue. Scheduled catalog scans evaluate the authorisation objects themselves — RLS_DISABLED, RLS_NO_POLICIES, RLS_TAUTOLOGY, MISSING_WITH_CHECK — along with Supabase-specific exposure rules, and each scan diffs against the previous snapshot so movement is impossible to miss.
The behavioural layer completes it: the probe issues GET requests to PostgREST as the anonymous visitor, converting policy text into observed fact about which tables serve rows. And because snapshots accumulate, the fix that quietly reverts is reported as a regression — the label that distinguishes bad luck from a broken process.
Why Supabase teams choose RowShield over golang-migrate
The pairing question resolves cleanly once the jobs are named. golang-migrate executes change; RowShield certifies outcome. Teams adopt us without touching their migration setup: the free probe needs only a project URL, and scheduled monitoring on a paid plan brings the nine-rule catalogue, hourly or quarter-hourly scans by plan, and remediation SQL generated from your columns with FORCE ROW LEVEL SECURITY included.
Alerts route to Slack, Discord, email or webhooks on transitions only, so quiet periods stay quiet. For Go teams the CLI matters especially: identical checks with CI-safe exit codes slot a verification gate beside the migrate step in Makefiles, Docker builds or GitHub Actions without a new runtime dependency.
Where golang-migrate is the right choice
As the migration engine inside Go services, golang-migrate is a sensible default with real flexibility in drivers and embedding, and nothing here argues against it. Execution, version tracking and reversibility are its job; it does them without fuss.
Teams needing exotic source layouts or multi-database drivers from one library will find its breadth useful beyond anything in this page’s subject area.
Using both
Embed golang-migrate as before; point RowShield at the project and let scheduled scans certify that every up — and every out-of-band change — left the authorisation layer intact. Execution and verification, composed.
RowShield reads pg_catalog metadata only and is built by Veristria, unaffiliated with the golang-migrate maintainers; the project is referenced descriptively as open-source software.
Frequently asked
- Is RowShield affiliated with the golang-migrate project?
- No. RowShield is built by Veristria, an independent company, and is neither endorsed by nor affiliated with the maintainers of golang-migrate, which is referenced descriptively as an open-source project.
- Is RowShield a good golang-migrate alternative?
- For executing versioned migrations in Go, no — keep golang-migrate; it is the right primitive. For continuously verifying that the migrated Supabase project remains private, yes: posture and behaviour monitoring is a different job that complements the migrator.
- Our down migrations restore dropped policies. Is that enough?
- Restoration helps, but only if the down path is perfect and nothing changes outside files. A restored policy can still carry a weakened predicate, and dashboard edits bypass files entirely — both are exactly what scheduled semantic checks and the probe catch.
Check your project in about ten seconds
Paste a URL. No signup, no writes, nothing stored.
Run the free audit