MP073critical

ban-superuser-role

Migration uses superuser-only operations. Migrations should run with minimal privileges.

operation
Privileges and RLS
lock taken
no table lock
remediation
Manual rewrite
category
Privileges & RLS

What triggers it

Any AlterSystemStmt node (ALTER SYSTEM SET ...), a CreateRoleStmt whose options include a superuser DefElem with a true boolean or integer value — or the bare SUPERUSER keyword, which defaults to true when no arg is present — or an AlterRoleStmt with the same superuser option.

What does not

CREATE ROLE or ALTER ROLE without a superuser option, or with it explicitly set false (a Boolean arg that isn't true, or an Integer arg that isn't 1). The rule only checks the superuser option name, so NOSUPERUSER and every other role attribute pass through untouched.

Where it applies

Applies to every PostgreSQL version MigrationPilot targets. It works on the SQL text alone — no database connection needed.

The lock, and what it blocks

No lock applies — this is a privilege check, not a locking concern. The rule flags the statement because it requires cluster-wide superuser privileges the migration shouldn't have, not because of anything it holds or blocks.

Why it matters

Running migrations as SUPERUSER is a security risk. Managed database services (RDS, Cloud SQL, Neon, Supabase) do not grant SUPERUSER access, so these operations will fail in production.

Unsafe, and safe

Flagged

ALTER SYSTEM SET max_connections = '200';

Safe alternative

ALTER DATABASE mydb SET max_connections = '200';

What it assumes

The rule assumes the migration shouldn't run with superuser access; on a self-hosted cluster where the deploy pipeline genuinely does have and need superuser, some of these statements may be intentional and safe, and the rule can't tell that apart from an over-privileged migration role by design.

What the CLI prints

migrationpilot analyze migration.sql
✗ [MP073] CRITICAL (line 1)
  ALTER SYSTEM requires SUPERUSER privileges and modifies postgresql.conf. Use ALTER DATABASE ... SET for per-database settings instead.

  Safe alternative:
  -- Use per-database settings instead of system-wide:
  ALTER DATABASE mydb SET <parameter> = '<value>';

  Why: Running migrations as SUPERUSER is a security risk: a malicious or buggy migration can modify system catalogs, bypass RLS, and damage the cluster. Managed database services (RDS, Cloud SQL, Neon, Supabase) do not grant SUPERUSER access, so these operations will fail in production. Design migrations to work with the minimum required privileges.
  Docs: https://migrationpilot.dev/rules/mp073

Generated by running the CLI's own formatter over the flagged example above, so it is the text the tool actually produces. A real run also reports the other rules that fire on the same statement; those blocks are left out here.

Turning it off

For one statement, put a comment on the line before it:

-- migrationpilot-disable MP073
ALTER SYSTEM SET max_connections = '200';

For the whole project, in .migrationpilotrc.yml — by name or by id:

.migrationpilotrc.yml
rules:
  MP073: false

# or keep it, and downgrade it
rules:
  MP073:
    severity: warning

Try it

Open this rule's flagged example in the playground. It runs in your browser — edit it and watch the finding appear and disappear.

Run MP073 in the playground