KingbaseES行级安全策略

什么是行级安全策略(RLS)?
行安全策略就是对不同用户,不同行数据的可见性,和可修改性。是表权限的一种扩展。

默认情况下表没有任何安全策略限制。这样用户根据自身对表持有的权限来操作表数据,对于查询或更新来说其中所有的行都是平等的。
当在一个表上启用行安全性时,所有对该表的操作都必须被一条行安全性策略所允许。如果为一个表启用了行级安全策略但是没有适用的策略存在,将假定为一种 “默认否定”策略,这样任何行都不可见也不可更新。
但是对全表进行操作的命令,比如 TRUNCATE 和 REFERENCES 不受影响。

行安全性策略可以针对特定的命令、角色或者两者。一条策略可以被指定为适用于ALL命令,或者查询(SELECT)、 插入(INSERT)、更新(UPDATE)或者删除(DELETE)。
同一个策略可分配多个角色,并且通常的角色成员关系和继承规则也适用。但是表的所有者,超级用户 (postgres) 以及加上了 BYPASSRLS 属性的角色不受安全性的限制。
只有表的所有者才具有启用 / 禁用行级安全性,给表添加策略的权限。

策略的相关命令
CREATE POLICY :创建策略
ALTER POLICY :修改策略
DROP POLICY :删除策略
ALTER TABLE xxx ENABLE/disable ROW LEVEL SECURITY :用于行级安全性的启用 / 禁用。

示例
初始化数据

CREATE TABLE usertest (id text, name text);
insert into usertest values(1,'u1');
insert into usertest values(2,'u2');
insert into usertest values(3,'u3');

将DML权限赋给用户u1,u2;
grant select,insert,update ON public.usertest to u1,u2;

create policy u1_select ON usertest for select to u1 using(name=current_user);

策略创建后默认是禁用的,需要通过alter table来开启表的行级安全功能

test1=# \d usertest
        数据表 "public.usertest"
 栏位 | 类型 | 校对规则 | 可空的 | 预设 
------+------+----------+--------+------
 id   | text |          |        | 
 name | text |          |        | 
策略(行安全性禁用):
    POLICY "u1_select" FOR SELECT
      TO u1
      USING ((name = CURRENT_USER))

alter table usertest enable row level security;

test1=# \d usertest
        数据表 "public.usertest"
 栏位 | 类型 | 校对规则 | 可空的 | 预设 
------+------+----------+--------+------
 id   | text |          |        | 
 name | text |          |        | 
策略:
    POLICY "u1_select" FOR SELECT
      TO u1
      USING ((name = CURRENT_USER))

开启安全策略后,使用u1/u2用户连接数据库,验证用户可访问数据情况:

test=# \c test1 system
您现在已经连接到数据库 "test1",用户 "system".
test1=# select * from usertest; 
 id | name 
----+------
 1  | u1
 2  | u2
 3  | u3
(3 行记录)

test1=# \c - u1;
您现在已经连接到数据库 "test1",用户 "u1".
test1=> select * from usertest;
 id | name 
----+------
 1  | u1
(1 行记录)

test1=> \c - u2;
您现在已经连接到数据库 "test1",用户 "u2".
test1=> select * from usertest ;
 id | name 
----+------
(0 行记录)

u1用户只能查询到name=u1的数据,u2用户无法查询到任何数据。符合预期说明策略已正常生效了。

test1=> \c - system
您现在已经连接到数据库 "test1",用户 "system".
test1=# alter user u2 bypassrls;
ALTER ROLE
test1=# \c - u2;
您现在已经连接到数据库 "test",用户 "u2".
test1=> select * from usertest ;
 id | name
----+------
 1  | u1
 2  | u2
 3  | u3
(3 行记录)

给u2用户赋予bypassrls权限,u2用户可以绕过表的rls策略。
posted @ 2024-03-29 18:38  KINGBASE研究院  阅读(19)  评论(0编辑  收藏  举报