Skip to content

Schema dump does not preserve AS RESTRICTIVE on CREATE POLICY #477

@McVeyMason

Description

@McVeyMason

When dumping a schema containing a restrictive RLS policy, the dump omits AS RESTRICTIVE, causing the policy to be recreated as the default permissive policy.

Repro SQL code

CREATE SCHEMA test;

CREATE TABLE test.test_table (
    id int PRIMARY KEY,
    mode text NOT NULL
);

ALTER TABLE test.test_table ENABLE ROW LEVEL SECURITY;

CREATE POLICY test_table_strict_policy ON test.test_table
    AS RESTRICTIVE
    TO PUBLIC
    USING (mode = current_setting('app.mode', true));

Dump schema

pgschema dump --schema test ...

Expected output

CREATE TABLE IF NOT EXISTS test_table (
    id integer,
    mode text NOT NULL,
    CONSTRAINT test_table_pkey PRIMARY KEY (id)
);

ALTER TABLE test_table ENABLE ROW LEVEL SECURITY;

CREATE POLICY test_table_strict_policy ON test_table AS RESTRICTIVE TO PUBLIC USING (mode = current_setting('app.mode', true));

Database state

postgres=# SELECT
    pol.polname,
    pol.polpermissive,
    CASE WHEN pol.polpermissive THEN 'PERMISSIVE' ELSE 'RESTRICTIVE' END AS policy_kind
FROM pg_policy pol
JOIN pg_class c ON c.oid = pol.polrelid
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'test'
  AND c.relname = 'test_table'
  AND pol.polname = 'test_table_strict_policy';
          polname          | polpermissive | policy_kind
---------------------------+---------------+-------------
 test_table_strict_policy  | f             | RESTRICTIVE

Actual output

CREATE TABLE IF NOT EXISTS test_table (
    id integer,
    mode text NOT NULL,
    CONSTRAINT test_table_pkey PRIMARY KEY (id)
);

ALTER TABLE test_table ENABLE ROW LEVEL SECURITY;

CREATE POLICY test_table_strict_policy ON test_table TO PUBLIC USING (mode = current_setting('app.mode', true));

The AS RESTRICTIVE clause is silently omitted. This changes the semantics of the policy when the dump is reapplied: applying the dumped CREATE POLICY recreates the policy as PERMISSIVE.

roundtrip_policy_kind=PERMISSIVE

Environment

  • PostgreSQL 18.1
  • pgschema v1.11.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions