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

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 提供者

提供者身份字段说明
GoogleEmailGoogle 账号邮箱
GitHubEmail / WorkflowGitHub Actions 身份
MicrosoftEmailAzure AD / Entra ID
GitLabEmail / PipelineGitLab 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 配置表

云平台环境变量说明
AWSAWS_REGION, AWS_ACCESS_KEY_ID需要 KMS 权限
GCPGOOGLE_APPLICATION_CREDENTIALS需要 Cloud KMS 角色
AzureAZURE_TENANT_ID, AZURE_CLIENT_ID需要 Key Vault 访问权限
VaultVAULT_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 - 验证机制 — 深入了解签名验证、日志验证、包含证明和批量验证。