强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Rekor 透明日志完整教程 / 05 - 签名集成

第 5 章:签名集成

本章介绍如何使用 cosign 和 Sigstore 生态进行软件签名,并将签名记录写入 Rekor 透明日志。涵盖传统密钥签名和无密钥签名(Keyless Signing)两种方式。


5.1 签名方式概览

Sigstore 生态支持多种签名方式:

签名方式 密钥管理 适用场景 安全级别
传统密钥签名 长期密钥 + 密码 本地开发、小团队 ⭐⭐⭐
KMS 集成签名 云 KMS 管理密钥 企业环境 ⭐⭐⭐⭐
无密钥签名 短期证书,无长期密钥 CI/CD、开源项目 ⭐⭐⭐⭐⭐

5.2 cosign 基础签名

5.2.1 生成密钥对

# 交互式生成密钥对
cosign generate-key-pair

# 预期输出:
# Enter password for private key: <输入密码>
# Enter again: <确认密码>
# Private key written to cosign.key
# Public key written to cosign.pub

# 非交互式生成(CI/CD 环境)
COSIGN_PASSWORD=mysecurepassword cosign generate-key-pair

5.2.2 签名容器镜像

# 签名一个 OCI 容器镜像
cosign sign \
  --key cosign.key \
  --yes \
  ghcr.io/myorg/myimage:v1.0.0

# 签名并附带注释
cosign sign \
  --key cosign.key \
  --yes \
  --annotations "build_id=$BUILD_ID" \
  --annotations "commit_sha=$COMMIT_SHA" \
  ghcr.io/myorg/myimage:v1.0.0

# 签名多架构镜像(签名 manifest list)
cosign sign \
  --key cosign.key \
  --yes \
  --recursive \
  ghcr.io/myorg/myimage:v1.0.0

5.2.3 签名 Blob 文件

# 签名文件
cosign sign-blob \
  --key cosign.key \
  --yes \
  myartifact.tar.gz

# 签名并输出签名和证书到文件
cosign sign-blob \
  --key cosign.key \
  --yes \
  --output-signature myartifact.sig \
  --output-certificate myartifact.cert \
  myartifact.tar.gz

5.2.4 验证签名

# 验证容器镜像签名
cosign verify \
  --key cosign.pub \
  ghcr.io/myorg/myimage:v1.0.0

# 验证 Blob 签名
cosign verify-blob \
  --key cosign.pub \
  --signature myartifact.sig \
  myartifact.tar.gz

# 验证并检查注释
cosign verify \
  --key cosign.pub \
  --annotations "build_id=$BUILD_ID" \
  ghcr.io/myorg/myimage:v1.0.0

5.3 Fulcio 证书颁发

5.3.1 Fulcio 是什么?

Fulcio 是 Sigstore 的证书颁发机构(CA),基于用户的身份(OIDC 身份)颁发短期代码签名证书。

┌─────────────────────────────────────────────────────────────────┐
│                     Fulcio 工作流程                              │
│                                                                 │
│  用户               OIDC Provider            Fulcio            │
│   │                     │                      │               │
│   │ 1. 登录请求         │                      │               │
│   │────────────────────►│                      │               │
│   │                     │                      │               │
│   │ 2. ID Token         │                      │               │
│   │◄────────────────────│                      │               │
│   │                     │                      │               │
│   │ 3. 生成临时密钥对    │                      │               │
│   │ 4. CSR + ID Token   │                      │               │
│   │────────────────────────────────────────────►│               │
│   │                     │                      │               │
│   │                     │  5. 验证 Token        │               │
│   │                     │◄─────────────────────│               │
│   │                     │                      │               │
│   │                     │  6. 确认身份           │               │
│   │                     │─────────────────────►│               │
│   │                     │                      │               │
│   │ 7. 签名证书         │                      │               │
│   │◄────────────────────────────────────────────│               │
│   │                     │                      │               │
│   │ 8. 用临时密钥签名构件                       │               │
│   │ 9. 上传签名到 Rekor                         │               │
└─────────────────────────────────────────────────────────────────┘

