Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

261
Views
PostgreSQL + Rails: is it possible to have a write-only database user in PG?

I am building a JSON API in Ruby on Rails. I want to have write-only user accounts that are supposed to feed data to the system but who should not be allowed to read from it.

In order to achieve an extra layer of security, I'd like to enforce this rule at the database level.

The idea is to have a "writer" type of user which uses a separate connection to the database. This connection should be allowed to insert / update / delete but not to select.

I have everything set up nicely but unfortunately Rails generates this query upon insert:

INSERT INTO "default"."products" ("id", "name", "sku") VALUES ($1, $2, $3) RETURNING "id"

The "RETURNING id" part is making it fail because the user does not have SELECT permissions:

ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR:  permission denied 
for relation products: 
INSERT INTO "default"."products" ("id", "name", "sku") VALUES ($1, $2, $3) RETURNING "id"

Is there any way to get around this in PG or Rails? The two options I see are:

  1. Granting a "limited" SELECT permission to writer users in PG, so they can only "see" some columns. I don't know if this is possible at all.
  2. Getting Rails to not add that "RETURNING id" at the end of the query, although this might have side effects.

I found one article of someone who had the same issue and ended up just granting SELECT rights to writer users:

https://til.hashrocket.com/posts/0c83645c03-postgres-permissions-to-insert-but-not-return

Any chance there is an actual solution to get the setup above to work?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

There is a way using row level security feature available since PostgreSQL 9.5:

create table products(id serial primary key, name text not null, sku text not null);
grant select,insert on products to tometzky;
grant usage on sequence products_id_seq to tometzky;
alter table products enable row level security;
create policy products_tometzky on products to tometzky
  using (id=currval('products_id_seq'));

tometzky=> select * from products;
ERROR:  currval of sequence "products_id_seq" is not yet defined in this session
tometzky=> insert into products (name, sku) values ('a','a') returning id;
1
tometzky=> select * from products;
1|a|a
tometzky=> insert into products (name, sku) values ('b','b') returning id;
2
tometzky=> select * from products;
2|b|b

A user only sees the last row he put to the database. He knows what it is anyway.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!