PostgreSQL实战:详解权限设置与管理全流程

文章目录

    • 一、权限概述
      • [1.1 为什么权限管理至关重要?](#1.1 为什么权限管理至关重要?)
      • [1.2 安全检查清单](#1.2 安全检查清单)
      • [1.3 权限管理核心原则](#1.3 权限管理核心原则)
    • [二、PostgreSQL 权限体系全景图](#二、PostgreSQL 权限体系全景图)
      • [1. 核心概念层级](#1. 核心概念层级)
      • [2. 权限类型速查表](#2. 权限类型速查表)
    • 三、角色(Roles)管理:权限的载体
      • [1. 创建角色(用户/组)](#1. 创建角色(用户/组))
      • [2. 角色继承与成员关系](#2. 角色继承与成员关系)
    • 四、数据库级权限
      • [1. 授权连接与创建对象](#1. 授权连接与创建对象)
      • [2. 默认权限(关键!)](#2. 默认权限(关键!))
    • [五、Schema 级权限](#五、Schema 级权限)
      • [1. 基础权限](#1. 基础权限)
      • [2. 安全建议](#2. 安全建议)
    • 六、表级权限(最常用)
      • [1. 基础 CRUD 授权](#1. 基础 CRUD 授权)
      • [2. 列级权限(敏感数据保护)](#2. 列级权限(敏感数据保护))
      • [3. 序列权限(自增ID)](#3. 序列权限(自增ID))
    • 七、函数与存储过程权限
    • 八、权限查询与审计
      • [1. 查看对象权限](#1. 查看对象权限)
      • [2. 查看角色拥有的权限](#2. 查看角色拥有的权限)
      • [3. 使用 psql 快捷命令](#3. 使用 psql 快捷命令)
    • 九、企业级权限管理流程
      • [场景:为新微服务 `order-service` 配置权限](#场景:为新微服务 order-service 配置权限)
        • [步骤 1:创建专用角色](#步骤 1:创建专用角色)
        • [步骤 2:授权数据库连接](#步骤 2:授权数据库连接)
        • [步骤 3:授权 Schema 权限](#步骤 3:授权 Schema 权限)
        • [步骤 4:授权表权限](#步骤 4:授权表权限)
        • [步骤 5:设置默认权限(防遗漏)](#步骤 5:设置默认权限(防遗漏))
        • [步骤 6:验证权限](#步骤 6:验证权限)
    • 十、高级技巧与陷阱规避
      • [1. 权限回收(REVOKE)](#1. 权限回收(REVOKE))
      • [2. PUBLIC 角色陷阱](#2. PUBLIC 角色陷阱)
      • [3. 权限与 Ownership](#3. 权限与 Ownership)
      • [4. RLS(行级安全)补充](#4. RLS(行级安全)补充)

适用版本 :PostgreSQL 12+(语法兼容 10+)
目标读者 :DBA、后端开发、运维工程师
核心价值:从零构建企业级权限体系,避免"删库跑路"风险

一、权限概述

1.1 为什么权限管理至关重要?

PostgreSQL 的权限模型是其安全基石。错误的权限配置可能导致:

  • 数据泄露(如普通用户读取 users.password
  • 服务中断(如应用账号误删表)
  • 权限蔓延(如开发人员拥有 SUPERUSER
  • 合规失败(违反 GDPR、等保要求)

黄金法则最小权限原则(Principle of Least Privilege)

1.2 安全检查清单

部署前必查

  • 所有应用账号无 SUPERUSER 权限
  • 敏感表(如 users)已限制列权限
  • public schema 已禁用 CREATE
  • 默认权限已配置
  • 无多余 PUBLIC 权限
  • 密码符合复杂度要求(用 scram-sha-256
  • 防火墙限制数据库端口访问 IP

1.3 权限管理核心原则

  1. 分层授权:Database → Schema → Table → Column
  2. 角色驱动:用非登录角色作为权限容器
  3. 默认权限:防止新对象权限遗漏
  4. 最小特权:只给必要权限,定期审计
  5. 自动化:用脚本管理权限,避免手工操作

记住:权限体系不是"一次配置,终身无忧",而是需要持续维护的安全防线。

二、PostgreSQL 权限体系全景图

1. 核心概念层级

复制代码
Cluster (实例)
└── Database (数据库)
    ├── Schema (模式)
    │   ├── Table/View/Sequence (对象)
    │   └── Function (函数)
    └── Roles (角色) → 权限载体

2. 权限类型速查表

对象类型 可授权权限 关键说明
DATABASE CONNECT, CREATE, TEMPORARY CONNECT 是基础
SCHEMA USAGE, CREATE USAGE 允许访问对象
TABLE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER 列级权限需单独授权
COLUMN SELECT, INSERT, UPDATE 高敏感字段保护
SEQUENCE USAGE, SELECT, UPDATE 自增ID控制
FUNCTION EXECUTE 存储过程调用
ALL PRIVILEGES 所有权限(慎用!) 不包含 GRANT OPTION

注意:GRANT OPTION 允许被授权者再授权(默认不包含)


三、角色(Roles)管理:权限的载体

PostgreSQL 中 用户 = 角色 + LOGIN 属性

1. 创建角色(用户/组)

sql 复制代码
-- 创建登录用户(带密码)
CREATE ROLE app_user WITH LOGIN PASSWORD 'StrongPass123!';

-- 创建非登录角色(用于权限分组)
CREATE ROLE read_only;
CREATE ROLE data_writer;

-- 创建超级用户(极度危险!仅限DBA)
CREATE ROLE dba_admin WITH SUPERUSER CREATEDB CREATEROLE LOGIN PASSWORD '...';

2. 角色继承与成员关系

sql 复制代码
-- 将用户加入权限组(自动继承权限)
GRANT read_only TO app_user;
GRANT data_writer TO app_user;

-- 查看角色成员
\du app_user

最佳实践

  • 非登录角色 作为权限容器(如 read_only
  • 用户只加入必要角色,避免直接授权

四、数据库级权限

1. 授权连接与创建对象

sql 复制代码
-- 允许角色连接数据库
GRANT CONNECT ON DATABASE myapp TO app_user;

-- 允许在数据库中创建临时表
GRANT TEMPORARY ON DATABASE myapp TO app_user;

-- 允许创建新 schema(通常只给管理员)
GRANT CREATE ON DATABASE myapp TO dba_admin;

2. 默认权限(关键!)

新创建的对象不会自动继承权限!需设置默认权限:

sql 复制代码
-- 设置未来在 public schema 创建的表自动授权 SELECT 给 read_only
ALTER DEFAULT PRIVILEGES 
    FOR ROLE db_owner  -- 对象创建者
    IN SCHEMA public
    GRANT SELECT ON TABLES TO read_only;

-- 设置序列 USAGE 权限
ALTER DEFAULT PRIVILEGES 
    FOR ROLE db_owner
    IN SCHEMA public
    GRANT USAGE ON SEQUENCES TO data_writer;

🔥 血泪教训:忘记设默认权限 → 新表无法被应用访问!


五、Schema 级权限

1. 基础权限

sql 复制代码
-- 允许使用 schema(必须先有此权限才能访问内部对象)
GRANT USAGE ON SCHEMA public TO app_user;

-- 允许在 schema 中创建对象(表/函数等)
GRANT CREATE ON SCHEMA analytics TO data_scientist;

2. 安全建议

  • 不要滥用 public schema :生产环境建议创建专用 schema(如 app_schema

  • 限制 public 权限

    sql 复制代码
    REVOKE CREATE ON SCHEMA public FROM PUBLIC; -- 禁止所有用户在 public 建表

六、表级权限(最常用)

1. 基础 CRUD 授权

sql 复制代码
-- 授权完整 CRUD
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE orders TO data_writer;

-- 只读权限
GRANT SELECT ON TABLE users TO read_only;

-- 授权所有表(慎用!)
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;

2. 列级权限(敏感数据保护)

sql 复制代码
-- 只允许读取非敏感列
GRANT SELECT (id, name, email) ON TABLE users TO app_user;

-- 禁止更新密码列
GRANT UPDATE (name, email) ON TABLE users TO app_user;
-- 注意:未授权的列将无法 UPDATE

3. 序列权限(自增ID)

sql 复制代码
-- 允许获取下一个 ID(INSERT 必需)
GRANT USAGE ON SEQUENCE orders_id_seq TO data_writer;

-- 允许查看当前值(调试用)
GRANT SELECT ON SEQUENCE orders_id_seq TO read_only;

七、函数与存储过程权限

sql 复制代码
-- 授权执行函数
GRANT EXECUTE ON FUNCTION calculate_discount(numeric) TO app_user;

-- 授权所有函数
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO app_user;

💡 函数权限独立于表权限!即使无表 SELECT 权限,仍可执行返回数据的函数。


八、权限查询与审计

1. 查看对象权限

sql 复制代码
-- 查看表权限
SELECT grantee, privilege_type 
FROM information_schema.role_table_grants 
WHERE table_name = 'orders';

-- 查看列权限
SELECT grantee, column_name, privilege_type
FROM information_schema.column_privileges
WHERE table_name = 'users';

2. 查看角色拥有的权限

sql 复制代码
-- 查看角色能访问哪些表
SELECT table_schema, table_name, privilege_type
FROM information_schema.table_privileges
WHERE grantee = 'app_user';

-- 查看默认权限
SELECT * FROM pg_default_acl;

3. 使用 psql 快捷命令

bash 复制代码
-- 列出数据库权限
\l+ myapp

-- 列出 schema 权限
\dn+ public

-- 列出表权限
\dp orders

九、企业级权限管理流程

场景:为新微服务 order-service 配置权限

步骤 1:创建专用角色
sql 复制代码
-- 权限组角色(非登录)
CREATE ROLE order_reader;
CREATE ROLE order_writer;

-- 应用用户
CREATE ROLE order_app WITH LOGIN PASSWORD '...';
GRANT order_reader, order_writer TO order_app;
步骤 2:授权数据库连接
sql 复制代码
GRANT CONNECT ON DATABASE ecommerce TO order_app;
步骤 3:授权 Schema 权限
sql 复制代码
-- 假设使用专用 schema
CREATE SCHEMA IF NOT EXISTS order_schema AUTHORIZATION db_owner;
GRANT USAGE ON SCHEMA order_schema TO order_reader;
GRANT CREATE ON SCHEMA order_schema TO db_owner; -- 仅 DBA
步骤 4:授权表权限
sql 复制代码
-- 只读表
GRANT SELECT ON TABLE order_schema.products TO order_reader;

-- 读写表
GRANT SELECT, INSERT, UPDATE ON TABLE order_schema.orders TO order_writer;
GRANT USAGE ON SEQUENCE order_schema.orders_id_seq TO order_writer;

-- 敏感表(禁止访问)
-- 不授权 payment_cards 表
步骤 5:设置默认权限(防遗漏)
sql 复制代码
ALTER DEFAULT PRIVILEGES 
    FOR ROLE db_owner
    IN SCHEMA order_schema
    GRANT SELECT ON TABLES TO order_reader;

ALTER DEFAULT PRIVILEGES 
    FOR ROLE db_owner
    IN SCHEMA order_schema
    GRANT SELECT, INSERT, UPDATE ON TABLES TO order_writer;
步骤 6:验证权限
sql 复制代码
-- 切换到应用用户测试
SET ROLE order_app;

-- 应成功
SELECT * FROM order_schema.products LIMIT 1;
INSERT INTO order_schema.orders (...) VALUES (...);

-- 应失败(权限拒绝)
SELECT * FROM payment_cards; -- 表不存在或权限拒绝

十、高级技巧与陷阱规避

1. 权限回收(REVOKE)

sql 复制代码
-- 回收表权限
REVOKE DELETE ON TABLE logs FROM app_user;

-- 回收角色成员
REVOKE data_writer FROM app_user;

-- 回收默认权限
ALTER DEFAULT PRIVILEGES 
    FOR ROLE db_owner
    IN SCHEMA public
    REVOKE SELECT ON TABLES FROM read_only;

⚠️ 注意REVOKE 不会级联影响已存在的对象!需手动处理。

2. PUBLIC 角色陷阱

  • PUBLIC隐式包含所有角色的特殊角色

  • 默认权限可能通过 PUBLIC 泄露:

    sql 复制代码
    -- 检查危险的 PUBLIC 权限
    SELECT * FROM information_schema.role_table_grants 
    WHERE grantee = 'PUBLIC';
  • 加固建议

    sql 复制代码
    REVOKE ALL ON DATABASE myapp FROM PUBLIC;
    REVOKE ALL ON SCHEMA public FROM PUBLIC;

3. 权限与 Ownership

  • 对象所有者(Owner) 自动拥有所有权限,且不能被 REVOKE

  • 转移所有权:

    sql 复制代码
    ALTER TABLE orders OWNER TO db_owner;

4. RLS(行级安全)补充

当需要动态行过滤(如多租户),配合使用 RLS:

sql 复制代码
-- 启用行级安全
ALTER TABLE tenant_data ENABLE ROW LEVEL SECURITY;

-- 创建策略:用户只能看自己的数据
CREATE POLICY tenant_isolation ON tenant_data
    USING (tenant_id = current_setting('app.current_tenant')::int);

RLS 是权限体系的强力补充,但不替代基础权限

相关推荐
Dontla2 小时前
Database Schema Introduction (structure of data, NoSQL schema)
数据库·nosql
2401_832298102 小时前
存算分离2.0,阿里云EMR Serverless破解数据处理瓶颈
数据库
Maggie_ssss_supp2 小时前
Linux-MySQL日志管理
数据库·mysql
喜欢吃豆2 小时前
PostgreSQL 高维向量存储架构深度解析:架构限制、核心原理与行业解决方案
数据库·人工智能·postgresql·架构·2025博客之星
茁壮成长的露露2 小时前
Percona Backup for MongoDB备份恢复操作
数据库·mongodb
l1t2 小时前
一个在postgresql中运行很快,但是在duckdb中运行很慢的SQL
数据库·sql·postgresql·duckdb
曹牧2 小时前
Oracle:增加十分钟
数据库·oracle
码界奇点2 小时前
深入解析MySQL9主从复制架构详解从原理到实战
数据库·sql·架构·可用性测试
独自归家的兔2 小时前
深度对比:PostgreSQL与MySQL的核心差异及选型指南
数据库·mysql·postgresql