题干与适用场景
你的平台在 OCI registry 中保存镜像,发布流程还要关联签名、SBOM 和漏洞扫描结果。请设计一个查询与验证服务:输入仓库名和镜像 digest,返回关联制品,支持按 artifactType 过滤,兼容尚未实现 Referrers API 的旧 registry,并在部署前阻止未验证的镜像。目标岗位是后端或平台工程师;题目聚焦 registry 协议和服务边界,不要求实现具体云厂商 SDK。
面试官考察点
强回答会把镜像 digest 当作不可变 subject,而不是把 tag 当作身份;理解 subject 建立关联、artifactType 描述用途、Referrers API 返回 OCI Index。还应覆盖旧 registry 的 fallback tag、分页与缓存一致性,以及“发现关联制品”和“验证签名”是不同步骤。只说“查镜像标签”或把 SBOM 当作可信证明,说明安全模型不完整。
回答前需要澄清的问题
- 输入是 tag 还是 digest?若是 tag,先解析到 digest,并固定后续验证对象。
- 是否必须兼容返回 404 的旧 registry?若必须,实现 OCI fallback tag,并处理并发更新。
- 返回结果是否用于准入阻断?若是,验证签名、发布者身份和 digest 必须在信任边界内完成。
- 关联制品是否可能超过单页大小?若是,透传 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、媒体类型和制品类型;查询路径是:
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 与信任状态。