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 权限体系全景图

下图展示了从角色登录到对象访问的完整权限链路。每个箭头代表一个必须被授予的权限步骤,缺少任何一环都将导致访问失败。

PostgreSQL 权限体系全景图 PostgreSQL 权限体系全景图 角色 (Role) 实例 (Instance) 数据库 (Database) 模式 (Schema) 对象 (Object) LOGIN CONNECT USAGE SELECT/INSERT/... 关键原则: • 权限是逐层累积的,必须每一层都通过。 • 角色可以继承其他角色的权限(通过 GRANT)。 • 模式级 USAGE 是访问对象的“门票”。

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 依赖隔离的具体设计模式,利用角色继承和模式隔离构建安全的测试沙箱。