【问题标题】:How to idempotently define row-level security policies in PostgreSQL?如何在 PostgreSQL 中幂等地定义行级安全策略?
【发布时间】:2021-09-04 15:44:30
【问题描述】:

我最近了解了 SQL 中的行级安全策略,并且喜欢能够在数据库中运行重要的安全逻辑的想法。但是,我不确定如何使更新 RLS 策略的工作流程与更新 API 代码一样好。

由于 RLS 策略本质上只是无状态逻辑,感觉就像我应该能够在一个 sql 模式文件中定义它们,该文件被检入 git 并在每次部署时运行以幂等设置策略。

我们可以通过使用drop if exists 获得一些方法,例如:

drop policy if exists "everyone can read" on patterns;
create policy "everyone can read" on patterns for select using (auth.role() = 'anon');

这看起来不错,但它并不是真正的声明性,因为它不会从以前版本的架构中删除数据库中仍然存在的任何策略。我可以删除表的所有现有策略然后重新创建它们吗?还是有其他方法可以解决这个问题?

【问题讨论】:

  • 我不明白这个问题。如果您想摆脱策略,您唯一需要做的就是包含drop policy if exists 行,但不要添加create policy 行。
  • 是的,但是为了确保它正确同步,我必须在文件中为曾经存在于任何版本的数据库中的每个策略保留一个 drop 语句。它可以工作,但有点乱,我想出了如何查询现有策略。
  • 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。

标签: sql postgresql


【解决方案1】:

我想出了如何删除所有策略。有两个列出策略的目录表; pg_policy 具有低级信息,而 pg_policies 对此更有用,因为它直接包含表名。

-- Drop all existing policies
do
$$
declare
   rec record;
begin
   for rec in (SELECT tablename, policyname FROM pg_policies)
   loop
     execute 'drop policy "'||rec.policyname||'" on '||rec.tablename;
   end loop;
end;
$$;

【讨论】:

  • 您应该使用format 进行正确的转义。也不要忽略表的模式名称。 SELECT polname AS name, polrelid::regclass AS table FROM pg_policyEXECUTE format('DROP POLICY %i ON %s, pol.name, pol.table);
【解决方案2】:

你有两个选择:

  • 查询 pg_policy 以获取表上的所有策略并删除它们

  • 删除任何版本的架构中曾经存在的所有策略

【讨论】:

    猜你喜欢
    • 2022-07-07
    • 2022-01-03
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    • 2018-04-30
    • 2021-02-08
    相关资源
    最近更新 更多