ledgerprove/sign-sbom

GitHub: ledgerprove/sign-sbom

一个 GitHub Action,通过 ECDSA-P521 签名、RFC 3161 时间戳和组织级哈希链为 SBOM 提供防篡改且公开可验证的加密签名能力。

Stars: 0 | Forks: 0

# LedgerProve — sign-sbom GitHub Action [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-LedgerProve-blue?logo=github)](https://github.com/marketplace/actions/ledgerprove-sign-sbom) [![Release](https://img.shields.io/github/v/release/ledgerprove/sign-sbom?display_name=tag&sort=semver)](https://github.com/ledgerprove/sign-sbom/releases) [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE) 以加密方式对你的 SBOM 进行签名,将其追加到防篡改的哈希链中,并获取公开验证 URL —— 所有这些都在一个 CI 步骤中完成。 ## 快速开始(为你自动生成 SBOM) ``` - name: Sign SBOM with LedgerProve uses: ledgerprove/sign-sbom@v1 with: api-key: ${{ secrets.LEDGERPROVE_API_KEY }} ``` 这就是整个工作流步骤。该 Action 会安装 Syft,为你的仓库生成 CycloneDX SBOM,使用 ECDSA-P521(硬件支持、不可导出的签名密钥)对其进行签名,并打印出一个公开的验证 URL。 ## 自带 SBOM(完全控制) 如果你已经在之前的步骤中生成了 SBOM(cyclonedx-cli、自定义工具等),请显式地传入它: ``` - name: Sign SBOM with LedgerProve uses: ledgerprove/sign-sbom@v1 with: api-key: ${{ secrets.LEDGERPROVE_API_KEY }} sbom-file: ./my-sbom.json ``` ## 它的工作原理 1. 读取你的 SBOM 文件(CycloneDX 或 SPDX,JSON 格式)。 2. 使用 SHA-256 对其进行哈希处理。 3. 将哈希值和元数据 POST 到 LedgerProve 的 API。 4. API 使用位于**硬件支持的安全芯片(secure enclave)**内私有密钥的 **ECDSA-P521** 对你的记录进行签名 —— 该密钥不可导出,且永远不会离开安全区域。 5. 你的记录会被追加到按组织划分的 **SHA-512 哈希链**中 —— 篡改任何记录都会导致后续的所有记录失效。 6. 从公共 TSA 请求 **RFC 3161 时间戳**,以便任何人都能证明记录的签署时间。 7. Action 会将 `verification-url` 设置为输出,供后续步骤使用(PR 评论、发布说明等)。 任何人都可以使用一条 OpenSSL 命令在验证 URL 处验证已签名的 SBOM。无需账户。 ## 输入 | 输入 | 必填 | 默认值 | 描述 | |-------|----------|---------|-------------| | `api-key` | ✅ | — | 你的 LedgerProve API 密钥 (`lp_live_…`)。在 https://ledgerprove.com/dashboard 生成。请将其存储为仓库或组织 secret。 | | `sbom-file` | ✅ | — | SBOM JSON 文件的路径。请在之前的步骤中使用 `syft`、`cyclonedx-cli` 或你选择的工具生成它。 | | `repo-id` | — | `${{ github.repository }}` | 用于记录此构建的仓库标识符。 | | `commit-hash` | — | `${{ github.sha }}` | 要记录的 commit SHA。 | | `build-status` | — | `PASS` | `PASS`、`FAIL` 或 `WARN`。使用 `FAIL` 可记录失败的构建(例如:测试失败、发现漏洞)。 | | `cve-count` | — | `0` | 可选。要固化到签名链 payload 中的 CVE 数量。大多数用户会将其保留为 `0` —— LedgerProve 会在每次签名构建后针对 OSV.dev 运行自己的 CVE 扫描,并在你的仪表板上展示真实的发现结果。此字段专为那些希望将自己扫描器中的数量记录在签名中的调用者提供。 | | `api-url` | — | `https://api.ledgerprove.com` | 覆盖 LedgerProve API URL。仅在自托管/测试环境时设置此项。 | ## 输出 | 输出 | 描述 | |--------|-------------| | `verification-id` | 公开验证 ID(24 位十六进制) | | `verification-url` | 任何人都可以用来验证 SBOM 的公开 URL | | `signature-algorithm` | 始终为 `ECDSA-P521-SHA512` | | `chain-index` | 此记录在你组织链中的位置 | | `record-hash` | 已签名记录的 SHA-512 | | `timestamped` | 如果附加了 RFC 3161 时间戳,则为 `true` | ## 完整示例 — 对每次构建进行签名,并在 PR 上发布验证 URL ``` name: Build & Sign SBOM on: [push, pull_request] jobs: build-sign: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # 1. Generate an SBOM with Syft (works for any language / lockfile) - name: Generate SBOM uses: anchore/sbom-action@v0 with: format: cyclonedx-json output-file: sbom.json # 2. Sign and chain it with LedgerProve - name: Sign with LedgerProve id: ledgerprove uses: ledgerprove/sign-sbom@v1 with: api-key: ${{ secrets.LEDGERPROVE_API_KEY }} sbom-file: ./sbom.json # 3. Comment the verification URL on the PR - name: Comment verify URL on PR if: github.event_name == 'pull_request' uses: actions/github-script@v7 with: script: | github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: '🛡 SBOM signed: ${{ steps.ledgerprove.outputs.verification-url }}' }) ``` ## 设置 API 密钥 1. 登录 https://ledgerprove.com/login(GitHub 或 Google)。 2. 点击仪表板中的 **Generate API key**。 3. 复制 `lp_live_…` 值(仅显示一次)。 4. 在你的 GitHub 仓库(或组织)中:**Settings → Secrets and variables → Actions → New repository secret** - 名称:`LEDGERPROVE_API_KEY` - 值:粘贴你的密钥 5. 在你的工作流中使用 `${{ secrets.LEDGERPROVE_API_KEY }}`。 ## 免费计划限制 - **1 个仓库**,无限次构建。 - 每次构建均提供 ECDSA-P521 签名。 - 永久有效的公开验证链接。 如需更多仓库、CVE 提醒、SBOM diff 和团队账户,请参阅 https://ledgerprove.com/pricing。 ## 自行验证已签名的 SBOM 任何人都可以在没有 LedgerProve 账户的情况下验证记录: ``` # 1. 获取公开记录 curl -s https://api.ledgerprove.com/verify/ # 2. 下载我们的公钥 curl -sO https://api.ledgerprove.com/.well-known/public-key.pem # 3. (可选)使用 OpenSSL 验证 RFC 3161 时间戳 openssl ts -reply -in token.tsr -text ``` ## 常见问题解答 ### 这与 sigstore / cosign 有什么不同? Sigstore 通过透明日志和公共证书授权机构(Fulcio)使用无密钥签名。如果你想要零密钥管理并且不介意依赖 CA,它是一个非常合适的选择。 LedgerProve 不使用 CA。每个组织都拥有一个保存在硬件支持 KMS 内的长效 ECDSA-P521 密钥,并且记录会被追加到按组织划分的哈希链中。权衡如下: - 如果你想要带有公共透明日志的真正无密钥签名,**Sigstore 胜出** - 如果你想要无需依赖 CA、符合 FIPS 标准的加密,以及单步 CI 集成,**LedgerProve 胜出** 两者都会生成可验证的产物;只是信任模型不同。 ### 为什么选择 ECDSA-P521 而不是 Ed25519? P521 符合 FIPS-186-5 标准(这对某些客户的合规性审查很重要),而且 AWS KMS 目前已支持使用它进行签名;KMS 中的 Ed25519 尚未正式发布 (GA)。当 Ed25519 正式推出后我们会进行切换。 ### 为什么使用哈希链而不是 Merkle 树 / 透明日志? 按组织划分的哈希链在操作上更简单,并且对于单个组织的历史记录可以提供相同的防篡改属性。全局 Merkle 日志(如 Rekor)提供了跨组织的公共可审计性 —— 如果你发布被广泛使用的产物,这非常有用,但对于内部 SBOM 来说用处不大。为了 MVP,我们选择了更简单的模型。 ### 这个 Action 会将我的 SBOM 内容发送到你们的服务器吗? 不会。该 Action 会在本地计算 SBOM 的 SHA-256,并且只发送哈希值和元数据。SBOM 主体永远不会离开你的 runner。签名后的记录引用的是哈希值,而不是文件本身。(权衡:如果以后想要完全的可复现性,你需要自己保留可检索的 SBOM —— sigstore 在证明包的使用上则采取了另一种方式。) ### 如果你们的服务出现故障会怎样? 已经签名的记录将永远可以使用 `https://api.ledgerprove.com/.well-known/public-key.pem` 上的公钥进行验证。如果你在本地缓存了公钥,即使我们的 API 无法访问,你也可以使用 OpenSSL 验证签名。但新的签名操作显然会失败,直到我们恢复正常。 ### 有免费计划吗? 有的 —— 1 个仓库,无限次构建,无需信用卡。开源 Action 和公共验证端点在所有计划中都是免费的。有关付费层级(更多仓库、更长的历史记录保留时间、SBOM diff、CVE 邮件提醒),请参阅 https://ledgerprove.com/pricing。 ### 为什么提交了 `dist/` 目录? GitHub Actions 直接运行编译后的 JavaScript —— Action 在运行时没有任何安装步骤。编译后的输出必须保存在仓库中。每次更改 `src/` 中的代码时,我们都会重新构建 `dist/`。 ## 许可证 [MIT](LICENSE)。源码:https://github.com/ledgerprove/sign-sbom ## 安全 有关安全披露,请参阅 [SECURITY.md](SECURITY.md) —— 请勿通过公开的 GitHub Issues 报告安全问题。 ## 贡献 欢迎提交 PR。请先阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 了解范围和流程。 ## 问题 / 疑问 - 常规问题:https://github.com/ledgerprove/sign-sbom/issues - 讨论:https://github.com/ledgerprove/sign-sbom/discussions - 邮箱:hello@ledgerprove.com
标签:CVE, DevSecOps, GitHub Actions, SBOM, 上游代理, 合规, 安全测试工具, 密码学, 手动系统调用, 数字签名, 数据可视化, 硬件无关, 自动化攻击, 自动笔记