3. IDP 制品类型与签名场景
在内部开发者平台(IDP)中,制品签名并非“一刀切”的操作。不同制品类型具有截然不同的打包结构、分发方式和运行时依赖,因此其签名需求、签名工具和验证策略也各不相同。本章将系统梳理容器镜像、Helm Chart、JAR 包、NPM 包这四类核心制品的签名场景,明确各自的签名对象、签名工具链以及自动化测试中的验证要点。
3.1 制品签名需求总览
下表从签名对象、核心工具、签名范围、验证时机四个维度,对比四类制品的签名需求差异:
| 制品类型 | 签名对象 | 核心工具 | 签名范围 | 验证时机 |
|---|---|---|---|---|
| 容器镜像 | 镜像 Manifest + 层摘要 | Cosign / Notation | 镜像仓库级(Repository + Tag) | 拉取时、部署准入时 |
| Helm Chart | Chart 包(.tgz)或 Provenance 文件 | Helm GPG / Cosign | Chart 版本级 | Chart 安装/升级时 |
| JAR 包 | JAR 文件内容(含 POM) | GPG / Maven Jarsigner | 构件坐标级(GroupId:ArtifactId:Version) | 依赖解析时、构建验证时 |
| NPM 包 | 包 tarball(.tgz) | npm audit / Sigstore | 包名@版本级 | 安装时、发布前 |
3.2 容器镜像签名场景
容器镜像是 IDP 中最常见的交付制品。签名对象是镜像的 Manifest 和每一层 Layer 的摘要(Digest)。当前主流方案为 Cosign(基于 Sigstore 生态)和 Notation(基于 OCI 1.1 标准)。
签名流程的核心步骤:
- 构建镜像并推送到仓库。
- 使用私钥对镜像摘要进行签名,生成签名对象(Signature Object)。
- 将签名对象关联存储到镜像仓库(作为 OCI Artifact 或 Tag 后缀)。
- 在拉取或部署准入阶段,使用公钥或信任策略验证签名。
自动化测试验证要点:
- 签名完整性: 验证签名对象是否成功生成并推送。
- 篡改检测: 修改镜像层后重新签名,验证旧签名是否失效。
- 多签名支持: 测试同一镜像被多个签名者签名时的验证逻辑。
- 策略引擎集成: 验证 Kyverno / OPA 等准入控制器能否正确拒绝未签名镜像。
registry.example.com/app:v1.0 签名后,通过 cosign verify 命令验证;再使用 cosign copy 复制镜像并修改标签,验证签名是否随摘要绑定而非标签绑定。
3.3 Helm Chart 签名场景
Helm Chart 的签名机制分为两种模式:传统 Helm GPG 签名(生成 provenance 文件)和基于 Cosign 的 OCI Chart 签名。在 IDP 中,推荐使用 OCI 注册表存储 Chart,并采用 Cosign 统一签名链路。
签名流程:
- 打包 Chart 为
.tgz文件。 - 使用 GPG 或 Cosign 对 Chart 包签名。
- 将 Chart 包和签名文件推送到 OCI 仓库。
- 安装时通过
helm install --verify或准入控制器验证。
自动化测试验证要点:
- Provenance 文件完整性: 验证
.prov文件与 Chart 包哈希匹配。 - 公钥轮换: 测试签名密钥更新后,旧 Chart 是否仍可被验证。
- 依赖 Chart 签名: 验证子 Chart 签名是否被父 Chart 继承或独立验证。
- OCI 签名兼容性: 测试 Cosign 签名的 Chart 能否被 Helm 3.8+ 原生识别。
--verify 标志仅验证 provenance 文件,不会自动验证依赖 Chart 的签名。在自动化测试中,必须显式对每个依赖 Chart 执行签名验证。
3.4 JAR 包签名场景
JAR 包签名在 Java 生态中历史悠久,主要依赖 Jarsigner(JDK 内置)和 GPG(用于 Maven Central 发布)。签名对象是 JAR 文件内的所有条目(Entry),签名信息存储在 META-INF/*.SF 和 META-INF/*.RSA 文件中。
签名流程:
- 使用
jarsigner工具对 JAR 文件签名,指定密钥库和别名。 - 生成签名后的 JAR 文件(内部包含签名块文件)。
- 部署到 Maven 仓库(如 Nexus / Artifactory)。
- 在构建时通过
maven-enforcer-plugin或自定义任务验证签名。
自动化测试验证要点:
- 签名算法强度: 验证是否使用 SHA-256 及以上摘要算法,拒绝 SHA-1。
- 证书链验证: 测试签名证书过期、吊销时的验证行为。
- 篡改检测: 解压 JAR 修改 class 文件后重新打包,验证签名是否失效。
- 多签名共存: 测试同一 JAR 被多个组织签名时的验证优先级。
# 使用 jarsigner 签名示例
jarsigner -keystore mykeystore.jks -storepass:file storepass.txt \
-sigalg SHA256withRSA -digestalg SHA-256 \
myapp.jar myalias
# 使用 jarsigner 验证示例
jarsigner -verify -verbose -certs myapp.jar
3.5 NPM 包签名场景
NPM 生态的签名机制相对较新,主要依赖 Sigstore(通过 npm audit signatures)和 npm package provenance(基于 OIDC)。签名对象是发布的 tarball 文件。
签名流程:
- 在 CI 中发布 NPM 包时,启用 provenance 声明。
- Sigstore 自动对包摘要进行签名,生成签名凭证。
- 签名信息存储在 npm 注册表的 attestation 中。
- 安装时通过
npm audit signatures验证包的签名来源。
自动化测试验证要点:
- Provenance 声明: 验证发布的包是否包含正确的构建来源(GitHub Actions / GitLab CI)。
- 重放攻击防护: 测试同一包在不同 CI 运行中是否生成唯一签名。
- 离线验证: 测试在无网络环境下能否通过本地公钥缓存验证签名。
- 作用域包签名: 验证
@scope/package格式的包签名是否与普通包一致。
npm config set audit-signatures true,并在 CI 流水线中加入 npm audit signatures --registry=https://registry.internal 步骤。
3.6 制品签名链路架构总览
下图展示了四类制品在 IDP 中的签名链路架构,从构建阶段到部署准入阶段的完整流程:
3.7 自动化测试策略矩阵
针对上述四类制品,自动化测试策略应覆盖以下维度。下表给出了每个维度的测试用例设计建议:
| 测试维度 | 容器镜像 | Helm Chart | JAR 包 | NPM 包 |
|---|---|---|---|---|
| 正向签名 | Cosign 签名并验证通过 | Helm provenance 生成并验证 | Jarsigner 签名并验证通过 | npm provenance 发布并验证 |
| 篡改检测 | 修改镜像层后验证失败 | 修改 Chart.yaml 后验证失败 | 修改 class 文件后验证失败 | 修改 tarball 后验证失败 |
| 密钥轮换 | 新旧密钥分别验证 | GPG 密钥更换后验证 | 证书更换后验证 | OIDC 身份变更后验证 |
| 多签名者 | 两个 Cosign 密钥签名 | 多 GPG 用户签名 | 多证书链签名 | 多 CI 来源签名 |
| 过期/吊销 | 证书过期后验证失败 | GPG 密钥吊销后验证 | 证书吊销列表验证 | Sigstore 撤销验证 |
| 性能基准 | 签名耗时 < 5s | 签名耗时 < 3s | 签名耗时 < 2s | 签名耗时 < 1s |
3.8 本章小结
容器镜像、Helm Chart、JAR 包、NPM 包四类制品的签名需求各有侧重:
- 容器镜像 和 Helm Chart 推荐统一使用 Cosign + OCI 仓库,实现签名链路标准化。
- JAR 包 需关注签名算法强度和证书链管理,避免使用已弃用的 SHA-1。
- NPM 包 应优先采用 Sigstore 的 provenance 机制,减少密钥管理负担。
- 自动化测试必须覆盖正向签名、篡改检测、密钥轮换、多签名者、过期吊销和性能基准六个维度。