Docker Content Trust 已经不再适合被当成“有点老、但先放着也无妨”的底层管线。Docker 开始把 Docker Official Images 从 DCT 路径上撤下来,Azure 也给自己的 DCT 支持写明了退出时间表之后,镜像签名这件事就从后台卫生项变成了有明确失败面的迁移工程。[1][2][3]

这篇给平台团队和安全团队,适用场景是:你们的环境里已经有一部分镜像签名习惯、旧验证逻辑或发布流程,现在需要迁到新的 OCI 签名路径,同时又不想把切换过程做成 CI 中断,或者做成 admission policy(准入策略)上的混乱现场。

图像说明:封面图是专门为这篇文章制作的分析示意图。它要帮助读者把真正的问题看清:先把 DCT 视作 tag 时代的旧信任习惯,再决定生产里的默认验证权威究竟落在工作负载身份,还是落在证书与策略。

这次迁移真正要完成的是契约切换

迁移里最容易踩的坑,是想找一个“新的 DCT”,然后把旧操作习惯原封不动带过去。

这样做通常会出现三件事:团队继续把镜像信任理解成 tag 层面的属性,继续把长期私钥塞在并不适合的地方,再把验证策略改造推迟到“新工具先装上再说”的阶段。债务看起来被迁移了,实际只是换了外壳。

Docker 自己的 DCT 文档已经把这条老路径的问题写得很清楚。DCT 的信任绑定在镜像引用里的 tag,不在不可变的 digest 上,而且同一个 tag 在不同时间点还或许出现“有签名内容”和“无签名内容”并存的理解错位。[1] 它还依赖 Notary server、delegation key、timestamp key,以及一个 Docker 明确警告过“丢失后无法恢复”的离线 root key(根密钥)。[1]

在 DCT 还是公共注册表默认信任通道的年代,这种设计还能运转;放到 2026 年,它已经和今天的实际工程环境有明显错位。现在的主流做法更偏向 digest 级验证、OCI 原生签名存储、透明日志(transparency log)、云 KMS 插件,以及基于工作负载身份(workload identity)的 CI 签名。

为什么 DCT 现在更像验证债务,而不再像验证能力

有三条事实足够说明问题。

第一,Docker 已经进入退场阶段。Docker 公开写明,上游 Notary v1 代码库已经不再积极维护,Docker Hub 上使用 DCT 的拉取占比已经低于 0.05%,而 Docker Official Images 从 2025 年 8 月 8 日 开始还会逐步碰到证书过期问题。[2] 如果你的拉取路径还依赖 DOCKER_CONTENT_TRUST=1,Docker 给出的现实建议已经接近“把它拿掉”。[2]

第二,Azure Container Registry 给出了完整时间表。微软说明,DCT 的弃用从 2025 年 3 月 31 日 开始,ACR 会在 2028 年 3 月 31 日 彻底移除 DCT。[3] 这已经是一个开始倒计时的迁移窗口。

第三,DCT 的运维形状和现代自动化并不匹配。Docker 文档里的 DCT 工作流仍然围绕本地 trust store(信任存储)、delegation key 导入,以及通过 Notary 初始化仓库来组织。[1] 这一套和今天的短时凭证签名、工作负载身份签名、云证书管理,已经是两种不同工程范式。

所以迁移目标不该理解成“把 docker trust sign 换成另一个命令”,真正要完成的是:把团队从 tag 时代的信任思路,迁到 digest 时代的验证契约。

分叉点在哪里:选身份优先的 Sigstore,还是证书优先的 Notation

大多数团队未必要给所有镜像找一条完全一致的通路,但每个环境仍然该有一条主路径。否则审核成本会不断上升。

可以先用一条很快的分流判断,把选择问题压实:

什么时候该把 Sigstore 设成主路径

Sigstore 的默认路径是 keyless signing(无长期密钥签名)。它的文档解释得很直接:Fulcio 会给临时生成的签名密钥签发 短时证书,把这个密钥与 OpenID Connect(开放身份连接,OIDC)身份绑定起来,再由 Rekor 把签名事件写入透明日志。[4] 这样一来,团队关注的重心就从“长期私钥放在哪、谁有机会摸到它”,转成“是哪一个工作负载身份在什么 issuer(签发方)下面签了这个制品、事件有没有被记录”。

这条路更适合下面几种环境:

Sigstore 还有一个实际优势:镜像之外的 blob、attestation、SBOM 等工件,也能放进同一套“身份 + 透明日志”的理解框架里。

什么时候该把 Notation 设成主路径

Notation 所处的位置不太一样。Notation 项目把自己定义成面向 OCI 注册表生态的标准签名工具,而微软在 ACR 的迁移文档里,也把 Notary Project 视作替代 DCT 的便携路径,用于注册表、CI 系统和 AKS 准入控制里的签名与验证。[3][6][7]

这条路更适合下面几种组织条件:

