L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Déploiement et opérations · SKILL.md

implementing-image-provenance-verification-with-cosign

implementing-image-provenance-verification-with-cosign

使用 Sigstore Cosign 进行容器镜像来源签名与验证,支持基于 OIDC 的无密钥签名、证明附件及 Kubernetes 准入强制执行。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: implementing-image-provenance-verification-with-cosign description: 使用 Sigstore Cosign 进行容器镜像来源签名与验证,支持基于 OIDC 的无密钥签名、证明附件及 Kubernetes 准入强制执行。 domain: cybersecurity subdomain: container-security tags: [cosign, sigstore, image-signing, supply-chain, provenance, keyless, slsa] version: "1.0" author: mahipal license: Apache-2.0

使用 Cosign 实施镜像来源验证

概述

Cosign 是 Sigstore 工具集中用于对容器镜像和 OCI 制品进行签名、验证和附加元数据的工具。它同时支持基于密钥和无密钥(OIDC)两种签名方式,集成了 Fulcio(证书颁发机构)和 Rekor(透明日志),为容器镜像提供供应链安全保障。

前提条件

  • 已安装 Cosign CLI
  • 用于构建镜像的 Docker 或 Podman
  • 符合 OCI 规范的容器仓库(Docker Hub、GHCR、GCR、ECR)
  • 用于无密钥签名的 OIDC 提供商账号(GitHub、Google、Microsoft)

安装 Cosign

# 通过 Go 安装
go install github.com/sigstore/cosign/v2/cmd/cosign@latest

# 通过 Homebrew 安装
brew install cosign

# 通过脚本安装
curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64"
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
sudo chmod +x /usr/local/bin/cosign

# 验证安装
cosign version

基于密钥的签名

生成密钥对

# 生成 cosign 密钥对(创建 cosign.key 和 cosign.pub)
cosign generate-key-pair

# 生成存储在 KMS 中的密钥对
cosign generate-key-pair --kms awskms:///alias/cosign-key
cosign generate-key-pair --kms gcpkms://projects/PROJECT/locations/LOCATION/keyRings/KEYRING/cryptoKeys/KEY
cosign generate-key-pair --kms hashivault://transit/keys/cosign

使用密钥签名镜像

# 签名镜像
cosign sign --key cosign.key ghcr.io/myorg/myapp:v1.0.0

# 添加注解签名
cosign sign --key cosign.key \
  -a "build-id=12345" \
  -a "git-sha=$(git rev-parse HEAD)" \
  ghcr.io/myorg/myapp:v1.0.0

使用密钥验证镜像

# 验证签名
cosign verify --key cosign.pub ghcr.io/myorg/myapp:v1.0.0

# 带注解检查的验证
cosign verify --key cosign.pub \
  -a "build-id=12345" \
  ghcr.io/myorg/myapp:v1.0.0

无密钥签名(OIDC)

无密钥签名(交互式)

# 无密钥签名 - 打开浏览器进行 OIDC 认证
cosign sign ghcr.io/myorg/myapp:v1.0.0

# 签名、证书和 Rekor 条目将自动创建

无密钥签名(CI/CD - 非交互式)

# GitHub Actions(自动使用 OIDC 令牌)
cosign sign ghcr.io/myorg/myapp:v1.0.0 \
  --yes

# 使用显式身份令牌
cosign sign ghcr.io/myorg/myapp:v1.0.0 \
  --identity-token=$(cat /var/run/sigstore/cosign/oidc-token) \
  --yes

验证无密钥签名

# 通过邮件身份验证
cosign verify ghcr.io/myorg/myapp:v1.0.0 \
  --certificate-identity=builder@example.com \
  --certificate-oidc-issuer=https://accounts.google.com

# 通过 GitHub Actions 工作流验证
cosign verify ghcr.io/myorg/myapp:v1.0.0 \
  --certificate-identity=https://github.com/myorg/myrepo/.github/workflows/build.yml@refs/heads/main \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com

