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
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
Dump schema
pgschema dump --schema test ...Expected output
Database state
Actual output
The
AS RESTRICTIVEclause is silently omitted. This changes the semantics of the policy when the dump is reapplied: applying the dumpedCREATE POLICYrecreates the policy asPERMISSIVE.Environment