5.3.2 Fulcio 证书的内容

Fulcio 颁发的证书包含以下关键信息:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: <unique-serial>
    Signature Algorithm: ECDSA-SHA384
        Issuer: CN=sigstore-intermediate, O=sigstore.dev
        Validity
            Not Before: <issue-time>
            Not After : <issue-time + 10min>    ← 10 分钟有效期
        Subject:
            <空 - 身份信息在扩展字段中>
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                email:user@example.com          ← OIDC 身份
            1.3.6.1.4.1.57264.1.1:
                https://accounts.google.com     ← OIDC 颁发者
            1.3.6.1.4.1.57264.1.8:
                https://github.com/login/oauth  ← 构建环境(GitHub Actions)
            1.3.6.1.4.1.57264.1.9:
                https://github.com/myorg/myrepo/.github/workflows/build.yml@refs/heads/main
                                               ← 工作流引用

5.3.3 Fulcio 支持的 OIDC 提供者

提供者 身份字段 说明
Google Email Google 账号邮箱
GitHub Email / Workflow GitHub Actions 身份
Microsoft Email Azure AD / Entra ID
GitLab Email / Pipeline GitLab CI
Dex 自定义 企业 OIDC 代理

5.4 OIDC 身份验证

5.4.1 什么是 OIDC?

OIDC(OpenID Connect)是一个基于 OAuth 2.0 的身份验证层,允许客户端验证用户身份并获取基本信息。

5.4.2 OIDC 与 Sigstore 的集成

Sigstore 使用 OIDC 获取用户的短期身份令牌(ID Token),然后向 Fulcio 申请代码签名证书。

主要 OIDC 提供者配置:

# Google
cosign sign --yes \
  --oidc-issuer=https://accounts.google.com \
  ghcr.io/myorg/myimage:v1.0.0

# GitHub Actions(自动检测)
# 无需手动指定 issuer,cosign 会自动检测 CI 环境

# GitLab CI
cosign sign --yes \
  --oidc-issuer=https://gitlab.com \
  ghcr.io/myorg/myimage:v1.0.0

# 自定义 OIDC 提供者(如企业 SSO)
cosign sign --yes \
  --oidc-issuer=https://sso.mycompany.com \
  --oidc-client-id=cosign \
  --oidc-client-secret=$OIDC_SECRET \
  ghcr.io/myorg/myimage:v1.0.0

5.4.3 手动获取 ID Token

在某些环境中,你可能需要手动获取 ID Token:

# 使用 gcloud 获取 Google ID Token
gcloud auth print-identity-token --audiences=sigstore

# 使用 GitHub API 获取 Token(GitHub Actions 中自动设置)
curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN" \
  "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sigstore"

# 使用 Dex 获取 Token
curl -s "https://dex.mycompany.com/auth?client_id=cosign&response_type=id_token&scope=openid+email"

5.5 无密钥签名(Keyless Signing)

5.5.1 无密钥签名原理

无密钥签名是 Sigstore 最重要的创新之一。它消除了长期密钥管理的负担:

传统签名:
  开发者 ──► 长期私钥(需安全存储数年)
         ──► 用户 ──► 公钥(需验证信任链)

无密钥签名:
  开发者 ──► OIDC 身份验证(一次性)
         ──► Fulcio 短期证书(10 分钟有效期)
         ──► 临时密钥签名
         ──► 签名记录到 Rekor
         ──► 临时密钥销毁

5.5.2 无密钥签名的步骤

# 步骤 1: 用户通过 OIDC 身份验证
# 步骤 2: Fulcio 颁发短期证书
# 步骤 3: cosign 使用临时密钥签名
# 步骤 4: 签名上传到 Rekor

# 一键完成所有步骤
cosign sign --yes ghcr.io/myorg/myimage:v1.0.0

