0

对于数据摄取服务,我想通过以下方式严格限制其对数据库的访问。此摄取器服务必须能够:

  • 创建新表来存储新类型的数据(即能够动态存储新类型数据的动态摄取器)。
  • 将新列添加到 ingester 创建的表之一(仅向后向前模式兼容性)。
  • 在 ingester 创建的表之一中插入新行。

指定此摄取者角色的另一种方法是查看它不应执行的操作:

  • DROP 任何表,包括它创建的表
  • SELECT、DELETE、UPDATE 任何表中的任何行
  • 删除或更新任何表中的列

我没有找到任何方法来满足 PostgreSQL 的所有这些限制。例如,要更改一个表,摄取者角色需要拥有该表,但是当您拥有一个表时,您自动有权访问该表的 DELETE、SELECT、UPDATE... 操作。理想情况下,我希望所有这些表都归数据库管理员用户所有。此管理员用户将是唯一允许执行任何破坏性操作的用户。

我们可以使用触发器和函数的组合来满足这些约束,或者我们可以仅基于角色和授权操作来指定吗?

4

2 回答 2

1

这绝对是不可能的。

创建表的人就是表的所有者,并且可以更改和删除它。

两种前进方式:

  • 像您建议的事件触发器。

  • 让其他人拥有这些表并提供SECURITY DEFINER操作它们的功能。

于 2019-10-01T21:42:17.400 回答
1

感谢劳伦兹的帮助。

我提出了以下解决方案,该解决方案基于 EVENT TRIGGER 和 FUNCTION 与管理员用户拥有的 SECURITY DEFINER 的组合。

EVENT TRIGGER 检测到由 ingester 用户完成的任何 CREATE TABLE,然后调用以 admin 用户权限执行的函数。此函数更改表的所有者,并分别向摄取者和报告用户授予插入和选择权限。摄取者用户现在能够创建表并将数据插入其中。但是这个摄取者不再能够读取、更新或删除这个表。报告用户只能读取表格。

CREATE OR REPLACE FUNCTION trg_create_table_set_owner()
 RETURNS event_trigger
 LANGUAGE plpgsql 
 SECURITY DEFINER
AS $$
DECLARE
  obj record;
BEGIN
  FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() WHERE command_tag='CREATE TABLE' LOOP
    EXECUTE format('ALTER TABLE %s OWNER TO service_admin', obj.object_identity);
    EXECUTE format('GRANT INSERT ON TABLE %s TO ingester_role;', obj.object_identity);
    EXECUTE format('GRANT SELECT ON TABLE %s TO reporting_role;', obj.object_identity);
  END LOOP;
END;
$$;

CREATE EVENT TRIGGER trg_create_table_set_owner
 ON ddl_command_end
 WHEN tag IN ('CREATE TABLE')
 EXECUTE PROCEDURE trg_create_table_set_owner();
于 2019-10-04T20:53:02.350 回答