3

I have a web app backed by Postgres.

  • Each web app request should only read/write data for the current logged-in user.
  • Every table with user data has a user_id column.

I occasionally have bugs where I forget to add user_id = ? to the WHERE clause of an SQL request. To protect against this problem in a general way, I'm looking into Postgres row-level security (article):

  • Set a policy on every user data table: CREATE POLICY table_policy ON table USING (user_id::TEXT = current_setting('app.user_id'))
  • In the web app, when a request begins, set the current logged-in user ID on the request's connection: SET app.user_id = ?.

This allows me to completely ignore user_id when writing SELECT and UPDATE requests.

My remaining problem is INSERTs. Is there a way to avoid having to provide user_id on INSERTs?

Kannan Goundan
  • 4,962
  • 3
  • 24
  • 31

1 Answers1

1

Just having a look at the manual :

Existing table rows are checked against the expression specified in USING, while new rows that would be created via INSERT or UPDATE are checked against the expression specified in WITH CHECK

it seems that you just have to add a WITH CHECK clause to your policy in addition of the USING clause, and which will apply to the INSERT and UPDATE statements.

Edouard
  • 6,577
  • 1
  • 9
  • 20
  • Yes, `INSERT` statements will be checked -- if my `INSERT` specifies the wrong `user_id`, it will be appropriately rejected. But what I'm looking for is a way to not even have to provide `user_id` in my `INSERT`s. – Kannan Goundan Dec 29 '20 at 01:31