尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

PostgreSQL权限管理实践

PostgreSQL权限管理实践
📅 发布时间:2026/6/23 16:09:33

基于user模型

模式和用户同名

只有一个模式

# postgres用户连接
psql -U postgres -c "create user test password 'test';"
psql -U postgres -c "create database testdb with owner=test;" 
psql -U postgres -d testdb -c "CREATE SCHEMA test AUTHORIZATION test;"
#test用户连接创建自定义对象:
psql -U test -d testdb -c "create table test_t(id int)"

这样的好处是,test用户连接testdb默认直接连接到了test模式,因为search_path默认值如下:

postgres=# select name,setting,unit,context from pg_settings where name ~* 'search_path';name     |     setting     | unit | context 
-------------+-----------------+------+---------search_path | "$user", public |      | user
(1 row)

test用户为读写用户,后期如果需要使用只读用户,直接创建用户授权即可

-- 1、创建用户及指定密码:
create user readonly with encrypted password 'readonly';
-- 2、设置用户默认事务只读:
alter user readonly set default_transaction_read_only=on;
-- 3、赋予用户连接数据库权限:
grant connect on database testdb to readonly;
-- 4、切换到指定数据库:
\c testdb
-- 5、赋予用户权限,查看public模式下所有表:
grant usage on schema public to readonly;
alter default privileges in schema public grant select on tables to readonly;
-- 6、赋予指定模式下用户表、序列查看权限:
grant usage on schema test to readonly;
grant select on all sequences in schema test to readonly;
grant select on all tables in schema test to readonly;
alter default privileges in schema test grant select on tables to readonly;

有多个模式

创建数据库

psql -U postgres -c "create user test password 'test';"
psql -U postgres -c "create database testdb with owner=test;"

创建业务用户和模式

psql -U postgres -c "create user user1 password 'user1';"
psql -U postgres -c "create user user2 password 'user2';"
psql -U postgres -d testdb -c "CREATE SCHEMA user1 AUTHORIZATION user1;"
psql -U postgres -d testdb -c "CREATE SCHEMA user2 AUTHORIZATION user2;"

给业务用户授权数据库权限

psql -U postgres -c "grant all privileges on database testdb to user1;"
psql -U postgres -c "grant all privileges on database testdb to user2;"

需要几个模式就创建几个用户,用户和模式同名,用户只允许在和自己同名的模式下创建自定义对象,可以授权其他模式的读权限

授权user2查询user1模式下的查询权限:

grant usage on schema user1 to user2;
grant select on all tables in schema user1 to user2;
alter default privileges in schema user1 grant select on tables to user2;

后期如果还需要创建只读用户,和只有一个模式创建只读用户的场景一样

模式和用户不同名

-- 创建父角色(不能登录,昨晚对象的属主)
create role test;
-- 业务用户
create user test1 password 'test1';
create user test2 password 'test2';
grant test to test1,test2;
-- 创建数据库
create database testdb with owner=test;
-- 创建模式
\c testdb
create schema test_schema authorization test;

业务用户test1连接testdb库,创建自定义对象

-- psql -U test1 -d testdb
create table test_schema.test_t(id int);

 注意此时test1用户创建的表test2用户无权访问(表的属主为test1)

可以把owner转为test用户即可

reassign owned by test1 to test;

基于role模型

权限管理设计模型

该模型简单有效,推荐绝大多数客户使用。

  • 1个RDS PostgreSQL高权限账号,具有所有权限,由少量资深DBA掌握。
  • 项目或者团队维度,1个资源owner账号,2个基本Role:{project}_role_readwrite、{project}_role_readonly。
  • 在Role的基础上创建业务账号:业务账号user = role + login权限。
  • 1个项目或团队可以有多个Schema。权限分配尽量以Schema或Role为单位。
  • 业务表请勿放到schema public中。因为PostgreSQL默认所有用户对schema public都有CREATE和USAGE权限。

权限规划示例

本示例以项目维度进行权限管理示例,同样也适用于团队维度。

  • DBA拥有RDS PostgreSQL实例的高权限账号,名称是dbsuperuser。
  • 业务项目名称是rdspg,新建schema名称是rdspg、rdspg_1。

项目中新增的资源owner账号和Role规划如下:

user/Role schema中表权限 schema中存储过程权限
rdspg_owner (user),是唯一的项目资源owner账号 DDL:CREATE、DROP、ALTER
DQL:SELECT
DML:UPDATE、INSERT、DELETE
DDL:CREATE、DROP、ALTER
DQL:SELECT,调用存储过程
rdspg_role_readwrite (role) DQL:SELECT
DML:UPDATE、INSERT、DELETE
DQL(SELECT,调用存储过程) ,若存储过程有DDL操作,会抛出权限相关错误。
rdspg_role_readonly (role) DQL(SELECT) DQL(SELECT,调用存储过程),若存储过程有DDL或者DML操作,会抛出权限相关错误。

