Thread: Update row attribute that is part of row level security policyusing_expression
Update row attribute that is part of row level security policyusing_expression
I'd like to use RLS to 'hide' or 'deactivate' data at some point that some rows are not visible to the application user anymore.
Let's say user a owns the data and can see all his data.
The application user 'b' can only select,update,delete... 'active' data, but is also able to 'deactivate' currently 'active' rows.
Below is how I tried to accomplish this.
But I'm not able to 'deactivate' rows in the table as application user b.
How can i accomplish this? If possible without having to change the application sql’s that run against the table(s)?
create user a with password 'a';
create user b with password 'b';
\c postgres a;
create table t1(id int,active boolean);
insert into t1 values(1,true);
insert into t1 values(2,false);
create policy mypolicy on t1 for all to b using (active);
alter table t1 enable row level security;
grant all on t1 to b;
select * from t1;
id | active
----+--------
1 | t
2 | f
(2 rows)
--> OK
--Now connect as the application user b
\c postgres b;
select * from t1;
id | active
----+--------
1 | t
(1 row)
--> OK
--now I want to 'deactivate' the active row
update t1 set active=false where id=1;
ERROR: new row violates row-level security policy for table "t1"
--> I want to be able to do this.
My question is:
How can user b read just ‘active’ data AND be able to ‘deactivate’ some active rows?
According to the docs (https://www.postgresql.org/docs/current/sql-createpolicy.html) the reason why the update fails is:
The policy USING expression is applied to Existing & new rows on UPDATES if read access is required to the existing or new row
Re: Update row attribute that is part of row level security policyusing_expression
On 5/3/19 4:47 AM, Saupe Stefan wrote: > I'd like to use RLS to 'hide' or 'deactivate' data at some point that > some rows are not visible to the application user anymore. > > Let's say user a owns the data and can see all his data. > > The application user 'b' can only select,update,delete... 'active' data, > but is also able to 'deactivate' currently 'active' rows. > > Below is how I tried to accomplish this. > > But I'm not able to 'deactivate' rows in the table as application user b. > > How can i accomplish this? If possible without having to change the > application sql’s that run against the table(s)? > > create user a with password 'a'; > > create user b with password 'b'; > > \c postgres a; > > create table t1(id int,active boolean); > > insert into t1 values(1,true); > > insert into t1 values(2,false); > > create policy mypolicy on t1 for all to b using (active); > > alter table t1 enable row level security; > > grant all on t1 to b; > > select * from t1; > > id | active > > ----+-------- > > 1 | t > > 2 | f > > (2 rows) > > --> OK > > --Now connect as the application user b > > \c postgres b; > > select * from t1; > > id | active > > ----+-------- > > 1 | t > > (1 row) > > --> OK > > --now I want to 'deactivate' the active row > > update t1 set active=false where id=1; > > ERROR: new row violates row-level security policy for table "t1" > > --> I want to be able to do this. > > My question is: > > How can user b read just ‘active’ data AND be able to ‘deactivate’ some > active rows? The primary issue here is you are using a security policy to try to enforce something that is not security related, the visibility of data. If a user was locked out of data for security reasons, but had the ability to unlock that data on their own it would not be much of a security policy. I see two choices: 1) Don't use RLS for this. Just allow the user to toggle active as needed. Not sure where the user is viewing the data, but active/inactive could be part of the code that allows data through. 2) If you want to use RLS then create a SECURITY DEFINER function that runs as the user that does have non-RLS restricted access to the table. Have user b use that to change the active status. > > According to the docs > (https://www.postgresql.org/docs/current/sql-createpolicy.html) the > reason why the update fails is: > > The policy USING expression is applied to Existing & new rows on UPDATES > if read access is required to the existing or new row > -- Adrian Klaver adrian.klaver@aklaver.com