PostgreSQL + Rails: 是否可以在 PG 中拥有只写数据库用户?

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

我正在 Rails 的 Ruby 中构建一个 JSON API。我想要只写用户帐户,这些帐户应该向系统提供数据但不应允许从中读取数据。

为了实现额外的安全层,我想在数据库级别强制执行此规则。

想法是让 "writer" 类型的用户使用单独的数据库连接。应该允许此连接插入/更新/删除但不允许 select.

我已经很好地设置了一切,但不幸的是 Rails 在插入时生成此查询:

INSERT INTO "default"."products" ("id", "name", "sku") VALUES (, , ) RETURNING "id"

"RETURNING id" 部分导致失败,因为用户没有 SELECT 权限:

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

在 PG 或 Rails 中有什么办法可以解决这个问题吗?我看到的两个选项是:

  1. 在 PG 中授予作者用户 "limited" SELECT 权限,因此他们只能 "see" 某些栏目。我完全不知道这是否可能。
  2. 让 Rails 不在查询末尾添加 "RETURNING id",尽管这可能会产生副作用。

我发现了一篇有同样问题的人的文章,结果只是向作者用户授予 SELECT 权限:

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

是否有实际的解决方案可以使上述设置正常工作?

自 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

用户只能看到他放入数据库的最后一行。反正他知道是什么。