行级安全策略
行级安全策略(Row Level Security,以下简称RLS),允许在表级别对数据行的访问权限进行控制,支持细粒度的访问隔离。它通过管理员对表的行创建访问规则,控制用户可以查看或者修改的行。
RLS应用范围
-
行级安全策略支持以下命令:
ALL
、SELECT
、INSERT
、UPDATE
、DELETE
-
行级安全策略可以授予多个角色。
-
行级安全策略可以同时赋予在命令和角色上。
-
全表操作命令,如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 POLICY
、ALTER POLICY
和DROP 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。