Richmansolom/SBOM-ATTESTATION
GitHub: Richmansolom/SBOM-ATTESTATION
面向C/C++软件的SBOM生成、签名证明与漏洞扫描一体化参考实现,支持本地执行和CI/CD流水线集成。
Stars: 0 | Forks: 2
# 软件物料清单 (SBOM) 证明
本仓库是一个可复用的参考实现,用于在 COTS 工具和项目元数据的辅助下,为 C/C++ 软件生成、验证、签名和扫描 SBOM。
## 目标
使其他工程师或团队能够克隆此仓库,将其指向自己的 C/C++ 应用程序,并生成相同类别的输出:
- CycloneDX SBOMs(感知源码/构建/容器)
- NTIA 最低要素证据(本地 + Hoppr)
- 具有可验证加密签名的已签名 SBOM
- 来自 Grype 和 Trivy 的漏洞证据(包含 DB 新鲜度工件)
- 来自 GitHub 和 GitLab 的 CI/CD 流水线工件
## 参考架构
该实现采用分阶段模型:
1. 构建目标应用程序
2. 使用 COTS 工具生成原始 SBOM
3. 使用应用程序元数据丰富 SBOM
4. 验证 SBOM 结构和 NTIA 完整性
5. 签名 SBOM 并验证签名
6. 运行漏洞扫描并生成摘要报告
7. 发布工件和日志以供审计
## 仓库结构
```
sbom-attestation/
|-- example-app/ # Reference C++ target app
| |-- src/ # C++ sources
| |-- include/ # Headers
| |-- Dockerfile # Container build path
| |-- Makefile # Native build path
| `-- app-metadata.json # Custom component metadata
|-- scripts/
| `-- sign-sbom.sh # Canonicalize + sign + embed signature
|-- sbom/ # Generated SBOM outputs and PKI artifacts
|-- reports/ # Validation, scan, and DB evidence outputs
|-- sbom_ui/
| |-- app.py # Flask API (generate/sign/scan + pipeline APIs)
| |-- requirements.txt
| `-- static/index.html # Mission Control UI frontend
|-- generate-sbom.ps1 # Local orchestrator (native/container mode)
|-- merge-sbom.ps1 # Inject custom app metadata into SBOM
|-- check-ntia.ps1 # NTIA minimum-elements check
|-- .github/workflows/sbom-pipeline.yml # GitHub Actions pipeline
|-- .gitlab-ci.yml # GitLab CI pipeline
|-- start-ui-local.ps1 # Local UI starter on port 80
`-- README.md
```
## 工具链与角色
| Tool | Role in pipeline |
|---|---|
| Syft | Primary SBOM generation for source/filesystem/container |
| CycloneDX CLI | Convert/merge/validate CycloneDX documents |
| Distro2SBOM | Distribution package SBOM coverage |
| Hoppr | NTIA profile-based SBOM validation |
| Grype | SBOM vulnerability scan + DB status evidence |
| Trivy | Secondary SBOM vulnerability scan + DB metadata |
| OpenSSL | Key generation and signature verification |
## 先决条件
本地复现的最低要求:
- PowerShell 7+
- Docker Desktop (或 Podman)
- Python 3.10+ (用于 UI 后端)
- GNU Make 和 C++ 编译器 (用于 `example-app`)
可选但推荐:
- GitHub CLI (`gh`) 用于 UI 后端中的 GitHub 流水线集成
## 快速开始(本地)
### 1) 克隆并安装 UI 依赖
```
git clone https://github.com/Richmansolom/SBOM-ATTESTATION.git
cd .\SBOM-ATTESTATION
python -m pip install -r .\sbom_ui\requirements.txt
```
### 2) 构建参考 C++ 应用程序
```
cd .\example-app
make
.\build\sbom_demo_app.exe
cd ..
```
### 3) 生成 SBOM 和证据
原生模式:
```
pwsh -ExecutionPolicy Bypass -File .\generate-sbom.ps1 -Mode native
```
容器模式:
```
pwsh -ExecutionPolicy Bypass -File .\generate-sbom.ps1 -Mode container
```
容器模式(显式 Docker 运行时):
```
pwsh -ExecutionPolicy Bypass -File .\generate-sbom.ps1 -Mode container -ContainerRuntime docker
```
Podman 模式:
```
pwsh -ExecutionPolicy Bypass -File .\generate-sbom.ps1 -Mode native -ContainerRuntime podman
```
### 4) 验证预期输出
成功运行后,请确认以下关键文件是否存在:
- `sbom/sbom-source.enriched.json`
- `sbom/pki/sbom_public_key.pem`
- `reports/cyclonedx-validate.txt`
- `reports/hoppr-ntia.log`
- `reports/grype-report.json`
- `reports/trivy-sbom-report.json`
- `reports/vulnerability-analysis.txt`
- `reports/grype-db-status.txt`
## Mission Control UI
本地运行:
```
python .\sbom_ui\app.py
```
打开:
- `http://127.0.0.1:5000`
可选的本地自定义域名:
1. 以管理员身份添加到 hosts 文件:
- `127.0.0.1 www.sbomcontrol.com`
2. 在端口 80 上启动 UI:
- `pwsh -ExecutionPolicy Bypass -File .\start-ui-local.ps1`
3. 打开:
- `http://www.sbomcontrol.com`
重要提示:
- hosts 文件映射 (`127.0.0.1 www.sbomcontrol.com`) 仅限本地使用,将该域名指向您自己的机器。
- 如果您需要公开访问,请移除该 hosts 文件条目或使用您的 GitHub Pages URL/自定义域名 DNS 设置。
- 如果该条目保留在原位,当没有本地服务器运行时,可能会导致 `ERR_CONNECTION_REFUSED`。
### 公开访问快速开始(不依赖您的 PC)
为了使 UI 能被任何人访问,请分别部署前端和后端:
1. 将 API 后端 (`sbom_ui/app.py`) 部署到 Render:
- 使用此仓库的 `render.yaml`
- 服务 URL 将类似于:`https://sbom-control-api.onrender.com`
2. 将前端 (`sbom_ui/static`) 部署到 GitHub Pages:
- 此仓库包含 `.github/workflows/pages-ui.yml`
- 在仓库设置中启用带有 GitHub Actions 的 Pages
3. 打开/分享您的 Pages URL:
- `https://.github.io//`
- 此仓库示例:`https://richmansolom.github.io/SBOM-ATTESTATION/`
当前 UI 行为:
- 在 GitHub Pages 上,前端现在默认自动指向 `https://sbom-control-api.onrender.com`。
- 如果您使用不同的后端 URL,请使用以下命令覆盖一次:
- `https://.github.io//?api=https://your-api-host`
- 该覆盖设置将保存在浏览器 localStorage (`sbom_api_base`) 中以供将来加载。
- 您也可以直接在 UI Connect 模态框中设置/更新 API Base URL(`API Base URL` 字段)。
详细步骤:参见 `FREE_HOSTING_SETUP.md`。
注意:
- 自定义域名(例如 `www.sbomcontrol.com`)需要拥有该域名并在域名注册商/DNS 托管商处配置 DNS 记录。
- Flask/本地脚本无法自行创建公共 DNS 域名。
### UI 提供者模式 (GitHub + GitLab)
UI 支持两种提供者:
- GitHub Actions 模式
- GitLab CI 模式
Connect 模态框字段:
- Provider: `github` 或 `gitlab`
- Project path: `namespace/project`
- API Base URL: 后端端点(例如 `https://sbom-control-api.onrender.com`)
- Access token: 公共读取操作可选;除非配置了后端环境令牌,否则触发操作必需
Mission Control 已实现的行为:
- GitHub 和 GitLab 流水线触发均在同一 UI 中进行 (`Pipelines -> Launch`)
- GitHub 作业日志视图,支持后端令牌回退
- GitLab 单作业流水线通过解析跟踪标记映射到逻辑阶段条带 (`Build -> Generate -> Sign -> Scan -> Report`)
- 通过 `?api=...` 和 Connect 模态框 `API Base URL` 保存 API base 覆盖设置
- Vulnerability 页面通过 `GET /api/report/unified?scanner=&source=auto` 自动从本地文件或 CI 工件拉取报告
- SBOM Viewer/Components 现在会在流水线完成时自动刷新,并可以通过 `GET /api/sbom/unified?source=auto` 从本地文件或 CI 工件拉取 SBOM JSON
- SBOM Viewer 显示 SBOM 源元数据(本地、GitHub 工件或 GitLab 工件),并在可用时附带 run/pipeline 引用
推荐的后端环境变量(Render/API 主机):
- `GITHUB_TOKEN` 用于 GitHub 触发/读取/日志流程
- `GITLAB_TOKEN` 用于 GitLab 触发/读取流程
- 可选:`GITLAB_TRIGGER_TOKEN` 用于 GitLab 触发令牌模式
## CI/CD 对等性
### GitHub
工作流:`.github/workflows/sbom-pipeline.yml`
阶段包括:
- Build
- Generate
- Sign
- Scan
- Report
### GitLab
工作流:`.gitlab-ci.yml`
实现与 GitHub 相同的逻辑阶段和工件。
## 当前实现状态
以下内容已在此仓库中实现并验证:
- **SBOM 生成:** Syft + Trivy + Distro2SBOM 通过 CycloneDX 合并,用于源码/构建目标。
- **元数据丰富:** 自定义 C/C++ 应用程序组件元数据被合并到生成的 SBOM 中。
- **验证:** CycloneDX schema 检查、本地 NTIA 检查和 Hoppr NTIA 验证已到位。
- **证明:** 基于 OpenSSL 的流程实现了嵌入式 SBOM 签名生成 + 验证。
- **漏洞分析:** Grype 和 Trivy 扫描生成 JSON/表格输出和综合摘要证据。
- **Mission Control UI:** 托管前端 + 后端 API 支持 GitHub 和 GitLab 流水线触发/监控流程。
- **已应用安全加固:** CI 支持 `SBOM_PRIVATE_KEY_PEM` 密钥注入,并排除将私钥材料上传到 CI 工件。
## 现实世界的威胁相关性
最近的 Trivy 供应链事件报告强调了一个重要观点:安全工具本身也是软件供应链的一部分,可能成为攻击目标。
- Aqua 事件公告和补救更新:[Aqua Security Trivy update](https://www.aquasec.com/blog/trivy-supply-chain-attack-what-you-need-to-know/)
- 示例下游影响报告:[BleepingComputer coverage](https://www.bleepingcomputer.com/news/security/cisco-source-code-stolen-in-trivy-linked-dev-environment-breach/)
吸取这些教训后,本仓库反映的控制措施:
- 尽可能避免在 CI 中使用可变的扫描器引用;首选固定版本。
- 将 CI 凭证/令牌视为高风险机密,并使用最小权限原则。
- 将签名密钥材料排除在工件之外;通过 CI 保护变量注入机密。
- 保留可审计的证据(验证日志、扫描输出、DB 状态)用于事件响应和证明。
## 证明与验证模型
此实现结合了多层验证:
1. CycloneDX 结构验证
2. NTIA 最低要素验证 (`check-ntia.ps1`)
3. Hoppr NTIA profile 验证
4. 签名生成和验证
5. 双重漏洞扫描器交叉检查 (Grype + Trivy)
6. 漏洞 DB 新鲜度证据捕获
## 可复现所需的工件集
如果另一个团队想要声称“实现类别相同”,他们应该生成并保留:
- 丰富后的 SBOM (`sbom-source.enriched.json`)
- 已签名 SBOM 和签名/公钥证据
- NTIA 检查输出(如果可用,为 `reports/ntia-summary.txt`)
- Hoppr 输出 (`reports/hoppr-ntia.log`, `reports/hoppr-ntia-results.json`)
- Grype 报告和 DB 状态/提供者文件
- Trivy 报告和 DB 状态/更新证据
- 综合漏洞摘要报告
## 如何将其适配到其他 C/C++ 项目
1. 将 `example-app/` 替换为您的项目路径
2. 使用以下内容更新元数据源 (`app-metadata.json`):
- supplier
- component names
- versions
- dependency relationships
3. 确保 CI 和本地脚本中的构建命令与您的构建系统匹配
4. 保持 SBOM 输出名称稳定,以保持下游工具/UI 的兼容性
5. 重新运行本地生成并确认工件集
6. 在 GitHub 和 GitLab 上运行 CI 并比较输出
## 质量门检查清单
在接受运行之前使用此检查清单:
- 构建成功
- 为预期目标生成了 SBOM
- 丰富合并正确
- CycloneDX 验证通过
- NTIA 检查通过 (脚本 + Hoppr)
- 签名验证通过
- Grype 和 Trivy 报告已生成
- DB 状态文件已生成且新鲜
- 工件已上传且可下载
## 免费托管(可选)
- 前端:GitHub Pages (`sbom_ui/static`)
- 后端 API:Render (`sbom_ui/app.py`)
有关使用 `?api=https://...` 的部署连接,请参见 `FREE_HOSTING_SETUP.md`。
## 安全说明
- 切勿提交私有签名密钥
- 在 CI 中,首选将 `SBOM_PRIVATE_KEY_PEM` 作为受保护的密钥变量注入,而不是在工件中生成新的私钥
- 对生产分支保持启用分支保护
- 对流水线触发使用最小权限令牌
- 将生成的漏洞报告视为敏感操作数据
## 数据使用和管理计划(当前流水线)
所有 SBOM 输出均被视为敏感的软件供应链记录。以下内容反映了仓库当前的行为和 CI 配置。
- **源代码权威:** GitHub (`Richmansolom/SBOM-ATTESTATION`) 是主要维护源。GitLab 通过同步更新保持一致(允许时直接推送,或受保护分支合并请求流程)。
- **SBOM 工件:** `sbom/` 下的 SBOM 文件在 GitHub Actions 和 GitLab CI 中均作为 CI 工件发布。
- **工件保留:** 当前保留期为 **7 天** (GitHub `retention-days: 7`, GitLab `expire_in: 1 week`),而非三个月。
- **漏洞报告:** Grype 和 Trivy 输出归档在 `reports/` 中(JSON 和表格/文本输出,加上 `vulnerability-analysis.txt` 以及 DB 状态/更新/提供者证据)。默认情况下目前不生成 HTML 漏洞报告。
- **加密密钥:** `scripts/sign-sbom.sh` 可以在运行时在 `sbom/pki/` 中生成 RSA 密钥对(当未提供密钥时)。CI 流水线支持通过 `SBOM_PRIVATE_KEY_PEM` 进行基于密钥的注入,并明确排除私钥工件上传。
- **凭证和令牌:** UI 将连接配置存储在浏览器 `sessionStorage` (`sbom_cfg`) 中。如果提供,令牌仅通过 `X-SBOMOKEN` 发送到此后端以进行提供者 API 调用。令牌对于公共读取操作是可选的,通常对于受保护的触发操作是必需的。
- **外部数据流:** SBOM 处理/扫描在 runner 容器中本地执行。流水线确实从上游注册表拉取漏洞数据库和容器镜像(例如 Grype DB 和 Trivy DB 源)。
- **PII 处理:** 流水线和 UI 专为软件/组件元数据设计,不会有意收集或处理个人身份信息 (PII)。
## 许可证
MIT
标签:AI合规, Angular, Attestation, BOM, C/C++, CycloneDX, DevSecOps, Docker, Flask, GitLab, Grype, NTIA, SBOM, 上游代理, 事务性I/O, 代码签名, 后端开发, 国防工业, 安全合规, 安全测试工具, 安全防御评估, 文档安全, 洛克希德马丁, 硬件无关, 结构化查询, 网络代理, 自动化安全, 请求拦截, 跌倒检测, 软件物料清单, 逆向工具