# 输出示例:
# tlog entry created with index: 12345678
# Pushing signature to: ghcr.io/myorg/myimage:sha256-abc123.sig

5.5.3 验证无密钥签名

验证时需要提供预期的身份信息:

# 验证容器镜像
cosign verify \
  --certificate-identity=user@example.com \
  --certificate-oidc-issuer=https://accounts.google.com \
  ghcr.io/myorg/myimage:v1.0.0

# 验证 GitHub Actions 签名的镜像
cosign verify \
  --certificate-identity=https://github.com/myorg/myrepo/.github/workflows/build.yml@refs/heads/main \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  ghcr.io/myorg/myimage:v1.0.0

5.5.4 无密钥签名的安全优势

特性 传统密钥 无密钥签名
密钥存储 需要长期安全存储 临时密钥,立即销毁
密钥泄露影响 所有历史签名受影响 仅影响单次签名
证书有效期 数年 10 分钟
身份绑定 手动绑定 自动绑定 OIDC 身份
信任建立 需要密钥分发 基于 OIDC 提供者信任

5.6 企业级签名集成

5.6.1 使用云 KMS 签名

对于企业环境,建议使用云 KMS 管理签名密钥:

# AWS KMS
cosign sign \
  --key awskms:///alias/my-signing-key \
  --yes \
  ghcr.io/myorg/myimage:v1.0.0

# GCP KMS
cosign sign \
  --key gcpkms://projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key/versions/1 \
  --yes \
  ghcr.io/myorg/myimage:v1.0.0

# Azure Key Vault
cosign sign \
  --key azurekms://my-vault.my-service.azure.net/my-key \
  --yes \
  ghcr.io/myorg/myimage:v1.0.0

# HashiCorp Vault Transit
cosign sign \
  --key hashivault://transit/keys/my-key \
  --yes \
  ghcr.io/myorg/myimage:v1.0.0

5.6.2 KMS 配置表

云平台 环境变量 说明
AWS AWS_REGION, AWS_ACCESS_KEY_ID 需要 KMS 权限
GCP GOOGLE_APPLICATION_CREDENTIALS 需要 Cloud KMS 角色
Azure AZURE_TENANT_ID, AZURE_CLIENT_ID 需要 Key Vault 访问权限
Vault VAULT_ADDR, VAULT_TOKEN 需要 Transit 引擎权限

5.6.3 多密钥签名

对于高安全需求,可以使用多个密钥进行签名:

# 使用不同密钥签名
cosign sign --key key1.key --yes ghcr.io/myorg/myimage:v1.0.0
cosign sign --key key2.key --yes ghcr.io/myorg/myimage:v1.0.0

# 验证时要求多个签名
cosign verify \
  --key key1.pub \
  ghcr.io/myorg/myimage:v1.0.0

cosign verify \
  --key key2.pub \
  ghcr.io/myorg/myimage:v1.0.0

5.7 签名容器镜像的高级操作

5.7.1 签名 OCI Bundle

# 签名并指定存储位置
COSIGN_REPOSITORY=myregistry.io/signatures \
  cosign sign --key cosign.key --yes \
  ghcr.io/myorg/myimage:v1.0.0

# 验证时指定签名位置
COSIGN_REPOSITORY=myregistry.io/signatures \
  cosign verify --key cosign.pub \
  ghcr.io/myorg/myimage:v1.0.0

5.7.2 签名时附加 SBOM

# 生成 SBOM
syft ghcr.io/myorg/myimage:v1.0.0 -o spdx-json > sbom.spdx.json

# 签名 SBOM
cosign sign-blob \
  --key cosign.key \
  --yes \
  --output-signature sbom.sig \
  --output-certificate sbom.cert \
  sbom.spdx.json

# 签名镜像并附加 SBOM 附件
cosign attach sbom \
  --sbom sbom.spdx.json \
  --type spdx \
  ghcr.io/myorg/myimage:v1.0.0

