notary v1 客户端无法连接 notary v2 服务端,因二者协议不兼容:v1 基于 tuf+json-rpc,v2 遵循 oci distribution spec,使用独立 artifact 签名和标准 registry api;需改用 cosign 或 notation 工具,并确保 registry 支持 oci artifact。

notary v1 客户端连不上 v2 服务端?先确认协议兼容性
Notary v2 不是 v1 的简单升级,而是基于 OCI 分发规范重构的独立协议栈,v1 客户端(notary 命令行工具)根本无法与 v2 服务端通信——它压根不理解 application/vnd.oci.image.manifest.v1+json 或 application/vnd.oci.artifact.manifest.v1+json 这类媒体类型。
常见错误现象:404 Not Found 或 415 Unsupported Media Type,尤其在 push/sign 操作时;不是网络或认证问题,是协议握手失败。
- v1 使用自定义的 TUF + JSON-RPC 风格 API,路径类似
/v2/_catalog或/v2/<repo>/_trust/tuf/</repo> - v2 严格遵循 OCI Distribution Spec,所有操作走标准 registry http API,签名作为 artifact 上传到
<repo>:<digest>-sig</digest></repo>或独立命名空间(如<repo>:sha256-xxx.sig</repo>) - 没有“平滑迁移”开关,v1 客户端和 v2 服务端之间不存在兼容桥接层
用什么替代 notary CLI?选 cosign + notation
官方已明确将 cosign 和 notation 作为 Notary v2 的推荐客户端工具链:前者专注密钥管理与签名验证(尤其适合 CI/CD),后者更贴近传统 Notary 的交互习惯(支持 plugin、本地 trust store、多签名策略)。
使用场景差异:
- 如果你在 github Actions / tekton 里做自动签名,优先用
cosign sign—— 它对 OIDC Token、KMS(如 AWS KMS、HashiCorp Vault)集成最成熟 - 如果你需要本地管理多个信任策略、验证时提示 human-readable 策略名,或者要对接企业级证书颁发流程,
notation更合适(它内置了notation verify --policy和notation cert generate) - 两者都支持 OCI Image、Helm Chart、CNAB 等任意 blob,但
notation对非镜像 artifact 的元数据描述更灵活(通过artifactType字段)
registry 必须启用 OCI Artifact 支持
Notary v2 签名不是附加在 manifest 上的字段,而是独立上传的 artifact,registry 必须明确声明支持 org.opencontainers.artifacts 扩展能力,否则 notation sign 或 cosign sign 会报错 400 Bad Request: unknown artifact type。
主流 registry 兼容状态:
-
docker.io(Docker Hub):默认开启,无需配置 -
ghcr.io:从 2023 年底起全量支持,但需确保 repo 是 public 或你有 write 权限 - 私有 Harbor:必须升级到 v2.8+,并在
harbor.yml中显式开启enable_content_trust: true和artifact_types: ["application/vnd.oci.image.manifest.v1+json", "application/vnd.oci.artifact.manifest.v1+json"] - 自建 distribution(registry:2):原生不支持,必须用
oras-project/oras或换用project-zot等兼容实现
签名验证逻辑变了:不再依赖本地 TUF root.json
v1 的验证靠下载一整套 TUF 元数据(root.json, targets.json 等)并本地执行阈值检查;v2 把策略判断前移到验证命令本身,签名有效性 ≠ 信任成立 —— 你必须显式指定策略源(文件、URL、plugin)。
容易踩的坑:
- 直接运行
notation verify <image></image>会失败,报错no verification policy found—— 必须先写一个verification-policy.json并用--policy指定 -
cosign verify默认只校验签名和证书链,不强制绑定策略;若要等效 v1 的“只有 targets.json 允许的 tag 才可信”,得配合cosign verify --certificate-oidc-issuer或自定义--rekor-url+ 策略脚本 - 所有策略文件里的
repository字段必须精确匹配镜像名(含 registry 主机名),myapp和localhost:5000/myapp被视为两个不同仓库
复杂点在于:信任决策不再由服务端集中控制,而是分散到每个验证方的策略配置里。这意味着策略同步、更新、审计都得自己设计机制,不是换个工具就能自动继承原来的安全模型。