2. PostgreSQL 安全模型基础:用户、角色、模式(Schema)与权限体系概览
在构建 Mock 依赖隔离环境之前,必须理解 PostgreSQL 的安全模型。与许多数据库不同,PostgreSQL 将“用户”和“角色”统一管理,并通过“模式(Schema)”实现逻辑隔离。本章将系统梳理这四层安全体系,为后续的权限最小化设计奠定基础。
2.1 角色与用户:统一的主体模型
PostgreSQL 使用 角色 (Role) 作为访问控制的核心主体。角色可以是一个数据库用户、一组用户,或两者兼具。角色可以拥有数据库对象(如表、视图),也可以将权限授予其他角色。
| 概念 | 说明 | 创建方式 |
|---|---|---|
| 登录角色 (Login Role) | 可以连接数据库,相当于传统意义上的“用户”。 | CREATE ROLE name LOGIN PASSWORD '...'; |
| 组角色 (Group Role) | 通常不登录,用于集中管理权限,可包含其他角色。 | CREATE ROLE name NOLOGIN; |
| 用户 (User) | 是 LOGIN 属性的角色别名,二者本质相同。 |
CREATE USER name PASSWORD '...'; |
最佳实践:在 Mock 隔离场景中,建议为每个测试套件或每个开发者创建独立的登录角色,并通过组角色统一授予公共权限(如连接数据库、使用公共模式),实现权限的集中管理与最小化分配。
2.2 模式 (Schema):逻辑隔离的容器
模式是 PostgreSQL 实现逻辑隔离的核心机制。一个数据库可以包含多个模式,每个模式独立管理其内部的表、视图、函数等对象。通过模式,可以在同一个数据库中为不同应用、不同测试环境创建独立的命名空间。
- 默认模式:每个数据库自动包含
public模式。 - 搜索路径:通过
search_path控制对象查找顺序,典型设置为"$user", public。 - 隔离效果:不同模式下的同名表互不干扰,这是 Mock 依赖隔离的物理基础。
-- 为测试环境创建独立模式
CREATE SCHEMA IF NOT EXISTS mock_test_schema AUTHORIZATION mock_user;
-- 设置搜索路径,优先使用测试模式
SET search_path TO mock_test_schema, public;
2.3 权限体系:从粗粒度到细粒度
PostgreSQL 的权限控制分为三个层级:实例级、数据库级和对象级。理解这些层级是设计安全策略的前提。
| 层级 | 权限示例 | 控制粒度 | 典型场景 |
|---|---|---|---|
| 实例级 | LOGIN, SUPERUSER, CREATEDB |
粗粒度 | 控制谁能连接服务器、创建数据库 |
| 数据库级 | CONNECT, CREATE, TEMP |
中粒度 | 控制谁能访问特定数据库、在其中创建模式 |
| 模式级 | USAGE, CREATE |
中粒度 | 控制谁能使用模式中的对象、在模式中创建新对象 |
| 对象级 | SELECT, INSERT, UPDATE, DELETE, EXECUTE |
细粒度 | 控制对具体表、视图、函数的数据操作 |
常见误区:仅授予
CONNECT 权限到数据库,并不代表用户可以访问其中的表。用户还需要获得对应模式的 USAGE 权限以及表上的 SELECT/INSERT 等对象级权限。权限是逐层叠加的,缺一不可。
2.4 权限体系全景图
下图展示了从角色登录到对象访问的完整权限链路。每个箭头代表一个必须被授予的权限步骤,缺少任何一环都将导致访问失败。
2.5 权限管理核心命令
掌握以下命令是实施安全策略的基础。在 Mock 隔离场景中,GRANT 和 REVOKE 是最常用的操作。
-- 1. 创建组角色并授予权限
CREATE ROLE mock_readonly NOLOGIN;
GRANT CONNECT ON DATABASE testdb TO mock_readonly;
GRANT USAGE ON SCHEMA mock_schema TO mock_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA mock_schema TO mock_readonly;
-- 2. 创建登录角色并加入组角色
CREATE ROLE dev_user LOGIN PASSWORD 'secure_pass';
GRANT mock_readonly TO dev_user;
-- 3. 撤销权限(最小化原则)
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON SCHEMA mock_schema FROM PUBLIC;
Mock 隔离要点:在后续章节中,我们将利用模式级
USAGE 和对象级 SELECT/INSERT 权限,为每个 Mock 测试套件创建独立的模式,并仅授予该套件所需的最小权限集。这既能防止测试数据污染,又能避免测试代码意外修改生产对象。
2.6 默认权限与 PUBLIC 角色
PostgreSQL 默认授予 PUBLIC 角色一些权限,这在生产环境中可能存在安全隐患。在 Mock 隔离设计中,必须显式收紧默认权限。
| 默认权限 | 影响 | Mock 环境建议 |
|---|---|---|
PUBLIC 对 public 模式有 CREATE 权限 |
任何用户都能在 public 模式中创建对象 |
必须撤销:REVOKE CREATE ON SCHEMA public FROM PUBLIC; |
PUBLIC 能连接数据库 |
所有用户默认可以连接 | 根据需求撤销或保留 |
| 新创建对象的默认权限 | 对象所有者拥有全部权限,PUBLIC 无权限 |
通常安全,但需注意函数执行权限 |
通过以上基础,我们已经建立了 PostgreSQL 安全模型的完整认知。下一层将深入 Mock 依赖隔离的具体设计模式,利用角色继承和模式隔离构建安全的测试沙箱。