← 中文资源

简体中文版本

添加只追加审计日志表

在业务变更的同一事务中写入只追加审计表,记录谁在何时从何处修改了哪条记录。

阅读英文原文

审计变更,而不只是请求

HTTP 访问日志记录请求发生过;审计事件记录状态转换:操作者、动作、实体、变更前后和 request id。二者互补。访问日志帮助排查流量和错误,审计事件回答问责问题,并且必须防篡改。

审计行要与业务变更在同一事务中写入。业务更新回滚,审计事件也必须回滚;审计插入失败,业务变更应失败,而不能在没有轨迹的情况下提交。这是有意的可用性权衡:受监管的变更不允许无审计进行。

BEGIN;
UPDATE customers SET billing_address = $1 WHERE id = $2;
INSERT INTO audit_events (actor_id, action, entity_type, entity_id, after, request_id)
VALUES ($3, 'customer.billing_address.update', 'customer', $2, $4, $5);
COMMIT;

保护历史

应用代码只能插入和读取审计事件,不能更新或删除。只授予必要权限,并为归档保留独立角色。加密备份,并让审计表的访问控制比业务表更严格。审计轨迹涉及法律敏感性时,考虑哈希链或一次写入的外部存储。

设计负载

默认只存回答问题所需的字段,而不是整行。完整快照方便,但增加个人数据暴露并使保留更困难。敏感信息脱敏,使用稳定实体标识,并包含 request id,以便与日志和 trace 关联而无需保存原始请求头。

验证事务边界

预期结果:成功更新恰好有一条包含操作者、实体 id 和 request id 的审计行,而故意失败的更新没有审计行。通过在审计插入后强制业务更新失败并查询表来确认,计数必须不变。同时确认应用角色可以插入和查询,但在更新或删除时收到权限错误。