行级安全策略

行级安全策略

行级安全策略(Row Level Security,以下简称RLS),允许在表级别对数据行的访问权限进行控制,支持细粒度的访问隔离。它通过管理员对表的行创建访问规则,控制用户可以查看或者修改的行。

RLS应用范围

  • 行级安全策略支持以下命令:ALLSELECTINSERTUPDATEDELETE

  • 行级安全策略可以授予多个角色。

  • 行级安全策略可以同时赋予在命令和角色上。

  • 全表操作命令,如TRUNCATE、REFERENCES命令由于其特殊的操作方式,不适用于行级权限。

RLS创建语法

CREATE POLICY policy_name ON table_name 
[ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ] 
[ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ] 
[ USING ( using_expression ) ] 
[ WITH CHECK ( check_expression ) ] 
  • policy_name: 策略名,每个策略都有一个名字,每个表可以定义多个策略,表的范围内策略名字唯一,不同的表可以有同名的策略,当表有多个策略时,多个策略之间是OR的关系。

  • USING:针对已经存在的记录的校验,可实施在SELECT,INSERT,UPDATE,DELETE,或者ALL上。

  • WITH CHECK:针对将要新增或变更的记录上的校验,可实施在SELECT,INSERT,UPDATE,DELETE,或者ALL上。

可以使用 CREATE POLICYALTER POLICYDROP POLICY命令来管理策略(创建、修改和删除)。

-- 查询当前策略
SELECT * FROM pg_policies WHERE tablename='table_name';

管理RLS

在目标表启用RLS

ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;

关闭RLS

ALTER TABLE table_name DISABLE ROW LEVEL SECURITY;

示例

 
-- 订单数据按照租户分组
CREATE TABLE order_details (order_id text, tenant_name text, order_detail text);
 
ALTER TABLE order_details ENABLE ROW LEVEL SECURITY;
 
-- 控制只能访问自己租户的数据
CREATE POLICY order_multi_tenant ON order_details 
USING (tenant_name = current_user);
 
-- 创建多个策略,它们会被结合应用,多个策略为OR的关系:
CREATE POLICY order_update ON order_details
FOR UPDATE
USING (tenant_name = current_user)
WITH CHECK (order_id IS NOT NULL);
protonbase=> \d order_details
             Table "public.order_details"
    Column    | Type | Collation | Nullable | Default 
--------------+------+-----------+----------+---------
 order_id     | text |           |          | 
 tenant_name  | text |           |          | 
 order_detail | text |           |          | 
Policies:
    POLICY "order_multi_tenant"
      USING ((tenant_name = current_user))
    POLICY "order_update" FOR UPDATE
      USING ((tenant_name = current_user))
      WITH CHECK ((order_id IS NOT NULL))

更多有关RLS的使用,请参考Row Security Policies