微软的教程还强调了两个很关键的操作点:签名时应尽量使用 digest,不要把可变 tag 当成信任锚点;timestamping(时间戳)与 trust policy(信任策略)应该在设计一开始就进入验证路径,而并非后面再补。[7]

迁移过程中尽量不要做的两件事

1)不要一边保留 DCT 拉取路径,一边把验证改造无限后延

既然 Docker Official Image 在 DCT 路径上已经会受到证书过期影响,那么把 DOCKER_CONTENT_TRUST=1 继续散落在旧 CI 作业里,只是在延长一块已知脆弱面。[2] 更合理的动作,是先把 DCT 从关键拉取路径上拿掉,再有意识地把验证能力重建到新路径上。

2)不要把基于 tag 的信任习惯原样搬到新系统

DCT 绑定 tag,确实让人容易用人类可读标签来理解“哪个版本可信”。现代签名系统更适合把 tag 留给发布协作,把 digest 留给信任判断。微软的 Notation 教程明确建议用 digest 识别被签名镜像,因为 tag 可变、也或许被覆盖。[7] Cosign 的验证流程同样默认会检查签名 payload 里绑定的 digest。[5]

如果你的切换方案里还写着“验证 stable 这个 tag 就可以”,那这次迁移还没有真正完成。

一条可强制执行的四阶段切换路径

阶段一:把旧信任面全部盘出来

先找出 DCT 还活在哪些地方:

这一步更像依赖图盘点,不只是 grep 命令。风险最大的 DCT 依赖,往往埋在没人碰的旧模板里。

阶段二:先决定新的验证问题到底怎么问

每个环境最好先回答清楚,系统以后默认验证的是什么:

整个组织可以同时支持两条路,但单个环境若没有默认答案,评审压力会很快失控。

阶段三:先双签,再双向核验,最后再上强制策略

切换窗口里,可以让新发布候选在新路径上完成签名,同时保留必要的旧行为。这里追求的长期状态并非双轨运行,更实际的目标,是先把验证证据和失败样式收集完整,再把 admission 规则切成阻断模式。

通过标准应当尽量工程化:

阶段四:切 enforcement,再清理 DCT 资产

当 CI 与预发环境里的验证都已经稳定通过,就可以从 pull/build 环境移除 DCT,在平台允许的地方关闭注册表侧 DCT,再把不用的 delegation key 等材料退役。[2][3]

理想终态应该很朴素:

一个足以推翻“快速迁移”叙事的证伪条件

如果你的环境高度 air-gapped(隔离网络),或者注册表与准入层现在还不具备所需的签名 referrer 支持,或者安全流程暂时还没有办法批准 OIDC 身份策略与证书 trust store 策略中的任意一种,那么“快速切换”这件事在当前条件下就站不住。

这时需要先把验证权威模型定下来,再选 CLI。把架构缺口伪装成工具安装任务,后面通常会反复返工。

接下来一个季度值得盯住的四件事

  1. 残余 DCT 依赖,尤其是只会在热修复或回滚流程里冒出来的那种。[1][2]
  2. digest-first 验证纪律 是否已经进入 CI、注册表和准入控制。[5][7]
  3. trust policy 所有权 是否真正清楚:Sigstore 侧看 issuer 与身份,Notation 侧看证书与 trust store。[4][6][7]
  4. 云平台退出时间表,例如 ACR 的 2028 年 DCT 移除节点。[3]

结语

一场做得好的 DCT 迁移,关注点不该是哪个新签名 CLI 用起来更像旧工具,真正关键的是:生产里到底由什么契约来决定“这份镜像可信”。

如果你的组织本来就以身份为中心,Sigstore 往往更贴合现有流程;如果组织治理本来就以证书和策略为中心,Notation 通常更容易落地。两条路最后指向的是同一个升级动作:让信任判断回到 digest 级验证,并把签名身份或证书策略写成可审计、可解释的显式规则。

来源

  1. Docker Docs, Content trust in Docker(DCT 的 tag 语义、密钥角色、根密钥丢失不可恢复警告、DOCKER_CONTENT_TRUST 行为)
  2. Docker Blog, Retiring Docker Content Trust(Notary v1 维护状态、Docker Hub 使用占比低于 0.05%、DOI 证书过期时间线、迁移方向)
  3. Microsoft Learn, Transition from Docker Content Trust to Notary Project - Azure Container Registry(ACR 弃用时间表、关闭 DCT 的方法、Notary Project 迁移入口)
  4. Sigstore Docs, Overview(无长期密钥签名、Fulcio 短时证书、Rekor 透明日志、OIDC 身份流程)
  5. Sigstore Docs, Verifying Signatures(身份约束验证参数、digest claim 校验、bundle 与日志验证行为)
  6. Notation README(OCI 标准签名、Notation 作为 Notary Project 规格实现、Azure Key Vault 与 AWS Signer 集成示例)
  7. Microsoft Learn, Sign Container Images with Notation and Azure Key Vault by Using a Self-Signed Certificate(优先按 digest 签名、Notation CLI 与插件流程、验证路径)