千家信息网

PostgreSQL DBA(102) - pgAdmin(Row Level Security)

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,PostgreSQL提供了Row Level Security(RLS)来控制哪些行可以访问或修改。一、简介其标准的语法是:[pg12@localhost ~]$ psql -d testdbTimi
千家信息网最后更新 2026年11月03日PostgreSQL DBA(102) - pgAdmin(Row Level Security)

PostgreSQL提供了Row Level Security(RLS)来控制哪些行可以访问或修改。

一、简介
其标准的语法是:

[pg12@localhost ~]$ psql -d testdbTiming is on.Expanded display is used automatically.psql (12.0)Type "help" for help.[local]:5432 pg12@testdb=# \help create policyCommand:     CREATE POLICYDescription: define a new row level security policy for a tableSyntax:CREATE POLICY name ON table_name    [ AS { PERMISSIVE | RESTRICTIVE } ]    [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]    [ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ]    [ USING ( using_expression ) ]    [ WITH CHECK ( check_expression ) ]URL: https://www.postgresql.org/docs/12/sql-createpolicy.html[local]:5432 pg12@testdb=#

其中,USING表示满足using_expression表达式为T的行才能看到或操作,否则这些行将被隐藏(hidden);
WITH CHECK表示在执行INSERT/UPDATE操作时,如新数据不能通过check_expression表达式的校验则被视为非法数据。

二、注意事项
1.RLS必须通过ALTER TABLE … ENABLE ROW LEVEL SECURITY显式启用;
2.如启用RLS,那么至少存在一个policy
创建数据表,插入数据,启用RLS

[local]:5432 pg12@testdb=# drop table if exists t_rls1;NOTICE:  table "t_rls1" does not exist, skippingDROP TABLETime: 37.363 ms[local]:5432 pg12@testdb=# create table t_rls1(id int,c1 int);CREATE TABLETime: 137.931 ms[local]:5432 pg12@testdb=# [local]:5432 pg12@testdb=# insert into t_rls1 values(1,1);INSERT 0 1Time: 1.820 ms[local]:5432 pg12@testdb=# insert into t_rls1 values(2,2);INSERT 0 1Time: 0.582 ms[local]:5432 pg12@testdb=# [local]:5432 pg12@testdb=# ALTER TABLE t_rls1 ENABLE ROW LEVEL SECURITY;ALTER TABLETime: 1.714 ms[local]:5432 pg12@testdb=# select * from t_rls1; id | c1 ----+----  1 |  1  2 |  2(2 rows)

创建新的user,查询数据表,因为不存在policy,因此没有数据返回(但为什么pg12这个用户可以?后续有解释)

Time: 23.349 ms[local]:5432 pg12@testdb=# create user testuser with passwod 'test';ERROR:  unrecognized role option "passwod"LINE 1: create user testuser with passwod 'test';                                  ^Time: 1.165 ms[local]:5432 pg12@testdb=# create user testuser with password 'test';CREATE ROLETime: 15.721 ms[local]:5432 pg12@testdb=# grant all on t_rls1 to testuser;GRANTTime: 8.125 ms[local]:5432 pg12@testdb=#

3.同一个命令,同一种类型,多个policys之间是OR的关系,即某行满足其中一个policy就可以返回(如select命令);同一个命令不同的命令类型,则多个policys之间的关系是AND,必须所有policys都满足才能返回(如update中存在where子句时)。
4.只有表的owner可以创建policys
5.超级用户或者具有BYPASSRLS权限的用户会跳过RLS检查。这解释先前为什么policy没有,但pg12查询有数据返回但testuser用户没有。

[local]:5432 pg12@testdb=# \du                                   List of roles Role name |                         Attributes                         | Member of -----------+------------------------------------------------------------+----------- pg12      | Superuser, Create role, Create DB, Replication, Bypass RLS | {} testuser  |

6.数据表的owner用户默认会跳过RLS检查

[local]:5432 testuser@testdb=> create table t_rls2(id int,c1 int);CREATE TABLETime: 10.256 ms[local]:5432 testuser@testdb=> [local]:5432 testuser@testdb=> insert into t_rls2 values(1,1);INSERT 0 1Time: 3.422 ms[local]:5432 testuser@testdb=> insert into t_rls2 values(2,2);INSERT 0 1Time: 2.580 ms[local]:5432 testuser@testdb=> [local]:5432 testuser@testdb=> ALTER TABLE t_rls2 ENABLE ROW LEVEL SECURITY;ALTER TABLETime: 2.124 ms[local]:5432 testuser@testdb=> select * from t_rls2; id | c1 ----+----  1 |  1  2 |  2(2 rows)Time: 1.127 ms[local]:5432 testuser@testdb=> \d t_rls2               Table "public.t_rls2" Column |  Type   | Collation | Nullable | Default --------+---------+-----------+----------+--------- id     | integer |           |          |  c1     | integer |           |          | Policies (row security enabled): (none)

testuser1&testuser2均为普通用户,但testuser1查询数据有返回,但testuser2没有

[pg12@localhost ~]$ psql -d testdb -U testuser2Timing is on.Expanded display is used automatically.psql (12.0)Type "help" for help.[local]:5432 testuser2@testdb=> select * from t_rls2; id | c1 ----+----(0 rows)Time: 3.808 ms[local]:5432 testuser2@testdb=>

可通过ALTER TABLE … FORCE ROW LEVEL SECURITY命令强制启用

[local]:5432 testuser@testdb=> ALTER TABLE t_rls2 FORCE ROW LEVEL SECURITY;ALTER TABLETime: 1.967 ms[local]:5432 testuser@testdb=> select * from t_rls2; id | c1 ----+----(0 rows)Time: 2.369 ms

具体的应用案例可详见参考资料中的链接。

三、参考资料
PG Conf of US 2019 - Row Level Security
Using "Row Level Security" to make large companies more secure

数据 用户 命令 数据表 查询 之间 参考资料 多个 类型 表达式 资料 参考 检查 解释 不同 普通 事项 只有 子句 权限 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 国智互联网科技 深圳恒合互联网络科技有限公司 科技股互联网 互联网科技未来 没上市的科技互联网公司 青岛互联网科技公司 九亚互联网科技 互联网科技logo设计 友谊互联网络科技 互联网科技股午盘股票涨跌 华夏恒生互联网科技013171 中和天地互联网科技有限公司 雨阳互联网卡科技有限公司 互联网科技资金流入 宁波跨境商互联网科技有限公司 珠海东科互联网科技有限公司 互联网高科技行业有哪些企业 长沙渺峰互联网科技有限公司 第三届互联网大会安防黑科技 广东猫王互联网科技有限公司电话 互联网科技巨头监管 北京互联网科技 互联网科技视频素材 新华互联网科技校企合作 开启互联网科技时代小说 广州慧亚互联网科技怎么样 苏州铭阳互联网科技有限公司 成都互联网科技公司工作好不好 畅思互联网科技 福仕德教育科技互联网
0