2. 数据库身份与账号体系

在数据库访问控制中,“谁在访问”是所有权限判断的起点。数据库身份体系并不是简单地在数据库里建几个用户,而是要把人的身份、程序的运行身份、数据库内部的登录身份、以及权限集合这四层关系理清楚。很多权限失控的根因,不是授权给多了,而是身份从一开始就没有分层:应用直连用超级用户、运维共用一个账号、离职人员账号未回收、服务账号密码写死在配置文件里。本节围绕数据库用户、角色、服务账号、应用账号四类对象,讲清它们的定位、创建方式、映射关系与生命周期管理。

四类身份对象的定位

先明确四类对象的边界,避免混用:

  • 数据库用户(User):数据库实例内真实存在的登录主体,拥有独立的认证凭据(密码、证书、外部认证映射等)。它是权限的最终承载者,所有授权最终都落到某个用户或它所属的角色上。
  • 角色(Role):权限的集合容器,本身通常不直接用于登录(部分数据库允许角色登录,但治理上应避免)。角色分为功能角色(按职责打包权限,如只读角色、报表角色)和业务角色(按业务域划分,如订单库读写角色)。
  • 服务账号(Service Account):代表某个系统组件或后台任务运行的身份,如备份程序、数据同步工具、监控采集器。它应具备最小权限、可审计、凭据可轮换。
  • 应用账号(Application Account):代表业务应用连接数据库的身份,通常由应用通过连接池使用。它对应的是“应用”这一逻辑主体,而非某个自然人。

关键原则是:人用个人账号,程序用专用账号,权限通过角色授予,禁止共享账号。个人账号用于运维和排障,可追溯到具体人;应用和服务账号用于程序,凭据集中管理、定期轮换。

创建与映射关系

以常见的 PostgreSQL 为例,创建过程可以这样组织。先建角色,再建用户,最后把用户加入角色:

-- 1. 创建功能角色(不登录)
CREATE ROLE app_readonly NOLOGIN;
GRANT CONNECT ON DATABASE orderdb TO app_readonly;
GRANT USAGE ON SCHEMA public TO app_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_readonly;

-- 2. 创建应用账号并映射到角色
CREATE USER app_order_svc WITH PASSWORD '由密钥管理系统注入';
GRANT app_readonly TO app_order_svc;

-- 3. 创建服务账号(备份专用)
CREATE USER svc_backup WITH PASSWORD '由密钥管理系统注入';
GRANT pg_read_all_data TO svc_backup;

这里体现了“用户—角色—权限”的映射链:权限授予角色,角色授予用户,用户用于登录。应用账号 app_order_svc 不直接持有表级权限,而是通过 app_readonly 角色间接获得,这样调整权限时只需改角色,不必逐个改用户。

在 MySQL 中,用户与角色是分离的,需要显式激活角色:

CREATE ROLE 'app_readonly';
GRANT SELECT ON orderdb.* TO 'app_readonly';
CREATE USER 'app_order_svc'@'10.20.%' IDENTIFIED BY '...';
GRANT 'app_readonly' TO 'app_order_svc'@'10.20.%';
SET DEFAULT ROLE 'app_readonly' TO 'app_order_svc'@'10.20.%';

注意 'app_order_svc'@'10.20.%' 中的主机限制,这是把“应用账号”绑定到特定网段的重要手段,能显著缩小凭据泄露后的可利用范围。

数据库身份映射与生命周期 身份来源 自然人(DBA/开发) 个人账号 · 可追溯 业务应用 应用账号 · 连接池 后台任务/组件 服务账号 · 最小权限 外部身份源 LDAP/OIDC 映射 数据库用户 dba_zhang 个人运维账号 app_order_svc 应用账号 svc_backup 服务账号 ext_ldap_user 外部映射账号 角色与权限 role_dba_admin 运维管理权限集 role_app_readonly SELECT + CONNECT role_backup_operator 备份读取权限 role_report_reader 报表只读权限 生命周期: 申请审批 → 创建映射 → 授权角色 → 定期复核 → 凭据轮换 → 停用回收

生命周期管理的关键动作

身份不是建完就结束,生命周期管理才是治理的核心。可以按以下阶段组织:

申请与审批:任何账号创建都应有工单记录,明确申请人、用途、所需角色、有效期。应用账号和服务账号由系统负责人申请,个人账号由本人申请并经主管审批。

创建与映射:按“先角色后用户”的顺序创建,用户只授予角色,不直接授予对象权限。外部身份源(LDAP/OIDC)映射时,应把外部组映射到数据库角色,而不是逐个映射用户,减少维护量。

凭据管理:应用和服务账号的密码不应写在代码或配置文件中,应通过密钥管理系统(如 Vault、KMS)动态注入,并设置轮换周期。个人账号应启用强密码策略或多因素认证。

定期复核:每季度或每半年对账号和角色成员关系做一次复核,重点检查:长期未登录的账号、权限过大的角色、离职人员账号、共享账号。复核结果应记录并留痕。

停用与回收:人员离职或应用下线时,应在规定时限内锁定或删除账号,并回收其角色成员关系。删除前先确认没有其他依赖,避免影响正常业务。

共享账号是治理中最常见的隐患。一旦多人共用一个账号,审计日志只能定位到账号,无法定位到人,出现问题时无法追责。应坚决避免,用个人账号加角色授权替代。

一个可参考的账号登记表

为了让生命周期管理可执行,建议维护一份账号登记表,字段如下:

字段说明示例
账号名数据库内唯一标识app_order_svc
类型个人/应用/服务应用账号
归属系统所属应用或组件订单服务
绑定角色授予的角色列表role_app_readonly
来源主机允许连接的网段10.20.%
凭据方式密码/证书/外部认证Vault 动态密码
有效期账号或凭据的有效期2025-12-31
复核周期下次复核时间每季度
状态启用/停用/待回收启用

这张表既是运维台账,也是审计依据。每次创建、变更、回收都更新它,就能把身份体系从“建了就不管”变成“全程可追踪”。

一个实用判断:如果某个账号的权限无法用一句话说清“它为什么需要这些权限”,那这个账号的授权大概率过宽,应回到角色设计重新梳理。

总结来看,数据库身份体系的核心是分层与映射:自然人、应用、服务组件对应不同的账号类型,账号通过角色获得权限,角色按职责打包。创建时遵循“先角色后用户、只授角色不授对象”,运行中做好凭据轮换与定期复核,结束时及时停用回收。把这条链路管住,后续的权限治理才有稳定的基础。