3090 字
约 10 分钟
14
S16-A24 · 审计需求的技术转译:业务方说要审计,技术要落成什么
2024-12-31
2026-11-09

业务方说"这个操作必须留痕",技术团队当天加了一张日志表。半年后审计进场,第一个问题是:"上个月 12 号,谁把这条商品的价格从 199 改成了 89?"日志表里有时间、有 SQL 片段、有请求路径,唯独没有操作人,也没有旧值。于是"留痕"做完了,"审计"没做。

这不是执行不到位,而是转译缺失:业务方给的是一个词,技术团队接到的是一张表,中间那一步没人做。


1. "审计"这个词,在业务方口中通常是四件事

四件事的提问方式不同,实现机制不同,成本差一到两个数量级。混在一起谈,必然做成最贵又最不顶用的那一种。

那件事 将来谁会这样问 实现机制 成本量级
谁做的 "这笔操作是谁提交的?" 身份贯穿:请求上下文带操作者,落到记录里 低,主要是链路改造成本
能不能查到 "上个月那批异常操作,列出来。" 可检索的结构化记录 + 索引 + 查询入口 中,写入量决定存储与查询成本
能不能证明没被改 "你怎么保证这份记录不是事后补的?" 追加写、哈希链、外部锚定、独立存储 高,涉及流程与留存制度
能不能还原当时状态 "改之前这条数据长什么样?" 前后值快照或版本表,而非仅变更动作 高,写入放大约 2 倍以上,且要定义快照粒度
// 四件事对应的实现,成本从低到高
谁做的        → 请求上下文里带身份,落到记录
能不能查到    → 结构化字段 + 索引 + 查询入口
能不能证明没被改 → 只追加写 / 哈希链 / 独立存储
能不能还原当时状态 → 前后值或版本表(写入放大约 2 倍)

判断清单:

  1. 谁会来问?审计部门、外部监管、法务、内部风控,四者的口径不同。
  2. 问的是事实还是证明力?只有后者需要防篡改机制。
  3. 需要还原的是单条记录还是整批状态?后者要考虑快照与重放,成本陡增。
  4. 留存期是谁定的?来自审计要求,还是来自存储预算的倒推?
  5. 记录是否需要对外出示?需要时即可举证性要求,属于合规范畴。
  6. 现有采集点能否拿到操作者?拿不到时,其余字段再全也没用。

一句话判据:"留痕"回答的是有没有写下来,"审计"回答的是能不能据此下结论。


2. 转译的第一步:把"要审计"拆成问题清单

在写任何表结构之前,先产出一份问题清单:列出将来可能被问的具体问句。这份清单是最小可交付物,也是唯一能验证"做够了没有"的东西。

// 问题清单:每条都要能映射到字段与采集点,映射不上的先标缺口
questions:
  - q: "上个月 12 号谁改了商品 X 的价格?"
    needs: [operator, occurred_at, object_id, before, after]
    source: app-audit
  - q: "这批下架操作里,有没有人用了别人的账号?"
    needs: [operator, session_id, object_id, action]
    source: app-audit
  - q: "这条记录从写入到现在有没有被改过?"
    needs: [record_hash, prev_hash, storage]
    source: append-only-log
  - q: "退款审批当时看到的订单金额是多少?"
    needs: [snapshot_ref, occurred_at]
    source: version-table

判断清单:

  1. 每个问题是否有明确的提问人角色?没有角色的问题,多半是想象出来的。
  2. 每个问题是否能映射到具体字段?映射不上的,就是当前方案的缺口。
  3. 问题是否可以回答"查不到"?有些问题本来就该答"我们没留",提前说清比事后解释便宜。
  4. 问题清单是否被业务方签字确认?没确认的清单,审计时会被重新解释一遍。
  5. 清单是否随业务变化更新?口径变更次数本身是一项度量。

问题清单的价值不在于穷尽,而在于让"够不够"变成可讨论的事:业务方会说"还要能查金额",技术方会说"那需要快照",成本与必要性在这一刻才第一次对齐。


3. 五个必答字段与各自的缺失后果

字段 缺失后果 采集难点
操作者 记录只能证明"发生过",不能证明"谁做的",审计价值归零 异步任务、消息消费、内部调用没有天然身份
时间 无法定位窗口,也无法排序与去重 多时钟源、时区、精度不一致
对象 无法回答"这条记录关于谁",只能全表人工比对 对象标识在级联操作中会变(合并、拆分)
动作 无法区分查询与修改,也无法归类 动作词表不统一,"更新"与"修改"混用
前后值 能证明改过,不能证明改成了什么,也无法回滚 大字段、关联表、批量操作的成本
// 一条能回答审计问题的记录:字段齐备只是下限
{
  "operator": { "type": "user", "id": "u_8821", "via": "web" },
  "occurred_at": "2026-03-12T10:22:31.482+08:00",
  "object": { "type": "product", "id": "p_3391" },
  "action": "price.update",
  "before": { "price": 19900, "currency": "CNY" },
  "after":  { "price": 8900,  "currency": "CNY" },
  "traceId": "b71e-4c02",
  "prevHash": "9ac1...", "hash": "3f7d..."
}

