Let's say I have a users
table with three columns, public_data
, private_data
, and system_data
, and I have three roles named postgres
, authenticated_user
, and visitor
.
postgres
is superuser and can access all data (including system_data
of course)
authenticated_user
should be able to access every user's public_data
, their own private_data
, but not system_data
visitor
can only access every users' public_data
How do I set up my tables, roles, grants, and policies to accomplish the above?
Go to the Protection tab and uncheck Locked option and click Ok. Now select only the cells or columns, rows that you want to protect. Right click and choose Format cells again. Go to the protection tab and check Locked option and click Ok.
Best Practices It's highly recommended to create a separate schema for the RLS objects: predicate functions, and security policies. This helps to separate the permissions that are required on these special objects from the target tables.
You can use row-level and column-level access control to restrict access to certain types of information that require additional security. Row-level and column-level access controls can help you to protect sensitive information and comply with government regulations for security and privacy.
This isn't really a declarative row security question, as it sounds like you want to return all rows, but display different column values depending on the current user
As per your comment, you're okay with different queries per user type. I don't see a way around using a case
statement for private_data
create table users (
id int primary key,
owner name not null,
public_data text,
private_data text,
system_data text
);
--these should probably be groups, not users:
create user visitor;
create user authenticated_user;
grant visitor to authenticated_user; -- will inherit visitors permissions
grant select(id, owner, public_data) on users to visitor;
grant select(private_data) on users to authenticated_user;
insert into users (id, owner, public_data, private_data, system_data) values (1, 'visitor', 'public', 'private to visitor', 'system');
insert into users (id, owner, public_data, private_data, system_data) values (2, 'authenticated_user', 'public', 'private to authenticated_user', 'system');
set role visitor;
select id, owner, public_data from users;
set role authenticated_user;
select id, owner, public_data, case when owner=current_user then private_data else null end as private_data from users;
set role postgres;
select * from users;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With