Comparisons / Migration frameworks
RowShield vs Django migrations: model state versus authorisation state
The short version
- Django migrations derive from model state: makemigrations diffs your models against recorded migrations, and migrate applies the result. RowShield is a continuous Supabase monitor for everything model state omits — row level security, storage exposure, key leakage — with a probe that tests what the anon key can actually read.
- Choose Django migrations when — a Django team wants the framework’s dependable migration machinery left exactly as it is.
- Choose RowShield when — your Django app sits on Supabase Postgres and you want scheduled proof that policies, buckets and keys stayed safe between releases.
RowShield rules relevant here
Head to head: Django migrations vs RowShield
| Capability | Django migrations | RowShield | Edge |
|---|---|---|---|
| State model | Migration files record projected model state; the tracker replays and reconciles it. | Catalog snapshots record actual state, including every change that never passed through models. | RowShield |
| Authorisation coverage | Grants, policies and platform settings live outside the models, hence outside migrations. | The entire rule catalogue targets them: RLS flags, policy conditions, write guards, buckets, keys. | RowShield |
| Semantic checks | RunSQL migrations apply whatever SQL is given, unexamined. | Constant-true policies, missing WITH CHECK and disabled RLS detected and severity-ranked per scan. | RowShield |
| Behavioural evidence | No runtime requests; the serving layer is not exercised. | GET-only probe calls PostgREST as the anon role and records readable tables. | RowShield |
| Between-release coverage | Activity clusters at deploy time. | Scans every fifteen minutes to daily, so dashboard and console edits between deploys are caught. | RowShield |
| Alerting | Management-command output at execution time. | Transition-only alerts to Slack, Discord, email and webhooks; regressions labelled explicitly. | RowShield |
| Framework integration for Python teams | Deeply built into Django’s ORM workflow. | Deliberately external and stack-neutral. | Django migrations |
Column claims about Django migrations 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 Django migrations do
Django’s migration framework, documented at djangoproject.com, converts changes to model classes into migration files: makemigrations computes the difference between your models and the recorded migration state, and migrate applies pending files in order. The machinery is dependable, well documented, and central to how Django projects evolve schemas.
By design it manages what models express. Database authorisation on Supabase — row level security policies, storage bucket rules, the anon/service_role key split — is expressed nowhere in a Django model, so the migration tracker neither preserves, applies nor evaluates it. RunSQL blocks can carry such SQL, but the framework executes that text without reading its meaning, as any raw-SQL escape hatch must.
Where the scopes differ
The model-state machine and the authorisation layer are disjoint sets, and the gaps show in three familiar places. Recreated tables: a migration chain that rebuilds a table can drop its policies, and the framework reports success because model state matches. Escaped SQL: a RunSQL line containing USING (true) applies as faithfully as a correct policy — syntax is checked, semantics are not. Out-of-band edits: fixes applied in the Supabase dashboard or by an AI assistant leave no trace in the migration graph, so the next reconcile knows nothing of them.
RowShield’s design starts from that blind spot. Scheduled scans read the live catalog directly — provenance irrelevant — and evaluate the authorisation objects themselves: RLS_DISABLED, RLS_TAUTOLOGY, RLS_NO_POLICIES, MISSING_WITH_CHECK, PUBLIC_BUCKET_EXPOSURE, SERVICE_ROLE_KEY_EXPOSED.
The probe closes the loop with behaviour: GET requests to PostgREST as the anonymous visitor, recording which tables return rows. Snapshots persist between scans, so a reverted fix returns labelled as a regression — the one label that points at process rather than luck.
Why Supabase teams choose RowShield over Django migrations
Because "our migrations are tidy" and "our data is private" are different claims, and only the second one has a breach-shaped failure mode. RowShield evidences the second continuously: the free probe answers the readable-tables question from a URL alone, and scheduled monitoring on a paid plan adds the full nine-rule catalogue with hourly or quarter-hourly frequency by plan.
Findings arrive with remediation SQL generated from your columns, FORCE ROW LEVEL SECURITY included, and route to Slack, Discord, email or webhooks only when something changes. The CLI mirrors the engine for teams who want the checks inside their existing CI alongside python manage.py migrate.
Where Django migrations are the right choice
For evolving Django-managed schemas, the framework is excellent and we would change nothing about using it. Its determinism and history are assets; this page exists only because its jurisdiction ends at the model boundary.
Projects not on Supabase, with no public API surface, may legitimately conclude that continuous authorisation monitoring is surplus to requirements.
Using both
Let Django keep migrating the models; let RowShield watch the unmapped authorisation layer between releases. The combination covers both halves of the database — structure by framework discipline, protection by scheduled verification.
RowShield reads pg_catalog metadata only and is built by Veristria, unaffiliated with the Django project; Django is referenced descriptively as open-source software.
Frequently asked
- Is RowShield affiliated with the Django project?
- No. RowShield is built by Veristria, an independent company, and is neither endorsed by nor affiliated with the Django project or its maintainers. Django migrations are referenced descriptively based on official documentation.
- Is RowShield a good Django migrations alternative?
- For managing model-driven schema change in Django, no — the framework’s machinery is excellent and should stay. For continuous monitoring of Supabase authorisation that models and migrations never capture, yes: RowShield covers precisely the unmapped layer.
- Should we wrap RLS SQL in RunSQL migrations to stay covered?
- Scripting policies improves reproducibility, and we encourage it. It does not substitute for monitoring: the framework applies that SQL without evaluating it, so a tautological condition ships as smoothly as a correct one, and out-of-band edits still bypass the graph entirely.
Check your project in about ten seconds
Paste a URL. No signup, no writes, nothing stored.
Run the free audit