# Implementing Code Signing For Artifacts

> 本技能涵盖为构建产物实施代码签名，以确保软件供应链中的完整性和真实性。 内容包括使用 GPG、Sigstore 和平台专用签名工具对二进制文件、软件包和容器进行签名， 建立信任链，以及在部署管道中验证签名。

- Skill: `killvxk/implementing-code-signing-for-artifacts` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add killvxk/implementing-code-signing-for-artifacts`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/implementing-code-signing-for-artifacts/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/implementing-code-signing-for-artifacts

---


# 为构建产物实施代码签名

## 使用场景

- 建立产物完整性验证以防止供应链篡改时
- 合规要求需要密码学证明构建产物真实且未被修改时
- 向需要验证发布者身份的客户分发软件时
- 实施零信任部署管道以拒绝未签名产物时
- 满足 SLSA Level 2+ 的来源和完整性要求时

**不适用于**加密产物（签名提供完整性，而非保密性）、专门用于容器镜像签名（使用 cosign）或源代码身份验证（使用提交签名）。

## 前置条件

- 用于传统签名的 GPG 密钥对，或用于无密钥签名的 Sigstore 账号
- 来自证书颁发机构的代码签名证书（用于公开发布）
- 能够访问签名密钥或身份提供者的 CI/CD 管道
- 部署管道中的验证基础设施

## 操作流程

### 步骤 1：生成和管理签名密钥

```bash
# 生成用于产物签名的 GPG 密钥
gpg --full-generate-key --batch <<EOF
Key-Type: eddsa
Key-Curve: ed25519
Subkey-Type: eddsa
Subkey-Curve: ed25519
Name-Real: CI Build System
Name-Email: ci-signing@company.com
Expire-Date: 1y
%no-protection
EOF

# 导出公钥用于分发
gpg --armor --export ci-signing@company.com > signing-key.pub

# 导出私钥用于 CI/CD（存储在密钥管理器中）
gpg --armor --export-secret-keys ci-signing@company.com > signing-key.priv
```

### 步骤 2：在 CI/CD 中签名构建产物

```yaml
# .github/workflows/build-sign.yml
name: Build and Sign

on:
  push:
    tags: ['v*']

jobs:
  build-sign:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      id-token: write  # 用于 Sigstore 无密钥签名
    steps:
      - uses: actions/checkout@v4

      - name: Build artifacts
        run: |
          make build
          sha256sum dist/* > dist/checksums.sha256

      - name: Import GPG Key
        run: |
          echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import
          gpg --list-secret-keys

      - name: Sign artifacts
        run: |
          for file in dist/*; do
            gpg --detach-sign --armor --local-user ci-signing@company.com "$file"
          done

      - name: Install cosign for keyless signing
        uses: sigstore/cosign-installer@v3

      - name: Keyless sign with Sigstore
        run: |
          for file in dist/*.tar.gz; do
            cosign sign-blob "$file" \
              --output-signature "${file}.sig" \
              --output-certificate "${file}.cert" \
              --yes
          done

      - name: Create Release with signed artifacts
        uses: softprops/action-gh-release@v2
        with:
          files: |
            dist/*
            dist/*.asc
            dist/*.sig
            dist/*.cert
```

### 步骤 3：在部署管道中验证签名

```bash
# 验证 GPG 签名
gpg --import signing-key.pub
gpg --verify artifact.tar.gz.asc artifact.tar.gz

# 验证 Sigstore 无密钥签名
cosign verify-blob artifact.tar.gz \
  --signature artifact.tar.gz.sig \
  --certificate artifact.tar.gz.cert \
  --certificate-identity ci-signing@company.com \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

# 验证校验和
sha256sum --check checksums.sha256
```

### 步骤 4：使用来源信息签名 npm 包

```json
{
  "scripts": {
    "prepublishOnly": "npm run build && npm run test"
  },
  "publishConfig": {
    "provenance": true
  }
}
```

```bash
# 发布带来源证明的 npm 包
npm publish --provenance
```

## 关键概念

| 术语 | 定义 |
|------|------|
| 代码签名 | 对软件产物进行签名的密码学过程，用于验证发布者身份和产物完整性 |
| 分离签名 | 签名存储在与产物分离的文件中，允许独立分发 |
| 无密钥签名 | Sigstore 的方法，使用与 OIDC 身份绑定的短期证书，而非长期密钥 |
| 来源 | 描述产物构建方式、地点和构建者的元数据 |
| 透明日志 | 记录所有签名事件以供公开审计的仅追加日志（Rekor） |
| 信任链 | 从根 CA 到签名证书的层级链，建立对签名者身份的信任 |
| SLSA | 软件产物供应链级别 — 定义供应链安全级别的框架 |

## 工具与系统

- **GPG/PGP**：传统的非对称加密工具，用于签名和验证产物
- **Sigstore (cosign)**：使用 OIDC 身份和透明日志的现代无密钥签名基础设施
- **Rekor**：Sigstore 的透明日志，不可变地记录所有签名事件
- **Fulcio**：Sigstore 的证书颁发机构，颁发与 OIDC 身份绑定的短期证书
- **notation**：Microsoft 用于 OCI 镜像仓库的产物签名工具（Project Notary v2）

## 常见场景

### 场景：建立已签名的发布管道

**背景**：一个开源项目需要对发布产物进行签名，以便用户可以验证真实性并检测篡改。

**方法**：
1. 在 GitHub Actions 中使用 Sigstore 无密钥签名（无需密钥管理开销）
2. 使用 OIDC 身份通过 `cosign sign-blob` 签名所有发布二进制文件
3. 生成并签名校验和文件用于批量验证
4. 将签名、证书和校验和与发布产物一起上传
5. 在项目 README 中记录验证说明
6. 在 Homebrew formula 或 apt 仓库中添加验证步骤

**注意事项**：GPG 密钥泄露需要撤销并重新签名所有产物。Sigstore 无密钥签名通过使用短期密钥避免了这一问题。CI/CD 密钥中的长期签名密钥如果 CI 系统被入侵，将带来供应链风险。

## 输出格式

```
产物签名报告
========================
管道：Build and Sign v2.3.0
日期：2026-02-23
签名方法：Sigstore 无密钥 + GPG

已签名产物：
  app-v2.3.0-linux-amd64.tar.gz
    GPG:      通过（ci-signing@company.com，EdDSA/Ed25519）
    Sigstore: 通过（Rekor 条目：24658135，Fulcio 证书已颁发）
    SHA256:   a1b2c3d4...

  app-v2.3.0-darwin-arm64.tar.gz
    GPG:      通过
    Sigstore: 通过（Rekor 条目：24658136）
    SHA256:   e5f6g7h8...

  checksums.sha256
    GPG:      通过（分离签名）

透明日志：
  已记录条目：3
  日志索引范围：24658135-24658137
  验证：https://search.sigstore.dev
```

