Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining row level security with column grants

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?

like image 768
Julien Avatar asked Mar 13 '18 16:03

Julien


People also ask

How do you keep rows and columns secured?

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.

What are the best practices to use RLS row level security objects?

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.

What is row level and column level security?

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.


Video Answer


1 Answers

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;
like image 58
Neil McGuigan Avatar answered Oct 21 '22 10:10

Neil McGuigan