If you’re interested in row level access control on Postgres, it works like this:
Prior to doing queries, you do a SQL query that sets a “Postgres environment
variable”.
In very simplified terms, after that, queries automatically have a WHERE clause applied which ensures only rows with the value of the env variable are returned.
This is a good thing because it means you do not have to write WHERE customer = ‘blah’ anywhere.
-- a policy on the account relation to allow only members of the managers role to access rows, and only rows of their accounts
CREATE TABLE accounts (manager text, company text, contact_email text);
ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;
CREATE POLICY account_managers ON accounts TO managers
USING (manager = current_user);
EDIT: That page doesn't cover session vars, but this one does:
After configuring it as the parent post says, you set the environment variable like so:
SET myapp.manager = '123e4567-e89b-12d3-a456-426614174000';
Then you can just query the database and it will only return records where manager = '123e4567-e89b-12d3-a456-426614174000'
It's something like that anyway - you have to do lots of reading the docs and fiddling to make sure all the bits and pieces are set up right for it to work - which is why these folks are creating a SAAS to do all the thinking for you.
The real benefit of RLS is developers don't have to put "WHERE company_id=whatevere" on all queries, along with the risk that leaving it out or writing it wrong will reveal one client's data in another clients user interface.
I think most people think of environment variables as being for a whole process. For RLS this can be any GUC variable so it can be per-session, per transaction, etc.
Usually you would set it per transaction (and start a transaction for each request) and I think the important part you are missing to say is they are applied to any joins, CTE's, functions and views (as of the latest-1 version with the right flag).
So you write your schema, write your access (RLS) rules and can then write your queries as if you had access to the whole DB but the only parts you will see is what that user can access.
John here. Interesting! So, this is a per-session variable? Right now, we provide our customers with full logical separation in the same cluster. Do you have a preference for RLS or logical separation?
Prior to doing queries, you do a SQL query that sets a “Postgres environment variable”.
In very simplified terms, after that, queries automatically have a WHERE clause applied which ensures only rows with the value of the env variable are returned.
This is a good thing because it means you do not have to write WHERE customer = ‘blah’ anywhere.