Search code examples
sqlpostgresqlrow-level-security

PostgreSQL Row Security Policies is not working for CREATE POLICY FOR UPDATE WITH CHECK (false);


I'm trying to set up row level security on some tables. By now I had no issues with INSERT and SELECT, now trying to handle UPDATE.

I tried many things but really got stuck when I defined the policy with WITH CHECK (false) and I have the ability to execute updates on that table with rls user despite the policy defined.

Why is that happening? I expected all updates on that table to fail because WITH CHECK is a boolean validator.

Here is my code:

CREATE TABLE t (
                "id" SERIAL PRIMARY KEY NOT NULL, 
                "name" varchar (50) NOT NULL
               );
create role rls_user NOINHERIT;
GRANT USAGE ON SCHEMA public TO rls_user;

GRANT SELECT, UPDATE, INSERT ON ALL TABLES IN SCHEMA public TO rls_user;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO rls_user;

alter table t enable row level security;

CREATE POLICY t_update ON t
FOR UPDATE WITH CHECK (false);

----> CREATE POLICY t_update ON t
----> FOR UPDATE USING (false); ---> also doesn't work
set role rls_user;

UPDATE t 
SET name = 'blabla'
WHERE "id" = 1;

---> expected: UPDATE FAILED

---> result: 
--->           UPDATE 0

--->           Query returned successfully in 73 msec. 

Solution

  • Your policy makes the table appear empty for the rls_user, because it has no USING clause.

    Therefore, the UPDATE will never modify a row (UPDATE 0), and since no row is modified, no row has to pass the CHECK condition and no error is thrown.

    Note that you granted the user UPDATE permissions on the table, so it is allowed to run all updates on the table, as long as the modified rows pass the CHECK condition.