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策略。
KINGBASE研究院