系统设计面试:如何设计 C2PA 内容来源验证服务?
题干与适用场景
请设计一个为图片、视频和音频验证 C2PA Content Credentials 的服务。它需要接收大型媒体、保存签名清单、展示编辑历史,并在凭证无效、缺失或签发者不可信时给出可解释结果。
面试官考察点
- 能否正确区分 C2PA Manifest、Claim、签名和资产内容绑定。
- 能否处理大文件、异步验证、缓存、版本化与证书信任。
- 能否明确“有凭证”不等于“内容真实”,并设计降级与隐私边界。
回答前需要澄清的问题
先确认媒体类型和最大大小、上传还是只读验证、延迟目标、验证结果是否需要长期审计、信任根由谁维护,以及是否允许第三方取回 Manifest。还要确认服务要验证签名完整性,还是要对来源机构和编辑动作做业务级背书。
30 秒回答框架
我会把系统拆成上传与对象存储、Manifest 提取、密码学验证、信任目录、结果 API 和审计索引。媒体本体走对象存储,验证任务异步执行并以内容哈希幂等;结果区分签名有效性、链完整性、签发者信任和未知状态。读取端使用版本化缓存,凭证撤销或信任目录变化触发失效。产品层明确 C2PA 证明的是声明的来源与编辑链,不自动证明语义真实性。
分步骤深入解答
- 客户端申请上传 URL,服务记录资产哈希、大小、媒体类型和租户策略;对象存储启用版本与校验。
- 上传完成后投递验证队列。Worker 提取嵌入或远程 Manifest,检查 Claim 与资产哈希绑定、签名、时间戳、父子编辑链和重复凭证。
- 通过信任目录解析签发者证书、撤销状态和用途;把验证依赖的目录版本写入结果,避免同一资产在目录变化后无法解释。
- 结果写入不可变事件表与可查询索引,状态至少包括 valid、invalid、untrusted、missing 和 indeterminate,并保存证据引用而非复制全部媒体。
- API 返回摘要、编辑动作、签发者、验证时间和失败原因;大图预览与 Manifest 下载使用短期授权 URL。
- 对热点资产缓存结果,但键必须包含资产版本、规范版本和信任目录版本;撤销、目录更新或新验证器发布时批量失效。
- 通过限流、病毒扫描、队列重试、死信和租户隔离保护资源;对超大媒体采用分片上传,避免 API 进程持有完整文件。
POST /v1/assets/uploads
POST /v1/assets/{assetId}/verify
GET /v1/assets/{assetId}/provenance
GET /v1/trust-roots/{version}高质量示范回答
我会先定义信任边界:C2PA Manifest 是对来源和编辑声明的可验证签名,不是内容真假分类器。上传服务只保存对象版本和哈希,验证 Worker 异步检查 Manifest 与资产绑定、签名、编辑链、时间戳和证书状态。结果 API 把完整性、签发者信任、凭证缺失和暂时无法判断分开返回,并记录规范与信任目录版本。热点读取用版本化缓存,撤销或目录变化可失效;审计事件不可变,媒体访问使用短期授权。这样既能在高并发下扩展,也不会把“签名有效”误报为“事实真实”。
常见错误
- 把 C2PA 当成 AI 检测器或事实真伪裁判。
- 只验证签名,不验证 Manifest 与当前资产内容的绑定。
- 把证书链有效直接等同于签发机构值得信任。
- 将大文件同步塞进 API 请求,忽略对象存储、队列和幂等。
- 不记录规范、验证器和信任目录版本,导致结果无法复现。
追问及应对
编辑后为什么不能简单保留旧签名?
编辑会改变资产字节;系统应由编辑器追加新的 Manifest,形成父子链,并重新绑定当前资产哈希。旧声明可以保留为历史,但不能冒充当前版本的签名。
凭证缺失是否代表内容是假的?
不代表。缺失只说明服务没有可验证的来源声明;产品应显示 unknown 或 missing,并说明覆盖范围,避免把未参与生态的内容一律判假。
如何应对信任目录更新造成的结果变化?
结果带目录版本和验证时间;保留原始证据,目录更新后异步重验并生成新版本,审计记录说明状态变化原因。
如何防止 Manifest 隐私泄露?
按租户和字段设置可见性,默认只返回必要摘要;敏感字段加密,下载使用短期授权,审计日志记录访问者和用途。