3. 制品类型与签名需求:容器镜像、Helm Chart、JAR/WAR包、NPM包等不同制品的签名场景与安全要求

在平台工程 IDP 中,CI/CD 流水线会产出多种类型的制品。不同制品的打包方式、分发机制和运行时环境差异巨大,其签名需求和安全要求也各不相同。本章将系统梳理容器镜像、Helm Chart、JAR/WAR 包、NPM 包等主流制品的签名场景,并给出对应的安全策略建议。

3.1 制品签名核心目标与通用流程

无论哪种制品类型,签名的核心目标是一致的:

  • 完整性验证:确保制品在构建、传输、存储过程中未被篡改。
  • 来源认证:确认制品确实来自受信任的构建系统或发布者。
  • 不可否认性:发布者无法否认其签发的制品。
  • 策略执行:在部署或安装环节,根据签名状态执行准入控制。
通用签名流程:构建 → 计算摘要 → 使用私钥签名 → 附加签名或生成独立签名文件 → 分发签名与制品 → 验证方使用公钥验证摘要 → 比对摘要。

3.2 容器镜像签名

容器镜像是云原生环境中最核心的制品。其签名需求源于镜像的多层结构、仓库分发机制以及 Kubernetes 等运行时的安全准入要求。

3.2.1 签名场景与工具

场景 说明 推荐工具/标准
镜像仓库签名 在推送镜像到仓库时,对镜像 Manifest 进行签名 Notation、Cosign
构建时签名 在 CI 流水线构建完成后立即签名 Cosign (Keyless 模式)、Kaniko
运行时验证 Kubernetes 准入控制器在拉取镜像前验证签名 Ratify、Kyverno、OPA Gatekeeper
镜像层签名 对每一层内容进行签名,粒度更细 OCI Artifact Manifest + Notation

3.2.2 安全要求

  • 签名不可剥离:签名应作为 OCI Artifact 与镜像关联,而非仅存于仓库元数据。
  • 支持 Keyless 模式:利用 OIDC 和临时证书,避免长期私钥管理风险。
  • 准入策略绑定:签名验证结果必须与部署策略联动,拒绝未签名或签名无效的镜像。
  • 镜像摘要锁定:签名应绑定镜像的 digest(sha256),而非 tag。
实践要点:在 GitOps 工作流中,建议将签名验证作为 ArgoCD 或 Flux 的 pre-sync hook,确保只有经过签名的镜像才能被部署到生产环境。
容器镜像签名与验证流程 容器镜像签名与验证流程 CI 构建镜像 计算镜像摘要 使用私钥签名 推送签名 Artifact K8s 准入控制器 拉取签名并验证 比对摘要 允许/拒绝部署 说明:Cosign 支持 Keyless 模式,通过 OIDC 获取临时证书,签名存储在 Rekor 透明度日志中。 验证时无需预先分发公钥,适合动态团队和开源项目。

3.3 Helm Chart 签名

Helm Chart 是 Kubernetes 应用的打包格式。Chart 签名主要保护 Chart 包(.tgz)的完整性和来源,确保用户在安装或升级时使用的是未被篡改的 Chart。

3.3.1 签名机制

Helm 原生支持使用 GPG 对 Chart 进行签名。签名过程生成一个 .prov 文件(provenance file),包含 Chart 包的哈希值和签名。

# 使用 GPG 密钥对 Chart 签名
helm package --sign --key 'your-key-name' --keyring ~/.gnupg/secring.gpg ./mychart

# 验证 Chart 签名
helm verify ./mychart-0.1.0.tgz --keyring ~/.gnupg/pubring.gpg

3.3.2 安全要求

要求 说明
GPG 密钥管理 使用专用签名密钥,与开发者个人密钥分离;密钥过期策略需明确
Chart 仓库集成 ChartMuseum 或 OCI 仓库应支持存储和分发 .prov 文件
依赖验证 子 Chart 和依赖库也需签名,形成信任链
CI/CD 自动化 在流水线中集成 helm package --sign,私钥存储在 HSM 或密钥管理服务中
注意:Helm 3 默认使用 OCI 仓库时,签名机制仍在演进中。建议结合 Notation 或 Cosign 对 OCI 制品进行统一签名,而非仅依赖 GPG。

