代表性面试主题

后端面试题:如何用 OCI Referrers 关联镜像签名与 SBOM?

后端困难
Offer.cc 编辑团队发布 更新

题干

请设计一个后端服务,查询容器镜像关联的签名、SBOM 与扫描报告,并说明 OCI Referrers 的兼容与安全边界。

题干与适用场景

你的平台在 OCI registry 中保存镜像,发布流程还要关联签名、SBOM 和漏洞扫描结果。请设计一个查询与验证服务:输入仓库名和镜像 digest,返回关联制品,支持按 artifactType 过滤,兼容尚未实现 Referrers API 的旧 registry,并在部署前阻止未验证的镜像。目标岗位是后端或平台工程师;题目聚焦 registry 协议和服务边界,不要求实现具体云厂商 SDK。

面试官考察点

强回答会把镜像 digest 当作不可变 subject,而不是把 tag 当作身份;理解 subject 建立关联、artifactType 描述用途、Referrers API 返回 OCI Index。还应覆盖旧 registry 的 fallback tag、分页与缓存一致性,以及“发现关联制品”和“验证签名”是不同步骤。只说“查镜像标签”或把 SBOM 当作可信证明,说明安全模型不完整。

回答前需要澄清的问题

  1. 输入是 tag 还是 digest?若是 tag,先解析到 digest,并固定后续验证对象。
  2. 是否必须兼容返回 404 的旧 registry?若必须,实现 OCI fallback tag,并处理并发更新。
  3. 返回结果是否用于准入阻断?若是,验证签名、发布者身份和 digest 必须在信任边界内完成。
  4. 关联制品是否可能超过单页大小?若是,透传 opaque nextToken,不能自行解释或拼接 token。

30 秒回答框架

“我先把 tag 解析成 digest,所有关联都以 digest 为 subject。优先调用 /v2/{name}/referrers/{digest},按 artifactType 过滤签名、SBOM 或报告;旧 registry 返回 404 时读取 digest 派生的 fallback tag。发现制品后再验证签名与发布者身份,最后按策略决定是否允许部署。列表接口要分页、缓存短 TTL,并在缓存键中包含 digest 与过滤条件。”

分步骤深入解答

OCI 1.1 用 manifest 的 subject 指向被关联的 manifest,artifactType 描述关联制品。Referrers API 返回一个 OCI Index,索引项包含 digest、媒体类型和制品类型;查询路径是:

text
GET /v2/{name}/referrers/{subject-digest}?artifactType={type}

服务应先拒绝没有 digest 的验证请求。tag 只是可变指针,不能作为签名验证主键。解析 tag 后记录解析时的 digest,并把该 digest 传给查询、缓存与部署准入。

遇到支持 API 的 registry,200 空 Index 表示“没有关联制品”;遇到旧实现的 404,客户端读取将 sha256: 替换为 sha256- 的 fallback tag。fallback tag 由客户端维护,追加新 referrer 时存在读改写竞争;因此写入端要用 registry 支持的并发控制或重试策略,读取端不能把 fallback 当成强一致事实。

发现签名、SBOM 和扫描报告后分三步处理:按 artifactType 和发布策略筛选;拉取关联 manifest 与内容;验证签名是否覆盖目标 digest、发布者身份是否在信任根内、制品是否仍为允许状态。Microsoft 的指导把完整性、真实性和消费前阻断分开,说明“能查到签名”不等于“镜像可信”。

API 结果可能分页。服务应原样保存并透传 opaque nextToken,限制每页大小,缓存键使用 registry、仓库、subject digest、artifactType 和权限上下文。digest 是不可变的,列表缓存可以短期复用;签名撤销或状态变化仍需要明确 TTL 与重新验证策略。对安全准入路径,缓存只能加速发现,不能跳过最终验证。

高质量示范回答

我会把 digest 作为唯一 subject。客户端先把 tag 解析成 digest,再调用 OCI Referrers API 查询关联制品;artifactType 用于区分签名、SBOM 和扫描报告。支持 API 的 registry 返回 OCI Index,旧 registry 返回 404 时走 digest 派生的 fallback tag,并对更新竞争做重试。查询结果只负责发现,准入服务还要验证签名覆盖的 digest、发布者身份和信任根,随后按策略阻断未验证镜像。接口支持 opaque token 分页,缓存键包含 digest 与过滤条件;安全路径每次部署仍重新验证,避免把缓存当成信任结论。

常见错误

  • 错误表现 → 用 tag 作为签名主键 → 失败原因是 tag 可被重新指向 → 修正方法是先解析并固定 digest。
  • 错误表现 → 404 一律当成没有关联制品 → 失败原因是旧 registry 可能尚未实现 Referrers API → 修正方法是读取规范定义的 fallback tag。
  • 错误表现 → 查询到签名就允许部署 → 失败原因是未验证发布者身份、签名覆盖范围或镜像 digest → 修正方法是把发现与密码学验证分成两个阶段。
  • 错误表现 → 自己解析或拼接 nextToken → 失败原因是 token 是服务端不透明游标 → 修正方法是原样透传,并限制页大小和请求超时。

追问及应对

追问一:fallback tag 更新时两个构建同时写入怎么办?

把 fallback Index 更新视为读改写事务,使用 registry 的条件写、乐观重试或单写入队列。写入失败时重新读取最新 Index,再合并新 descriptor;不能覆盖另一个构建刚写入的关联。

追问二:签名存在但 SBOM 指向旧 digest 怎么处理?

以当前 subject digest 做一致性检查。签名、SBOM 和报告都必须明确关联同一个 digest;发现任一关联对象指向旧 digest,就标记为不适用并阻断准入,不能仅按镜像 tag 名称匹配。

追问三:registry 返回大量 referrers,如何避免查询拖垮服务?

限制 maxResults,透传 opaque token,并按 digest 和 artifactType 做短 TTL 缓存。对准入只查询策略需要的类型;后台索引可异步预热,但最终部署仍需验证返回的 manifest digest 与信任状态。

公开来源

同类题目