新增业务账号时,根据不同需求,采用如下管理模式创建:

  • rdspg_readwrite = rdspg_role_readwrite + login权限
  • rdspg_readonly = rdspg_role_readonly + login权限

配置步骤:

1、创建项目资源owner账号rdspg_owner和项目Role。DBA使用dbsuperuser高权限账号执行如下操作。

-- rdspg_owner 是项目管理账号
CREATE USER rdspg_owner WITH LOGIN PASSWORD 'asdfy181BASDfadasdbfas';
-- 创建业务数据库
create database testdb owner=rdspg_owner;
\c testdbCREATE ROLE rdspg_role_readwrite;
CREATE ROLE rdspg_role_readonly;-- 设置: 对于rdspg_owner 创建的表,rdspg_role_readwrite 有 DQL(SELECT)、DML(UPDATE、INSERT、DELETE)权限。
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON TABLES TO rdspg_role_readwrite;-- 设置: 对于rdspg_owner 创建的SEQUENCES,rdspg_role_readwrite 有 DQL(SELECT)、DML(UPDATE、INSERT、DELETE)权限。
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON SEQUENCES TO rdspg_role_readwrite;-- 设置: 对于 rdspg_owner 创建的表, rdspg_role_readonly 只有 DQL(SELECT)权限。
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT SELECT ON TABLES TO rdspg_role_readonly;

2、创建rdspg_readwrite、rdspg_readonly业务账号。DBA使用dbsuperuser高权限账号执行如下操作。

-- rdspg_readwrite只有 DQL(SELECT)、DML(UPDATE、INSERT、DELETE)权限。
CREATE USER rdspg_readwrite WITH LOGIN PASSWORD 'dfandfnapSDhf23hbEfabf';
GRANT rdspg_role_readwrite TO rdspg_readwrite;-- rdspg_readonly只有 DQL(SELECT)权限。
CREATE USER rdspg_readonly WITH LOGIN PASSWORD 'F89h912badSHfadsd01zlk';
GRANT rdspg_role_readonly TO rdspg_readonly;

3、创建schema rdspg,并授权给项目Role。DBA使用dbsuperuser高权限账号执行如下操作。

-- schema rdspg的owner是 rdspg_owner账号
CREATE SCHEMA rdspg AUTHORIZATION rdspg_owner;-- 授权ROLE相关SCHEMA访问权限。
GRANT USAGE ON SCHEMA rdspg TO rdspg_role_readwrite;
GRANT USAGE ON SCHEMA rdspg TO rdspg_role_readonly;

**说明: **rdspg_readwrite和rdspg_readonly自动继承了相关Role的权限变更,不需要再额外操作。

应用场景示例

场景1:使用rdspg_owner账号:对schema rdspg中的表进行DDL(CREATE、DROP、ALTER)操作

\c testdb rdspg_owner
CREATE TABLE rdspg.test(id bigserial primary key, name text);
CREATE INDEX idx_test_name on rdspg.test(name);

场景2:使用 rdspg_readwrite/rdspg_readonly 账号进行业务开发

业务开发遵循最小权限原则,尽量使用rdspg_readonly账号,需要DML操作的地方才使用rdspg_readwrite账号。这样也方便在业务层做读写分离

说明:

  • 业务层做读写分离,避免了自动读写分离中间件proxy带来的额外成本和性能损耗。
  • 即使目前还没有使用只读实例,也建议区分 readonly客户端、readwrite客户端,为使用只读实例做准备。readonly客户端建议使用readonly账号,最小权限原则,规避权限误用。
  • readonly客户端,使用readonly账号,设置JDBC URL:只读实例1地址,只读实例2地址,读写实例地址。
  • readwrite客户端,使用readwrite账号,设置JDBC URL:读写实例地址。

使用rdspg_readwrite账号,对schema rdspg中的表进行DQL(SELECT)、DML(UPDATE、INSERT、DELETE)操作:

\c testdb rdspg_readwrite
INSERT INTO rdspg.test (name) VALUES('name0'),('name1');
SELECT id,name FROM rdspg.test LIMIT 1;-- rdspg_readwrite没有 DDL(CREATE、DROP、ALTER)权限
CREATE TABLE rdspg.test2(id int);
ERROR:  permission denied for schema rdspg
LINE 1: create table rdspg.test2(id int);DROP TABLE rdspg.test;
ERROR:  must be owner of table testALTER TABLE rdspg.test ADD id2 int;
ERROR:  must be owner of table testCREATE INDEX idx_test_name on rdspg.test(name);
ERROR:  must be owner of table test