判断清单:

  1. 操作者是否区分了人、系统、定时任务?三类混在一个字段里,查询时无法过滤。
  2. 时间是否带时区且精度足够?秒级精度在批量操作里无法排序。
  3. 对象标识是否稳定?会变的标识需要在记录里同时写旧标识。
  4. 动作是否有受控词表?自由文本会在半年后变成几十种同义写法。
  5. 前后值是否只记变化的字段?全量快照会让写入量翻倍,但不是所有场景都该省。

4. 采集点、可读性与保留期

采集点 能拿到什么 盲区
应用层 操作者、业务语义、前后值 绕过应用的直连改库完全没有记录
数据库层(触发器、binlog、审计插件) 每一行的真实变更,无法绕过 查不到是谁做的,只有连接账号;批量与关联变更难以还原业务语义
网关层 请求方、路径、时间、响应码 只知道"调了这个接口",不知道改了哪条数据

采集点选错,最典型的表现就是"数据库层的操作查不到是谁"。数据库审计表里有账号 app_rw,几万个请求共用它,等于没有操作者。反过来,只做应用层,一次手工 UPDATE 就能让记录与事实脱节。

判断清单:

  1. 是否存在绕过应用的写路径(运维脚本、数据修复、DBA 直连)?存在就必须补数据库层记录。
  2. 应用层记录是否带请求上下文?拿不到会话与身份时,等于只记了动作。
  3. 两层记录是否能对齐?用 traceId 或业务键串起来,否则对账时互相矛盾。
  4. 记录是否追加写?可更新可删除的表,无法回答"有没有被改过"。
  5. 记录是否与业务库同库?同库时,一次误删会同时毁掉数据与证据。

可读性是被低估的一半。原始日志给审计者看,等于没给:他要的是"谁在什么时候把什么改成了什么",而不是一行带转义符的 JSON。可读性有三层:字段命名可读、动作词表可读、能按对象与时间直接查出变更轨迹。

─── 按对象查轨迹:审计者要的是这个,不是原始日志
SELECT occurred_at, operator_id, action, before_json, after_json
FROM audit_record
WHERE object_type = 'product' AND object_id = 'p_3391'
  AND occurred_at >= '2026-03-01'
ORDER BY occurred_at;
─── 只追加写:应用账号没有 UPDATE / DELETE 权限,才能回答"有没有被改过"
GRANT INSERT, SELECT ON audit_record TO 'app_audit'@'%';
─── 哈希链:hash = H(prev_hash || 本条规范化字段),链断即被改

审计需求与合规需求不是一回事:前者是自查(自己想知道发生了什么),后者是对外举证(要能向第三方证明)。举证要求通常包含独立存储、不可否认、留存年限与访问记录,成本高出一个台阶。把自查做成举证,是浪费;把举证当自查做,是缺口。

度量 说明
字段完整率 记录中五个必答字段齐备的比例
可回答的问题比例 问题清单中能实际回答的条目占比
取证耗时 从接到提问到给出结论的时间
审计口径变更次数 问题清单被重新解释的次数

5. 排错:五种"做了审计但答不上来"

现象 原因 处理
审计说"查不到谁改的" 采集点在数据库层,只有共用连接账号 补应用层身份贯穿,或用会话级标记
记录里有操作,业务上说不通 动作词表不统一,多条记录表达同一件事 建受控词表,历史数据做一次归一
记录被质疑"可以事后补" 记录表可更新,无追加写约束 改为只追加,加哈希链或独立存储
需要还原旧值却只有变更动作 只记了"改过",没记"改成什么" 加前后值或版本表,明确快照粒度
审计期发现保留期已过 保留期按存储成本设定 以审计要求为准重定,并留到期流程

6. 边界:什么情况不必做完整转译

场景 可压缩为 理由
内部小工具,操作人只有几名 一份问题清单 + 一张带五字段的表 人少,身份可从上下文直接推断
无对外承诺、无监管要求 只做"谁做的"与"能不能查到" 证明力与快照成本收不回来
数据本身可重放(事件溯源已存在) 复用事件流,不另建审计表 重复建设只会制造第二份真相
低频关键操作 单条记录 + 人工复核 频率低,人工成本低于系统成本

转译的终点不是"建一张表",而是一张业务方能读懂的问题清单,加一份能回答其中大部分问题的记录结构。答不了的那几条写明,比假装都能答更安全。


自测

  1. "留痕"与"审计"的差别,用一句话怎么表述?
  2. 四类审计诉求里,哪两类的实现成本明显更高,为什么?
  3. 五个必答字段中,缺失哪一个会让记录整体失去审计价值?
  4. 数据库层采集的最大盲区是什么,如何补救?
  5. 为什么"审计"与"合规"不能按同一套标准建设?
  6. 什么条件下可以把完整转译压缩成"问题清单加一张表"?
S16-A24 · 审计需求的技术转译:业务方说要审计,技术要落成什么
https://www.clxhxhhr.top/posts/6374/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。