MP079warning

warn-rls-policy-completeness

RLS policies should cover all operations (SELECT, INSERT, UPDATE, DELETE) to avoid silent access denial.

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

What triggers it

The AT_EnableRowSecurity subcommand of ALTER TABLE, when the migration's own CREATE POLICY statements for that table (found by scanning originalSql for the table name) cover some but not all of SELECT/INSERT/UPDATE/DELETE, and none of them uses FOR ALL.

What does not

Non-AlterTableStmt statements, and ALTER TABLE statements that don't enable RLS. A policy anywhere in the migration written FOR ALL clears the whole table. If the migration enables RLS but adds no policies at all, this rule stays quiet on purpose — that case is MP057's job.

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

None — the risk here isn't a lock, it's that PostgreSQL denies uncovered operations silently instead of raising an error.

Why it matters

When RLS is enabled, any operation without a policy is silently denied — queries return zero rows instead of raising an error. Always create policies for all operations or use a FOR ALL policy.

Unsafe, and safe

Flagged

ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY posts_select ON posts FOR SELECT USING (true);
-- Missing INSERT, UPDATE, DELETE policies!

Safe alternative

ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY posts_all ON posts FOR ALL USING (true);

What it assumes

Assumes every policy for the table lives in this same migration file — a policy created earlier, in a different file, won't be seen, so a table that's actually fully covered can still get flagged. Coverage detection is also a text match on create policy plus the table name, not a structural link between policy and table, so it can misjudge coverage in an unusual layout.

What the CLI prints

migrationpilot analyze migration.sql
⚠ [MP079] WARNING (line 1)
  RLS on "posts" has policies for select but missing insert, update, delete. Uncovered operations will be silently denied.

  Safe alternative:
  CREATE POLICY posts_insert ON posts FOR INSERT USING (true);
  CREATE POLICY posts_update ON posts FOR UPDATE USING (true);
  CREATE POLICY posts_delete ON posts FOR DELETE USING (true);

  Why: When RLS is enabled, any operation without a policy is silently denied: queries return zero rows instead of raising an error. If you create a SELECT policy but forget INSERT, all inserts silently fail (or error on PG 15+). Always create policies for all operations or use a permissive ALL policy as a baseline.
  Docs: https://migrationpilot.dev/rules/mp079

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 MP079
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

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

.migrationpilotrc.yml
rules:
  MP079: false

# or keep it, and downgrade it
rules:
  MP079:
    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 MP079 in the playground