第一章Docker镜像签名不是选修课安全合规的底层逻辑在容器化生产环境中未经验证的镜像等同于未经审计的二进制程序——它可能携带后门、恶意配置或过期漏洞。Docker镜像签名Docker Content Trust, DCT并非锦上添花的功能而是构建零信任架构的强制性基石。其核心价值在于将软件供应链的信任锚点从“谁构建了它”转向“谁签署了它”并通过密码学保证镜像内容自签名时刻起不可篡改。签名如何建立可信链Docker Content Trust 利用基于 PKI 的密钥体系根密钥root key离线保管用于签发委托密钥targets key后者再签署具体镜像标签。当客户端启用 DCT 后pull 操作会自动校验签名有效性及签名者身份拒绝未签名或签名失效的镜像。启用与验证签名的实操步骤# 启用 Docker Content Trust export DOCKER_CONTENT_TRUST1 # 构建并推送带签名的镜像需先初始化仓库签名 docker build -t myregistry.example.com/app:v1.2.0 . docker push myregistry.example.com/app:v1.2.0 # 验证签名信息输出签名者、时间戳、密钥ID docker trust inspect --pretty myregistry.example.com/app该流程强制要求所有推送镜像必须由授权密钥签名否则 push 将失败。常见签名失效场景镜像被中间人篡改后重新推送签名哈希不匹配签名密钥过期或被吊销DCT 自动拒绝过期证书本地未配置可信根密钥首次 pull 时无法验证 targets 签名Docker Content Trust 合规能力对照表合规要求DCT 支持能力验证方式镜像来源可追溯绑定签名者身份如 team-signing-keyproddocker trust inspect显示 signer 和 timestamp完整性保障SHA-256 内容哈希 RSA 签名绑定pull 时自动校验 manifest digest 与 signature payload第二章理解镜像签名的核心机制与标准演进2.1 签名的本质从数字签名到可信供应链的密码学基础数字签名并非简单“盖章”而是基于非对称密码学的数学承诺私钥生成不可伪造的签名公钥可无条件验证其完整性与来源。签名验证的核心流程发送方用私钥对消息摘要如 SHA-256加密生成签名接收方用同一公钥解密签名还原摘要独立计算消息哈希比对两者是否一致典型 ECDSA 签名验证Go 实现片段// Verify signature using public key and message func Verify(pub *ecdsa.PublicKey, msg []byte, r, s *big.Int) bool { h : sha256.Sum256(msg) return ecdsa.Verify(pub, h[:], r, s) // r,s: signature components }此处r和s是椭圆曲线上标量运算结果ecdsa.Verify内部执行模幂与点乘验证确保签名未被篡改且源自对应私钥。签名在供应链中的信任锚点作用环节签名载体验证主体源码提交GPG commit signatureCI 系统容器镜像Notary v2 signatureKubernetes admission controller2.2 CNCF Notary v2 与 Cosign 的架构对比与选型实践核心设计哲学差异Notary v2 聚焦于 OCI 兼容的通用签名服务采用独立的 TUFThe Update Framework后端Cosign 则贯彻“Kubernetes 原生”理念将签名直接存为 OCI Artifact如application/vnd.dev.cosign.sig无需额外元数据服务。签名存储方式对比维度Notary v2Cosign签名载体独立 TUF 仓库 OCI registry 扩展同一 registry 中的附属 artifact验证依赖TUF root/targets metadata公钥或 Fulcio OIDC 证书链典型 Cosign 签名流程# 使用 Fulcio 自动签发短期证书 cosign sign --oidc-issuer https://github.com/login/oauth \ --oidc-client-id sigstore \ ghcr.io/example/app:v1.0该命令触发 OIDC 认证流获取短期 X.509 证书并将签名以 detached 形式推送至 registry 同一 repo 下的 .sig artifact。验证时无需维护私钥或 TUF 仓库状态显著降低运维复杂度。2.3 OCI Image Spec 1.1 对签名元数据的原生支持与验证流程签名元数据的标准化字段OCI Image Spec 1.1 引入signatures字段作为镜像清单image manifest的可选顶层属性支持内联或外部引用签名{ schemaVersion: 2, signatures: [{ type: application/josejson, mediaType: application/vnd.oci.image.signature.v1json, content: eyJhbGciOiJFUzI1NiIsImtpZCI6ImFsaWNlLWtleSJ9... }] }该字段声明签名格式、媒体类型及 JOSE 编码内容使运行时能统一识别和解析无需依赖专有注解如 org.opencontainers.image.signatures。验证流程关键阶段拉取镜像清单后检查是否存在signatures数组对每个签名项验证 JOSE 结构完整性与签名者公钥信任链比对签名中声明的signedImageDigest与实际镜像摘要是否一致签名与镜像绑定关系字段作用是否必需signedImageDigest被签名镜像的 SHA256 摘要是mediaType标识签名格式规范版本是contentJOSE Compact Serialization 签名载荷是2.4 NIST SP 800-190A 第5.3节解析签名作为容器镜像完整性保障的强制性控制项签名验证的执行时机NIST 明确要求镜像拉取pull、运行run及部署前必须验证签名有效性而非仅在构建阶段生成。签名验证失败的处置策略拒绝加载未签名或签名无效的镜像记录完整验证日志含公钥指纹、签名时间戳、证书链OCI 镜像签名验证示例cosign verify --key cosign.pub registry.example.com/app:v1.2.0该命令调用 Cosign 工具使用本地公钥cosign.pub验证 OCI 镜像的 Sigstore 签名--key参数指定信任锚确保签名者身份可追溯至已授权的 CI/CD 流水线。签名与镜像元数据绑定关系字段作用是否强制digest镜像内容 SHA256 哈希是signature对 digest 的数字签名是issuer签发者身份如 GitHub OIDC 主体是2.5 实战使用 cosign verify 验证主流云厂商镜像签名链并生成合规审计报告验证阿里云ACR镜像签名# 验证阿里云ACR私有仓库中已签名的镜像 cosign verify --key https://kms.cn-hangzhou.aliyuncs.com/keys/acr-signing-key \ registry.cn-hangzhou.aliyuncs.com/my-ns/nginx:v1.25.3该命令通过阿里云KMS托管的公钥远程验证签名--key支持 HTTPS URL 形式的密钥发现确保签名链可追溯至可信根。多厂商签名兼容性对比云厂商密钥分发方式签名存储位置阿里云 ACRKMS HTTPS endpointOCI artifact manifest annotations腾讯云 TCRTCR Registry APISeparate signature image华为云 SWRSWR Certificate ServiceOCI index annotations生成SBOM签名审计报告使用cosign verify --output-file report.json导出结构化验证结果结合syft扫描生成 SBOM与签名元数据合并为合规证据包第三章构建可审计、可追溯的签名工作流3.1 私有密钥生命周期管理HSM集成与FIPS 140-2合规密钥生成HSM密钥生成调用示例GokeySpec : aws kms.CreateKeyInput{ KeyUsage: aws.String(ENCRYPT_DECRYPT), KeySpec: aws.String(RSA_3072), Origin: aws.String(AWS_HSM), // 强制绑定硬件模块 BypassPolicyLockoutSafetyCheck: aws.Bool(true), } result, err : kmsClient.CreateKey(keySpec)该调用强制密钥在FIPS 140-2 Level 3认证的HSM中生成Origin: AWS_HSM确保密钥永不离开HSM边界KeySpec指定符合NIST SP 800-56B rev2的强密钥长度。FIPS合规性验证要点密钥材料全程不可导出仅以句柄形式引用所有加密操作必须通过HSM API执行禁止软件模拟审计日志需留存至少90天并防篡改HSM密钥状态流转状态可操作性FIPS允许Enabled加密/解密/签名✅PendingDeletion仅销毁✅需30天等待期3.2 自动化签名流水线GitHub Actions Cosign OIDC身份联邦实战OIDC身份联邦核心配置permissions: id-token: write contents: read该配置启用 GitHub OIDC token 发行权限使工作流可向支持 OIDC 的签名服务如 Cosign安全证明自身身份无需硬编码密钥。流水线签名步骤构建容器镜像并推送至 GitHub Container Registry调用cosign sign使用 GitHub OIDC token 进行无密签名验证签名有效性并上传签名元数据至透明日志Cosign 签名命令详解cosign sign \ --oidc-issuer https://token.actions.githubusercontent.com \ --fulcio-url https://fulcio.sigstore.dev \ --rekor-url https://rekor.sigstore.dev \ ghcr.io/owner/reposha256:abc123--oidc-issuer指定 GitHub OIDC 发行方--fulcio-url对接 Sigstore 证书颁发服务--rekor-url将签名记录写入不可篡改的透明日志。3.3 签名策略即代码基于 Sigstore Policy Controller 的准入控制部署策略定义与 CRD 扩展Sigstore Policy Controller 通过自定义资源 ClusterImagePolicy 声明签名验证规则apiVersion: policy.sigstore.dev/v1beta1 kind: ClusterImagePolicy metadata: name: enforce-cosign-signed spec: images: - glob: ghcr.io/example/* authorities: - name: github-actions-key key: data: | -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE... -----END PUBLIC KEY-----该配置强制所有匹配镜像必须由指定公钥验证签名glob支持通配符匹配authorities可叠加多个信任源。准入链路集成Policy Controller 作为 ValidatingAdmissionPolicy 的后端执行器拦截Pod创建请求并调用 cosign 验证镜像签名有效性。组件职责Policy Controller解析策略、发起签名验证、返回准入决策cosign verifier本地校验 OCI 镜像的 detached signature 和证书链第四章Registry深度集成与SBOM联动签名验证4.1 配置Harbor 2.9启用Notary v2签名存储与Webhook事件推送启用Notary v2签名存储Harbor 2.9原生集成Notary v2Cosign兼容需在harbor.yml中启用签名服务notaryv2: enabled: true storage: filesystem: rootdirectory: /data/notaryv2该配置启用本地文件系统作为Notary v2签名元数据与TUF仓库的持久化后端rootdirectory路径需与Harbor主容器挂载卷一致确保签名数据跨重启不丢失。配置Webhook事件推送Notary v2签名事件通过标准Harbor Webhook推送支持以下关键事件类型事件类型触发条件signatures.push成功推送镜像签名至Notary v2signatures.delete签名被显式移除4.2 将Syft生成的SBOM嵌入签名荷载OCI Artifact Bundle实践构建带SBOM的OCI Artifact BundleOCI Artifact Bundle 允许将 SBOM如 Syft 输出的 CycloneDX JSON作为独立工件与镜像解耦绑定。关键在于复用 oras CLI 与符合 OCI 规范的 artifactType 声明syft alpine:3.19 -o cyclonedx-json sbom.cdx.json oras push localhost:5000/myapp:sbom \ --artifact-type application/vnd.cyclonedxjson \ sbom.cdx.json:application/vnd.cyclonedxjson该命令将 SBOM 以标准 MIME 类型注册为独立 artifact--artifact-type 确保仓库可识别其语义sbom.cdx.json 文件名不参与解析仅内容类型生效。签名与引用协同机制组件作用OCI 兼容性cosign signature对 bundle digest 签名✅ 支持 artifact digest 引用SBOM descriptor在 index.json 中声明✅ 符合 OCI Image Index v1.14.3 在Kubernetes Admission Controller中拦截无签名/弱签名镜像拉取请求准入校验核心逻辑Admission Controller 通过 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration 拦截 Pod 创建请求在 Validate 阶段解析 spec.containers[].image 并调用 Cosign 或 Notary v2 API 验证签名有效性。签名策略配置示例apiVersion: policies.k8s.io/v1 kind: ImagePolicy metadata: name: require-signed-images spec: images: - namePattern: ghcr.io/* policy: cosign: {minKeySize: 4096, requireSBOM: true}该策略强制所有 ghcr.io 命名空间下的镜像必须使用 ≥4096 位 RSA 密钥签名并附带 SBOM 清单。校验失败响应码对照错误类型HTTP 状态码Reason无签名403ImageMissingSignature弱密钥403InvalidSignatureKey4.4 构建签名-SBOM-漏洞扫描三元验证看板Trivy Cosign Grype联合输出三元协同验证流程通过容器镜像的签名Cosign、软件物料清单SBOM生成Trivy SBOM、漏洞扫描Grype三者联动构建可信交付闭环。所有输出统一注入 OCI 注解供策略引擎实时校验。自动化流水线集成示例# 1. 生成 SBOM 并推送到 registry trivy image --format cyclonedx --output sbom.json --sbom-type spdx your-app:v1.2.0 # 2. 签名镜像 cosign sign --key cosign.key your-registry/appsha256:abc123 # 3. 扫描漏洞并关联 SBOM grype your-registry/app:v1.2.0 --output json --file grype-report.json该脚本确保每次构建均产出可追溯的 SBOM、不可篡改的签名、以及与 SPDX 兼容的漏洞上下文。--sbom-type spdx 指定标准格式便于 Grype 解析依赖关系--file 输出结构化报告供看板聚合。验证结果聚合表组件工具输出格式校验目标镜像完整性CosignDSSE 证明签名公钥绑定依赖溯源TrivyCycloneDX/SPDX组件许可证与版本漏洞覆盖GrypeJSON/SARIFCVE 匹配精度 ≥98%第五章从签名到零信任容器运行时的演进路径容器安全已从单一镜像签名验证逐步演进为覆盖构建、分发、调度、运行全生命周期的零信任架构。CNCF 的 Falco 与 Tetragon 在内核态实时监控进程行为配合 SPIFFE/SPIRE 实现工作负载身份自动轮换替代静态证书绑定。可信执行环境集成Intel TDX 和 AMD SEV-SNP 现已在 Kubernetes v1.29 中通过 Device Plugin RuntimeClass 原生支持。以下为启用 TDX 的 Pod 配置片段apiVersion: v1 kind: Pod metadata: name: tdx-nginx spec: runtimeClassName: tdx-runtime containers: - name: nginx image: registry.example.com/nginx:1.25.3sha256:abc123... securityContext: seccompProfile: type: RuntimeDefault策略即代码实践Open Policy AgentOPA与 Gatekeeper 联动实现运行时准入控制。典型策略要求所有生产命名空间的 Pod 必须声明 service-account-token 卷挂载限制拒绝未设置automountServiceAccountToken: false的 Deployment拦截使用hostNetwork: true且未通过 SCC 白名单的 Pod强制注入istio.io/rev标签以匹配服务网格版本策略运行时行为基线建模行为类型基线阈值检测工具响应动作execve 调用 /bin/sh3 次/分钟Tetragon eBPF probeKill Alert via Slack webhook非标准端口 bind80/443/8080 以外Falco rule unusual-port-bindingQuarantine Snapshot memory