# 使用正则匹配验证
cosign verify ghcr.io/myorg/myapp:v1.0.0 \
  --certificate-identity-regexp=".*@example.com" \
  --certificate-oidc-issuer=https://accounts.google.com

证明(SLSA 来源)

附加 SBOM 证明

# 生成 SBOM
syft ghcr.io/myorg/myapp:v1.0.0 -o cyclonedx-json > sbom.cdx.json

# 将 SBOM 作为证明附加
cosign attest --key cosign.key \
  --type cyclonedx \
  --predicate sbom.cdx.json \
  ghcr.io/myorg/myapp:v1.0.0

# 验证证明
cosign verify-attestation --key cosign.pub \
  --type cyclonedx \
  ghcr.io/myorg/myapp:v1.0.0

附加漏洞扫描证明

# 运行扫描并保存结果
grype ghcr.io/myorg/myapp:v1.0.0 -o json > vuln-scan.json

# 将扫描结果作为证明附加
cosign attest --key cosign.key \
  --type vuln \
  --predicate vuln-scan.json \
  ghcr.io/myorg/myapp:v1.0.0

SLSA 来源证明

# 附加 SLSA 来源
cosign attest --key cosign.key \
  --type slsaprovenance \
  --predicate provenance.json \
  ghcr.io/myorg/myapp:v1.0.0

# 验证 SLSA 来源
cosign verify-attestation --key cosign.pub \
  --type slsaprovenance \
  ghcr.io/myorg/myapp:v1.0.0

CI/CD 集成

GitHub Actions

name: Sign and Publish
on:
  push:
    tags: ['v*']

permissions:
  contents: read
  packages: write
  id-token: write  # 无密钥签名所需

jobs:
  build-sign:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: sigstore/cosign-installer@v3

      - name: 登录到 GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: 构建并推送
        id: build
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}

      - name: 签名镜像(无密钥)
        run: |
          cosign sign --yes \
            ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

      - name: 生成并附加 SBOM
        run: |
          syft ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }} -o cyclonedx-json > sbom.json
          cosign attest --yes \
            --type cyclonedx \
            --predicate sbom.json \
            ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

Kubernetes 准入强制执行

Policy Controller(Sigstore)

# 安装 policy-controller
helm repo add sigstore https://sigstore.github.io/helm-charts
helm install policy-controller sigstore/policy-controller \
  --namespace cosign-system --create-namespace
# 在命名空间强制要求签名镜像
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
  name: require-signed-images
spec:
  images:
    - glob: "ghcr.io/myorg/**"
  authorities:
    - keyless:
        url: https://fulcio.sigstore.dev
        identities:
          - issuer: https://token.actions.githubusercontent.com
            subjectRegExp: "https://github.com/myorg/.*"
      ctlog:
        url: https://rekor.sigstore.dev

Kyverno 集成

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  validationFailureAction: Enforce
  rules:
    - name: verify-cosign-signature
      match:
        any:
          - resources:
              kinds: ["Pod"]
      verifyImages:
        - imageReferences:
            - "ghcr.io/myorg/*"
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/myorg/*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: https://rekor.sigstore.dev

透明日志(Rekor)

# 在 Rekor 中搜索镜像签名
rekor-cli search --email builder@example.com

# 获取特定条目
rekor-cli get --uuid <entry-uuid>

# 验证条目包含情况
cosign verify ghcr.io/myorg/myapp:v1.0.0 \
  --certificate-identity=builder@example.com \
  --certificate-oidc-issuer=https://accounts.google.com

最佳实践

  1. 在 CI/CD 自动化流水线中使用无密钥签名
  2. 按摘要签名而非按标签签名,以确保引用的不可变性
  3. 在签名旁边附加 SBOM 证明
  4. 使用 policy-controller 或 Kyverno 在准入阶段强制签名验证
  5. 使用 OIDC 身份验证代替单纯的密钥验证
  6. 对于基于密钥的签名,将密钥存储在 KMS 中(AWS KMS、GCP KMS、HashiCorp Vault)
  7. 验证完整信任链:签名 + 证书 + Rekor 包含情况
  8. 在签名上以注解形式包含构建元数据
Skills enregistrées