代表性面试主题

系统设计面试:如何设计防篡改审计日志服务?

系统设计困难
OfferCC 编辑团队发布 更新

题干

为安全与合规调查设计多租户审计日志服务。请说明事件模型、接入持久性、防篡改证据、访问控制、留存、查询隔离、导出和故障处理。

题目与范围

设计多租户审计日志服务,记录登录、权限变更、数据访问和配置更新等安全与合规动作。调查人员需要可检索历史和可验证导出,同时日志故障不能让普通业务悄悄丢失关键证据。

先定义完整性承诺。AWS CloudTrail 描述了可检索的不可变事件历史,OpenTelemetry 提供结构化日志模型;两者都不能证明事件在产生前就一定真实。答案要说清系统能证明什么。

面试官考察什么

面试官考察持久接入、追加写入、完整性验证、租户隔离、留存策略和运维权衡。好的回答会把审计证据与普通调试日志分开,并解释过载时如何避免安全事件丢失或被修改。

作答前需要确认的问题

  • 哪些动作必须记录,事件每秒量和突发量是多少?
  • 需要的是可发现篡改、抗篡改,还是外部可证明?
  • 审计事件无法接收时,业务请求必须失败吗?
  • 每个租户保留多久,法律保全是否覆盖删除?
  • 谁能查询、导出或验证其他租户数据?
  • 调查人员需要哪些查询维度和导出格式?

30 秒回答框架

“我会提供区域接入 API 和本地持久缓冲,让业务请求不依赖搜索索引。每条事件包含租户、操作者、动作、目标、请求关联、事件时间、接收时间、Schema 版本和来源。按租户与时间分区写入追加日志并跨故障域复制,再通过哈希链或签名段清单检测后续修改。近期事件进入热索引,旧段进入不可变留存。查询和导出按租户授权、留存与法律保全执行,并输出可验证清单。监控接收与丢弃、延迟、完整性检查和导出完成率。”

分步深入

第一步:定义事件契约

要求事件 ID、租户 ID、操作者和认证上下文、动作、目标、结果、来源服务、请求 ID、事件时间、接收时间、Schema 版本和必要属性。不要把密钥和无关载荷写入记录,使用引用或脱敏摘要。

第二步:分离接收与索引

只有事件进入持久缓冲或复制日志后才返回成功。消费者异步构建搜索索引和导出。这样搜索集群故障不会静默删除证据,也不会让每个业务请求等待索引完成。

第三步:让完整性可验证

规范化事件,用前一事件或段根计算哈希,并周期性签名或把清单锚定到独立信任域。保存序列缺口和验证结果。哈希链能发现接收后的修改,但不能证明上游服务发出的内容本身真实。

text
append(event):
    canonical = canonicalize(event)
    record.hash = H(previous_hash || canonical)
    durable_log.append(record)
    return accepted(record.event_id, record.hash)

第四步:分区与复制

按租户和时间分区,用哈希或租户键分散热点租户。按持久性目标跨故障域复制后再确认。保留租户内或聚合内顺序即可,除非确有必要,不要承诺全局顺序。

第五步:构建热检索与冷留存

近期事件进入调查索引,旧段压缩到不可变对象存储。索引必须能从日志重建。留存任务遵守租户策略和法律保全;删除可以留下可审计的策略记录,但不保留受保护载荷。

第六步:执行访问与导出控制

每次查询按租户、角色、用途和时间范围授权。查询和导出本身也记录为审计事件。导出生成签名清单,包含过滤条件、事件数、段哈希和时间戳,接收方可验证完整性。

第七步:定义故障和过载行为

选择有界本地缓冲、背压和关键事件策略。非关键遥测可以采样或延迟;安全事件则拒绝原始变更,或路由到隔离应急通道。只有易失内存暂存时,不能向调用方报告已接收。

第八步:运营信任边界

监控接入延迟、持久确认耗时、消费者延迟、拒绝事件、序列缺口、哈希失败、索引新鲜度、导出耗时和留存错误。限制密钥访问、轮换签名密钥、测试恢复和验证,并记录“审计系统的审计”。

高质量示范回答

“我会把审计日志作为独立证据系统。业务服务生成带事件 ID、租户、操作者、认证上下文、动作、目标、结果、请求 ID 和 Schema 版本的规范事件;事件进入跨故障域复制的持久日志后才确认接收,搜索索引和导出由异步消费者构建,索引丢失时可从证据日志重建。

证据日志按租户和时间分段,保存前序哈希并周期性签名或锚定。查询按租户、角色、用途和时间范围授权,查询与导出本身也写入审计;导出包含过滤条件、事件数、段哈希与签名清单。安全事件在接入故障时进入有界应急通道或阻止原始高风险操作,不能只放在进程内存后就报告成功。运维上监控接入延迟、序列缺口、哈希失败、索引新鲜度、拒绝事件和留存错误,并定期演练索引重建、密钥轮换和热点租户隔离。这个服务证明记录在接收后是否保持完整,上游事件真实性仍依赖身份、授权和业务事务。”

常见错误

  • 在事件持久化前返回成功,进程退出后留下无声缺口。
  • 把可修改的普通数据库表或调试日志直接当作审计证据。
  • 让查询索引成为唯一副本,索引损坏后无法重建。
  • 忽略查询、导出、保留策略变更和密钥轮换本身也要审计。
  • 声称哈希链可以证明上游事件内容真实。

追问及应对

搜索索引全部丢失怎么办?

保持证据日志继续接收,从不可变分段重建索引,并用事件数、序号和签名清单验证重建范围。

审计接入不可用时,业务是否继续?

按事件关键性处理。普通低风险动作可以进入有界持久缓冲;无法可靠记录的高风险安全动作应拒绝或进入隔离应急通道,不能静默放行。

如何避免热点租户拖垮其他租户?

按租户和时间分区,设置接入、查询和导出配额,隔离消费者资源;压测时同时验证其他租户的持久性与查询服务等级目标。

如何处理隐私删除与审计留存冲突?

按法律保全和租户策略区分字段,优先保存脱敏摘要或受控引用;执行删除时同步处理索引、对象段与备份,并保留可验证的策略执行记录。

公开来源

同类题目

相关面试工具

用 Solve 整理系统设计回答

从澄清需求开始,展开规模、架构、组件选择和取舍。

查看工具