Skip to main content
Use this when Row Level Security predicates protect tenants or other sensitive boundaries. supaschema compares policy definitions structurally. A changed USING expression, WITH CHECK expression, command, role list, or permissive/restrictive mode is treated as a real schema change. The RLS safety pack also surfaces Supabase-specific policy issues from parsed policy metadata: auth.role() usage, direct auth.uid() calls that are not wrapped as (select auth.uid()), update-capable policies without explicit WITH CHECK, policies without enabled RLS, and enabled RLS tables with no policies.

Use this when

  • Policy bodies are part of your access-control model.
  • Reviewers need to see tenant-isolation changes.
  • CI should catch drift between policy files and the database.
  • Deploy should block when configured RLS safety rules fail.
  • Supabase projects use auth.uid() or platform roles in policies.

Do this

Keep policies in the declarative tree near the protected tables:
Generate and check every policy change:
Review whether each predicate broadened reads, weakened writes, or changed role coverage. For apply workflows, the default workflow.rls_safety policy reports diagnostics without blocking. Set it to deploy_blocking when a project wants RLS diagnostics to refuse target mutation.

Verify

Block drift in CI:
Use Supabase stubs when verifying against bare PostgreSQL:

Supabase comparison

See why structural policy diffs matter.

CI gate

Gate policy changes before merge.

Check command

Surface policy changes with safety diagnostics.

Sync command

Block unsafe RLS changes before local or remote apply.
Last modified on June 25, 2026