使用rdspg_readonly账号,对schema rdspg中的表进行DQL(SELECT)操作:

\c testdb rdspg_readonly
INSERT INTO rdspg.test (name) VALUES('name0'),('name1');
ERROR:  permission denied for table testSELECT id,name FROM rdspg.test LIMIT 1;id | name
----+-------1 | name0
(1 row)

场景3:不同项目交叉授权

有个新项目employee,创建role和user以及授权如下:

\c testdb dbsuperuser
CREATE ROLE employee_role_readwrite;
CREATE ROLE employee_role_readonly;ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON TABLES TO employee_role_readwrite;
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON SEQUENCES TO employee_role_readwrite;
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT SELECT ON TABLES TO employee_role_readonly;CREATE USER employee_readwrite WITH LOGIN PASSWORD 'dfandfnapSDhf23hbEfabf';
GRANT employee_role_readwrite TO employee_readwrite;
CREATE USER employee_readonly WITH LOGIN PASSWORD 'F89h912badSHfadsd01zlk';
GRANT employee_role_readonly TO employee_readonly;

现在需要为账号employee_readwrite增加rdspg项目的表只读权限。DBA使用dbsuperuser高权限账号做如下操作:

-- 给账号 employee_readwrite 加上 rdspg_role_readonly 权限集合。
\c testdb dbsuperuser
GRANT rdspg_role_readonly TO employee_readwrite;

场景4:项目新增 schema rdspg_1,并授权给项目Role

rdspg_readwrite、rdspg_readonly、employee_readwrite账号自动继承了相关Role的权限变更,不需要再额外操作。DBA使用dbsuperuser 高权限账号做如下操作:

\c testdb dbsuperuser
CREATE SCHEMA rdspg_1 AUTHORIZATION rdspg_owner;-- 授权ROLE相关SCHEMA访问权限。
-- CREATE 使得 rdspg_owner 对schema rdspg_1中的表有 DDL(CREATE、DROP、ALTER)权限。
GRANT USAGE ON SCHEMA rdspg_1 TO rdspg_role_readwrite;
GRANT USAGE ON SCHEMA rdspg_1 TO rdspg_role_readonly;

账号权限查询

psql客户端,使用元命令\du查看所有用户和拥有的角色:

image-20251126230011754

从上述查询结果示例中可以看出:employee_readwrite账号的Member of列中,内容为rdspg_role_readonly,employee_role_readwrite,因此,此账号对employee项目表具有DQL和DML权限,对rdspg项目表具有DQL权限。

使用SQL查询

SELECT r.rolname, r.rolsuper, r.rolinherit,r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,r.rolconnlimit, r.rolvaliduntil,ARRAY(SELECT b.rolnameFROM pg_catalog.pg_auth_members mJOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)WHERE m.member = r.oid) as memberof
, r.rolreplication
, r.rolbypassrls
FROM pg_catalog.pg_roles r
WHERE r.rolname !~ '^pg_'
ORDER BY 1;

参考资料

https://help.aliyun.com/zh/rds/apsaradb-rds-for-postgresql/manage-permissions-in-an-apsaradb-rds-for-postgesql-instance

https://support.huaweicloud.com/bestpractice-rds-pg/rds_pg_0035.html

相关新闻

  • 预编译命令
  • 本地环境自建的es重启,http和https访问es,nested数据类型及设置es别名
  • 迈向人机共育的文明语法:AI元人文理论体系深度阐释——内观照叙事模型

最新新闻

  • UniLaViRA/HumanoidMimicGen/VERA/Tabero/S-Cheetah/FGO六大具身SOTA全网独家复现|零样本跨体导航/人形数据扩增/视频动作映射/触觉柔顺控力/仿生四足
  • 毕业设计 深度学习yolo藻类细胞检测识别(科研辅助系统)(源码+论文)
  • 鸿蒙 NDK开发:使用命令行CMake构建工程(三)
  • Windows系统文件FM20.DLL丢失找不到问题解决
  • 为什么你越讨好别人,越没人把你当回事?
  • Shell脚本为何成为AI智能体视觉(TVA)的“反射弧”(7)

日新闻

  • Arduino-ESP32项目深度解析:解锁隐藏芯片支持与架构演进
  • 2026年 系统窗厂家/品牌推荐榜单:隔音系统窗+高端系统门窗的核心优势与选购指南 - 品牌发掘
  • NVBench:首个双语非言语发声语音合成评测基准详解与实践

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号