2. 核心概念:变更记录(Change Log)的定义、结构、生命周期;权限模型(RBAC/ABAC)基础

在构建审查意见驱动的审批工作流时,变更记录(Change Log)与权限模型是支撑系统可追溯性与安全性的两大基石。变更记录确保每一次状态转换、字段修改、审批动作都有据可查;权限模型则控制谁可以发起变更、谁可以审批、谁可以查看历史。本节将分别阐述这两个核心概念的定义、结构、生命周期及基础模型。

2.1 变更记录(Change Log)

2.1.1 定义与作用

变更记录是对系统中某个实体(如工单、配置项、文档)在其生命周期内所有修改操作的不可篡改的时序日志。每条记录捕获操作发生的时间、操作者、操作类型、变更前后的数据快照以及关联的上下文信息(如审批意见、触发规则)。

核心作用:
  • 审计追溯:满足合规要求,回答“谁在何时改了什么”。
  • 问题诊断:快速定位导致异常的具体变更。
  • 数据恢复:支持回滚到任意历史版本。
  • 流程分析:统计变更频率、审批耗时、驳回率等指标。

2.1.2 标准数据结构

一个通用的变更记录条目通常包含以下字段。实际工程中可根据业务需求扩展,但核心字段应保持稳定。

字段名 类型 说明 示例
log_id UUID 全局唯一标识 a1b2c3d4-...
entity_type String 变更的实体类型 work_order
entity_id String 实体主键 WO-2024-001
action String 操作类型 UPDATE, SUBMIT, APPROVE
operator String 操作者标识(用户ID/服务账号) user:zhangsan
timestamp DateTime 操作发生时间(UTC) 2024-12-01T10:30:00Z
diff JSON 变更差异(字段级 before/after) {"status":{"old":"draft","new":"pending"}}
snapshot JSON 变更后的完整实体快照(可选) {...}
comment String 操作附言或审批意见 “预算已核实,同意提交。”
source String 变更来源(API/UI/后台任务) web_ui

2.1.3 生命周期

变更记录本身具有明确的生命周期,从创建到归档,确保存储成本与查询性能的平衡。

  1. 创建(Create):当实体发生任何状态变更或字段修改时,系统自动生成一条变更记录。此阶段记录处于活跃(Active)状态,支持实时查询。
  2. 在线存储(Online Storage):活跃记录存储在高速数据库(如 PostgreSQL、MySQL)中,用于近期的审计查询和流程追踪。通常保留 30-90 天。
  3. 归档(Archive):超过在线保留期限的记录被批量迁移至低成本存储(如对象存储 S3、冷存储),并建立索引以便按需检索。归档后记录状态变为已归档(Archived)。
  4. 清理(Purge):根据数据合规策略(如 GDPR、SOX),超过法定保留年限的记录将被彻底删除或匿名化处理。
工程建议:变更记录应设计为仅追加(Append-Only)的数据结构。禁止对已写入的记录进行 UPDATE 或 DELETE 操作,以保证审计链的完整性。如需修正,应生成一条新的“更正”记录。
变更记录生命周期 创建 在线存储 归档 清理 说明: • 创建:自动触发,仅追加写入。 • 在线存储:保留 30-90 天,支持高频查询。 • 归档:迁移至低成本存储,保留索引。 • 清理:合规删除,不可恢复。

2.2 权限模型基础:RBAC 与 ABAC

权限模型决定了“谁”可以对“哪个资源”执行“什么操作”。在审批工作流中,权限模型直接影响变更记录的生成范围与可见性。最常用的两种模型是基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC)。

2.2.1 RBAC(基于角色的访问控制)

RBAC 通过“用户 → 角色 → 权限”的映射关系来管理授权。用户不直接与权限挂钩,而是通过角色间接获得权限。

元素 定义 示例
用户(User) 系统使用者 张三, 李四
角色(Role) 权限的集合 审批员, 管理员, 只读用户
权限(Permission) 对资源的操作许可 work_order:approve, work_order:view
会话(Session) 用户激活的角色集合 张三激活了 审批员 角色
RBAC 优点:模型简单直观,管理成本低,适合角色相对固定的企业场景。
RBAC 局限:当权限粒度需要根据上下文动态调整时(如“仅允许审批金额小于 10 万的工单”),RBAC 会导致角色爆炸。

2.2.2 ABAC(基于属性的访问控制)

ABAC 通过评估一组属性(用户属性、资源属性、环境属性、操作属性)来动态决定是否允许访问。其核心是策略引擎根据预定义的策略规则进行布尔判断。

属性类别 示例属性 策略规则示例
用户属性 部门、职级、安全等级 user.department == "finance"
资源属性 资源类型、创建者、金额 resource.amount < 100000
环境属性 访问时间、IP 地址、设备类型 environment.time >= "09:00" && environment.time <= "18:00"
操作属性 操作类型(读/写/审批) action == "approve"
工程建议:在审批工作流中,推荐采用RBAC + ABAC 混合模型。使用 RBAC 管理基础的角色权限(如“谁可以进入审批页面”),使用 ABAC 处理细粒度的动态策略(如“部门经理只能审批本部门金额小于 50 万的工单”)。这样既保持了模型的可管理性,又获得了灵活性。
RBAC 与 ABAC 模型对比 RBAC 模型 用户 角色 权限 用户 → 角色 → 权限(静态映射) 适合角色固定、权限粒度较粗的场景 ABAC 模型 用户属性 资源属性 环境属性 策略引擎 允许/拒绝 基于属性 + 策略规则(动态评估) 适合权限粒度细、上下文敏感的场景

2.3 变更记录与权限模型的关联

在审批工作流中,变更记录与权限模型并非孤立存在,而是紧密耦合:

  • 权限决定变更记录的生成:只有拥有“编辑”或“提交”权限的用户,其操作才会被记录为变更。无权限的访问尝试应被拒绝,且通常也会记录一条“拒绝访问”的安全日志。
  • 权限决定变更记录的可见性:不同角色的用户查看同一工单的变更历史时,可能看到不同的内容。例如,普通成员只能看到状态变更,而审计员可以看到所有字段的 before/after 差异。
  • 变更记录可作为权限评估的输入:在 ABAC 策略中,可以引用变更记录中的属性(如“该用户在过去 24 小时内是否已经提交过 3 次变更?”)来动态调整审批权限。
常见陷阱:不要将变更记录系统设计为“全量可见”。未经过滤的变更历史可能泄露敏感数据(如审批人的个人意见、未公开的预算数字)。务必在查询变更记录时,根据当前用户的权限模型进行行级或字段级的过滤。

2.4 小结