Skip to content
返回质量保障

产物签名与供应链出处(SLSA)

签构建产物并附出处元数据、使消费者可验产物由预期管道从预期源构建——非攻击者注入。

为什么

满未签产物的注册表是无强信任边界——任何看起来对的产物(同名同版)被信、能推到注册表的攻击者(经泄令牌、typosquat 包或依赖混淆攻击)可注入恶意产物消费者拉跑。产物签名闭此隙: 构建管道用开发者永不持的键签产物(经 OIDC 无键签名)、消费者拉前验签。出处更进一步: 附签证明记录确切哪个源提交、哪个工作流、哪些建输入产生产物——故消费者可验不仅'这签了吗'而是'这从我预期的源、我预期的管道建的吗'。这是 SLSA 框架(软件产物验证供应链级别): 每级加控制(L1: 出处存在、L2: 托管构建、L3: 不可伪出处)。成本几分钟管道设;益处是消除已成最常见向量危害开源生态的整类供应链攻击。

何时使用

发产物(容器、npm 包、二进制)给他人或其他系统消费时——仅内部产物可从 L1 始、公开产物应目标 L3。

如何做

1. CI 工作流中启 OIDC
   - GitHub Actions 给每 job 发 OIDC 令牌;无长期密钥管
   - 工作流加 permissions: id-token: write

2. 用无键签名签产物(Sigstore / cosign)
   - cosign sign --keyless <image>——用临时键签、证书绑 OIDC 身份
   - 签名存注册表产物旁

3. 用构建 action 生成出处
   - 用 slsa-framework/slsa-github-generator 产出出处证明
   - 证明记录: 源仓、提交 SHA、工作流路径、建输入
   - 作 cosign 证明附到产物

4. 消费侧验证
   - cosign verify --certificate-identity <workflow-ref> <image>
   - cosign verify-attestation --predicate-type slsaprovenance <image>
   - 部署管道中验证为门控: 验失败则部署中止

5. 渐进 SLSA 级
   - L1: 出处存在(生成器产它)
   - L2: 构建托管(GitHub Actions 为托管构建器)
   - L3: 出处不可伪(构建器隔离不可篡)
   - 每级为构建平台属性、非额外代码写

示例

# .github/workflows/release.yml — 无键签名 + 出处
name: release
on:
  push:
    tags: ["v*"]
permissions:
  contents: read
  id-token: write   # 无键签名所需
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t ghcr.io/$ORG/app:$GITHUB_REF_NAME .
      - run: docker push ghcr.io/$ORG/app:$GITHUB_REF_NAME
      # 无键签(无密钥管)
      - uses: sigstore/cosign-installer@v3
      - run: cosign sign --yes ghcr.io/$ORG/app:$GITHUB_REF_NAME
  provenance:
    needs: build
    uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
    with:
      image: ghcr.io/$ORG/app:$GITHUB_REF_NAME

# 消费者(部署管道)拉前验证:
# cosign verify --certificate-identity-regexp 'github.com/$ORG/.github/workflows/release.yml' \
#   ghcr.io/$ORG/app:v1.2.3

常见问题

  • ⚠用存为 CI 密钥的长期键签——密钥为单点故障: 若泄(CI 密钥常泄)、攻击者可作你项目签任意产物、签名不供信任。
  • ⚠签产物但消费侧不验——签名存注册表但每部署拉不验、故无签恶意产物被拉跑、签名白费。
  • ⚠生成出处但不查源提交——消费者验'有出处证明吗'非'出处匹配我预期源吗'、故能从恶意 fork 触发工作流的攻击者为恶意产物产有效出处。
  • ⚠把 SLSA 级当复选框非属性——声称 L3 但未用隔离不可伪构建器、故出处技术上存在但可伪、供应链保证为虚。

最佳实践

  • ✓用无键签名(cosign sign --keyless 经 OIDC)故无长期键泄——签证书绑工作流身份仅该运行有效。
  • ✓使验证为部署门控: 部署管道跑 cosign verify 失败则中止——这把签名从副作用变强控制。
  • ✓消费侧验全出处(源仓、提交 SHA、工作流 ref)非仅签名存在——这防攻击者替换产有效签恶意产物的恶意源。
  • ✓用构建平台的 SLSA 生成器 action(它免费产不可伪 L3 出处)非手写出处——框架已解难问题。