Postgresql 中文操作指南

31.9. Security #

用于复制连接的角色必须具有 REPLICATION 属性(或为超级用户)。如果角色缺少 SUPERUSERBYPASSRLS,发布者行安全策略可以执行。如果角色不信任所有表所有者,请在连接字符串中包括 options=-crow_security=off;如果表所有者添加行安全策略,则该设置将导致复制停止,而不是执行该策略。必须在 pg_hba.conf 中配置角色的访问权限,并且它必须具有 LOGIN 属性。

为了能够复制初始表数据,用于复制连接的角色必须在已发布表上具有 SELECT 权限(或为超级用户)。

要创建发布,用户必须在数据库中具有 CREATE 权限。

要将表添加到发布中,用户必须对该表拥有所有权。要将架构中的所有表添加到发布中,用户必须为超级用户。要创建发布以自动发布所有表或架构中的所有表,用户必须是超级用户。

当前没有针对发布的权限。任何订阅(能够连接)都可以访问任何发布。因此,如果您打算通过使用行过滤器或列列表或通过不将整个表添加到发布中来向特定订阅者隐藏某些信息,请注意同一数据库中的其他发布可能会公开相同的信息。将来可能会向 PostgreSQL 添加发布权限,以允许更细粒度的访问控制。

要创建订阅,用户必须拥有 pg_create_subscription 角色的权限,以及数据库中的 CREATE 权限。

订阅应用进程将在会话级别使用订阅所有者的权限来运行。但是,在对特定表执行插入、更新、删除或截断操作时,它将切换角色为表所有者并以表所有者的权限执行操作。这意味着订阅所有者需要能够 SET ROLE 拥有复制表的每个角色。

如果已使用 run_as_owner = true 配置订阅,则不会发生用户切换。相反,所有操作都将通过订阅所有者的权限来执行。在这种情况下,订阅所有者只需对目标表的 SELECTINSERTUPDATEDELETE 具有权限,而无需 SET ROLE 权限对表所有者。但是,这也意味着拥有正在复制到的表的所有者可以以订阅所有者的权限执行任意代码。例如,他们可以通过简单地将触发器附加到他们拥有的某个表来执行此操作。因为通常不想允许一个角色自由地承担另一个角色的权限,所以除非不关心数据库内的用户安全,否则应避免此选项。

在发布者上,只能在复制连接开始时检查一次权限,并且在读取每个更改记录时不会重新检查权限。

在订阅者上,每次应用事务时都会重新检查订阅所有者的权限。如果某个工作进程正在应用事务时订阅的所有权被并发事务更改,则当前事务的应用程序将继续在旧所有者的权限下运行。