# 签名附件
cosign sign \
  --key cosign.key \
  --yes \
  --attachment sbom \
  ghcr.io/myorg/myimage:v1.0.0

5.7.3 签名时附加漏洞报告

# 生成漏洞报告
grype ghcr.io/myorg/myimage:v1.0.0 -o json > vuln-report.json

# 附加漏洞报告
cosign attest \
  --key cosign.key \
  --yes \
  --predicate vuln-report.json \
  --type vuln \
  ghcr.io/myorg/myimage:v1.0.0

5.8 签名策略配置

5.8.1 cosign 签名策略

# 签名策略示例 (policy.yaml)
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
  name: require-signed-images
spec:
  images:
    - glob: "ghcr.io/myorg/**"
    - glob: "gcr.io/myproject/**"
  authorities:
    - key:
        data: |
          -----BEGIN PUBLIC KEY-----
          MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
          -----END PUBLIC KEY-----
    - keyless:
        url: https://fulcio.sigstore.dev
        identities:
          - issuer: https://token.actions.githubusercontent.com
            subject: https://github.com/myorg/myrepo/.github/workflows/build.yml

5.8.2 签名验证策略

# 使用策略验证
cosign verify \
  --policy policy.yaml \
  ghcr.io/myorg/myimage:v1.0.0

# 使用 Rego 策略验证
cosign verify \
  --policy policy.rego \
  ghcr.io/myorg/myimage:v1.0.0

5.9 签名流程最佳实践

5.9.1 推荐签名流程

┌─────────────────────────────────────────────────────────────────┐
│                    推荐的签名流程                                │
│                                                                 │
│  1. 开发阶段                                                    │
│     └─ 使用 cosign generate-key-pair 生成测试密钥              │
│                                                                 │
│  2. CI/CD 阶段                                                  │
│     ├─ 使用无密钥签名(GitHub Actions / GitLab CI)            │
│     ├─ 自动上传签名到 Rekor                                    │
│     └─ 附加 SBOM 和漏洞报告                                    │
│                                                                 │
│  3. 发布阶段                                                    │
│     ├─ 使用 KMS 签名生产镜像                                   │
│     ├─ 要求多签名(审批流程)                                   │
│     └─ 验证所有签名和 Rekor 记录                               │
│                                                                 │
│  4. 部署阶段                                                    │
│     ├─ 验证镜像签名                                            │
│     ├─ 检查 Rekor 包含证明                                     │
│     └─ 验证证书身份和颁发者                                    │
└─────────────────────────────────────────────────────────────────┘

5.9.2 签名策略对比

策略 适用场景 优点 缺点
仅密钥签名 小团队 简单 密钥管理负担
密钥 + Rekor 中型团队 可审计 仍需密钥管理
无密钥签名 开源项目 无密钥管理 依赖 OIDC 提供者
KMS + 无密钥 企业 最高安全性 配置复杂
多重签名 高安全需求 防止单点失败 流程复杂

5.10 注意事项

无密钥签名的证书有效期:Fulcio 颁发的证书只有 10 分钟有效期。但这不影响签名的长期有效性,因为签名本身和证书都记录在 Rekor 中。

OIDC 依赖:无密钥签名依赖于 OIDC 提供者。如果 OIDC 提供者出现问题,签名流程会受影响。

时钟同步:签名和验证过程中需要准确的时间。确保服务器时钟同步(NTP)。

速率限制:公共 Fulcio 和 Rekor 实例有速率限制。企业环境应考虑私有部署。


5.11 本章小结

方式 适用场景 密钥管理 Rekor 集成
传统密钥签名 本地开发 长期密钥 手动 / 自动
KMS 签名 企业环境 云 KMS 自动
无密钥签名 CI/CD 自动
多重签名 高安全需求 多密钥 自动

扩展阅读


下一章06 - 验证机制 — 深入了解签名验证、日志验证、包含证明和批量验证。