SupaForge
GUIDE

How to Detect Missing RLS Policies Before Production

Scan for RLS drift after dashboard changes so no table reaches production unprotected.

Note: The SupaForge CLI is currently being prepared for public release. to be notified when it's available.

Why RLS Drift Happens

Supabase enables RLS at the table level, but policies are often written in the Dashboard SQL Editor during development and never properly promoted. A table migrated from staging might arrive in production with RLS enabled but zero policies — meaning every authenticated request is silently denied, or worse, an anonkey can read everything if a permissive policy was left behind.

CVE-2025-48757 showed this at scale: 170+ Lovable-generated apps shipped to production without RLS policies ever being promoted from their development environments.

What SupaForge Checks

The RLS check compares both environments and reports:

  • Tables with RLS enabled in source but disabled in target (or vice versa).
  • Policies that exist in one environment but not the other.
  • Policies with the same name but different USING or WITH CHECK expressions.
  • Permissive vs restrictive policy type mismatches.

Step 1 — Install and Configure

Install SupaForge
npm i -g @akalforge/supaforge

Create a configuration file pointing at your two environments. Use the connection strings from the Supabase dashboard under Settings → Database.

supaforge.config.json
{
  "environments": {
    "staging": {
      "dbUrl": "postgresql://user:pass@db.STAGING_REF.supabase.co:5432/postgres",
      "projectRef": "STAGING_REF",
      "apiKey": "your-staging-service-role-key"
    },
    "production": {
      "dbUrl": "postgresql://user:pass@db.PROD_REF.supabase.co:5432/postgres",
      "projectRef": "PROD_REF",
      "apiKey": "your-production-service-role-key"
    }
  },
  "source": "staging",
  "target": "production"
}

Step 2 — Run an RLS-Only Scan

Narrow the scan to RLS so you get a focused report without waiting for schema, data, or other checks:

Scan RLS check only
supaforge scan --check rls

The output lists every table with a discrepancy, the drift severity, and the SQL needed to fix the target environment.

Step 3 — Review Output

Each drift issue includes:

  1. Table name and whether RLS is enabled/disabled.
  2. Policy name, role, command (SELECT/INSERT/UPDATE/DELETE), and expression diff.
  3. Severity — critical for missing policies, warning for expression differences.
  4. Fix SQL — the exact CREATE POLICY or ALTER TABLE ... ENABLE ROW LEVEL SECURITY statement.

Step 4 — Promote or Fix Manually

Preview the changes first (promote is a dry-run by default):

Preview (dry-run, no changes applied)
supaforge promote

When satisfied, add --apply to promote only the RLS check:

Promote RLS changes
supaforge promote --check rls --apply

Step 5 — Add to Your CI Pipeline

Prevent RLS drift from reaching production by adding a scan to your CI workflow. A non-zero exit code from the scan command fails the pipeline when drift is detected:

GitHub Actions step
- name: Check RLS drift
  run: |
    npm i -g @akalforge/supaforge
    supaforge scan --check rls

Summary

RLS policies are the most security-critical piece of Supabase configuration. SupaForge detects drift across environments so you never ship an unprotected table. Run scans locally, in CI, or on a schedule to stay ahead of accidental changes.

Ready to try SupaForge?

Detect drift across all your Supabase environments in seconds.

View on GitHub