镜像签名验证是拉取时自动触发的强制校验,依赖签名比对、层哈希校验、内容寻址三重机制;必须用 digest(如@sha256:...)拉取,禁用模糊tag;生产环境需结合cosign-webhook等准入控制强化策略拦截。

镜像签名验证不是“事后检查”,而是拉取时自动触发的强制校验动作。它靠三重机制协同工作:签名比对、层哈希校验、内容寻址,缺一不可。
启用信任机制并配置可信根
签名验证的前提是客户端知道该信谁。Docker 默认信任 Docker Hub 的根证书,私有环境必须显式配置:
- 设置环境变量 DOCKER_CONTENT_TRUST=1(Docker 27+ 默认开启,但建议显式声明)
- 若使用 cosign,通过 --key 指定公钥路径,或用 --certificate-oidc-issuer 绑定可信身份源(如 GitHub Actions)
- 私有 Registry 需部署 Notary v2 或兼容 OCI Artifact 签名的服务(如 Harbor v2.8+)
必须用 digest 拉取,禁用模糊 tag
tag(如 :latest 或 :v2)可被仓库端任意修改,签名再强也拦不住劫持。真正起效的前提是内容寻址:
- 拉取命令必须写成
docker pull nginx@sha256:abc123...,而非nginx:latest - CI/CD 流水线中禁止出现未锁定的 tag;Kubernetes Pod 的
image:字段也应固定为@sha256:格式 - 可通过
docker inspect查看镜像实际 digest,或用oras discover查询 registry 中关联的签名 artifact
签名与层校验双保险同时生效
签名验证失败会直接中断拉取;即使签名被绕过,Docker 运行时仍会逐层校验:
- 客户端下载 manifest 后,向 Notary 或 cosign 兼容服务查询签名,并用公钥解密还原原始哈希,比对本地计算值
- 每层 blob 解压后,Docker 自动计算其未压缩内容的 SHA256(即 diffID),与 manifest 中声明值严格匹配
- 任一层被篡改(如注入恶意 so 文件),diffID 不符,报错
failed to verify layer integrity,且无法跳过
在部署环节叠加策略拦截
仅靠客户端验证不够,生产环境需在入口处强制把关:
- Kubernetes 中部署 cosign-webhook Admission Controller,在 Pod 创建前校验镜像签名有效性、证书签发者、时间窗口及 Rekor 日志存在性
- 策略可限定:仅允许来自
https://github.com/myorg/.*@refs/heads/main的签名,且必须写入 Sigstore Rekor - 配合 Kyverno 或 OPA Gatekeeper,实现基于命名空间、镜像路径、签名者邮箱等属性的细粒度放行规则











