I am using AWS Aurora Postgres 14 (14.5) and have this table set-up (with the help of Diesel in Rust) ->
create table contacts (
email TEXT NOT NULL,
user_id TEXT NOT NULL,
contact_data JSONB,
user_groups TEXT[],
tenant_groups TEXT[],
tags TEXT[],
PRIMARY KEY (email, user_id)
);
With policies ->
ALTER TABLE contacts FORCE ROW LEVEL SECURITY;
CREATE POLICY select_contacts_policy ON contacts
FOR SELECT
USING (user_id = current_setting('myapp.user_id'));
ALTER TABLE contacts ENABLE ROW LEVEL SECURITY;
CREATE POLICY insert_contacts_policy ON contacts
FOR INSERT
WITH CHECK (true);
ALTER TABLE contacts ENABLE ROW LEVEL SECURITY;
While inserting new data to this table, I first set a session parameter called user_id
(a string) (using Diesel's sql_query function)->
sql_query(format!("SET SESSION myapp.user_id = '{user_id}';")).execute(pg_conn)?;
Then I insert using diesel ->
diesel::insert_into(contacts::table)
.values(&contacts) # a custom struct
.on_conflict((contacts::email, contacts::user_id))
.do_update()
.set(&contacts)
.execute(pg_conn)?;
After this query, the user_id
is reverted to a default ->
sql_query("SET SESSION myapp.user_id = -1;").execute(pg_conn)?;
The diesel function call translates to this SQL Query (got it from postgres logs) ->
INSERT INTO "contacts" ("email", "user_id", "contact_data", "user_groups", "tenant_groups", "tags") VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT ("email", "user_id") DO UPDATE SET "email" = $7, "user_id" = $8, "contact_data" = $9, "user_groups" = $10, "tenant_groups" = $11, "tags" = $12
Upon running this query, I get this error message when there is a conflict and the update branch is triggered ->
new row violates row-level security policy (USING expression) for table "contacts"
I have a somewhat similar (without multiple users but the same schema) postgres installation (v 14.8) on my local which is able to upsert without any issues.
Additional information ->
The user working on this is a different one called backend
user
The access privileges -> Snapshot of access privileges for the contacts table
I tried to run an EXPLAIN ANALYZE
query and log it to see where the error occurs but that query results in policy violation before completion. If I run without the ANALYZE
flag, it just prints the query plan (but I want to know where and what is resulting in that violation)