3.4 JAR/WAR 包签名

JAR/WAR 包是 Java 生态的标准制品。签名通常使用 jarsigner 工具,基于数字证书对包内所有文件进行签名。

3.4.1 签名场景

  • 企业级应用部署:确保部署到应用服务器的 JAR/WAR 未被篡改。
  • Maven/Gradle 仓库:对发布的构件进行签名,防止依赖混淆攻击。
  • 安全审计:签名信息可追溯至构建者或 CI 系统。

3.4.2 安全要求

要求 说明
证书链完整 签名证书需由受信任的 CA 签发,或使用内部 PKI 并分发根证书
时间戳 使用 TSA(时间戳权威)为签名添加时间戳,确保证书过期后签名仍有效
签名算法 推荐使用 SHA-256 或更高强度的摘要算法,避免使用 SHA-1
CI/CD 集成 在 Maven/Gradle 构建插件中配置 jarsigner,私钥不得出现在构建脚本中
# 使用 jarsigner 签名 JAR 包
jarsigner -keystore mykeystore.jks -storepass:env KEYSTORE_PASS \
  -tsa http://timestamp.digicert.com \
  myapp.jar mykey-alias

# 验证 JAR 包签名
jarsigner -verify -verbose -certs myapp.jar

3.5 NPM 包签名

NPM 生态的签名机制相对较新。npm CLI 从 v8.0.0 开始支持包签名验证,使用 ECDSA 密钥对。

3.5.1 签名场景

  • 发布签名:在 npm publish 时对包内容进行签名。
  • 安装验证:在 npm install 时验证包的签名。
  • 供应链安全:结合 npm audit 和签名验证,防止恶意包注入。

3.5.2 安全要求

要求 说明
密钥对生成 使用 npm sign 命令生成 ECDSA 密钥对,公钥上传至 npm registry
CI/CD 集成 私钥存储在 CI 系统的 secrets 中,发布流水线自动执行签名
验证策略 在安装时通过 --signature 标志或配置 audit-signatures 强制验证
作用域包 企业应要求所有 @scope 包必须签名,未签名的包禁止安装
实践要点:对于私有 npm registry(如 Verdaccio、Artifactory),建议启用签名验证插件,在代理层拦截未签名的包。

3.6 制品签名需求对比总览

制品类型 签名工具/标准 签名对象 验证时机 密钥管理复杂度 CI/CD 集成难度
容器镜像 Cosign, Notation 镜像 Manifest 拉取时(准入控制) 中(支持 Keyless) 低
Helm Chart GPG, Cosign (OCI) Chart 包 (.tgz) 安装/升级时 中 中
JAR/WAR jarsigner 包内所有文件 部署时 高(需 CA 证书) 中
NPM 包 npm sign (ECDSA) 包内容 安装时 低 低
多制品签名架构总览 多制品签名架构总览 CI/CD 流水线 容器镜像 Helm Chart JAR/WAR NPM 包 Cosign / Notation GPG / Cosign jarsigner npm sign 所有签名操作应在 CI/CD 流水线中自动化执行,私钥统一由密钥管理服务(KMS)托管。

3.7 跨制品签名策略建议

在平台工程实践中,建议采用以下策略统一管理多制品签名:

  1. 统一签名层:使用 OCI Artifact 规范,将签名作为独立 Artifact 存储,与制品类型解耦。
  2. 密钥集中管理:所有签名私钥统一托管在 KMS(如 AWS KMS、HashiCorp Vault)中,CI/CD 流水线通过临时令牌获取签名权限。
  3. 策略即代码:将签名验证策略(如“必须签名”、“签名者必须在白名单内”)定义为代码,与部署流水线集成。
  4. 审计与可观测性:所有签名和验证操作记录到审计日志,便于事后追溯。
推荐路径:从容器镜像签名开始(Cosign + Keyless),逐步扩展到 Helm Chart 和 NPM 包,最后覆盖 JAR/WAR 等传统制品。优先选择支持 OCI 标准的工具,降低集成成本。