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
✗ [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:
rules:
MP073: false
# or keep it, and downgrade it
rules:
MP073:
severity: warningTry 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