Skip to content

feat(sbom): add SBOM generation, license resolution, and CSV export tooling#239

Merged
johntmyers merged 4 commits intomainfrom
feat/237-sbom-tooling/jomyers
Mar 11, 2026
Merged

feat(sbom): add SBOM generation, license resolution, and CSV export tooling#239
johntmyers merged 4 commits intomainfrom
feat/237-sbom-tooling/jomyers

Conversation

@johntmyers
Copy link
Copy Markdown
Collaborator

@johntmyers johntmyers commented Mar 11, 2026

Summary

  • Add a mise-integrated SBOM pipeline (mise run sbom) that generates CycloneDX SBOMs for all container images using Syft, resolves missing/hash-based licenses via crates.io/npm/PyPI APIs, and exports CSV reports to deploy/sbom/output/
  • Add mise run notices to generate THIRD-PARTY-NOTICES with full license texts for open-source attribution compliance, using cargo-about (Rust) and pip-licenses (Python)
  • Include sbom:check subtask for future PR CI integration (advisory-only, non-blocking)
  • Add agent skill (.agents/skills/sbom/SKILL.md) for on-demand SBOM operations

Details

New files

File Purpose
deploy/sbom/resolve_licenses.py Queries crates.io, npm, PyPI APIs + known Go/Debian license maps to resolve missing and hash-based licenses (~94% resolution rate). Uses concurrent requests (12 workers) with per-domain rate limiting.
deploy/sbom/sbom_to_csv.py Converts CycloneDX JSON SBOMs to CSV with columns: name, version, type, licenses, purl
tasks/sbom.toml Mise task definitions — sbom (orchestrator), sbom:generate, sbom:resolve, sbom:csv, sbom:check
tasks/notices.toml Mise task definition for notices
about.toml cargo-about configuration with accepted SPDX license list
.agents/skills/sbom/SKILL.md Agent skill for SBOM generation, license audit, and CSV export

Modified files

File Change
mise.toml Added ubi:anchore/syft and ubi:EmbarkStudios/cargo-about tools, updated python_paths to include deploy/sbom/*.py
.gitignore Added deploy/sbom/output/ (generated CSVs are not committed)
scripts/generate_third_party_notices.py Rewritten to use cargo-about (Rust) and pip-licenses (Python) for full license text extraction
THIRD-PARTY-NOTICES Regenerated with full license texts — 566 Rust packages across 133 license groups + 19 Python packages (15,986 lines)

Design decisions

  • Syft chosen as SBOM scanner (Apache-2.0, widely adopted, CycloneDX JSON output)
  • cargo-about for Rust attribution — extracts actual LICENSE files with per-package copyright notices
  • pip-licenses for Python attribution — fetched on-demand via uv run --with
  • SBOMs are release artifacts — generated on demand, not committed to repo
  • THIRD-PARTY-NOTICES is committed — checked into repo root for compliance visibility
  • Syft excludes .github/, .venv/, .cache/ to avoid dev artifact noise
  • Private packages (@openclaw/*, opencode-*, pi-extension-*) are accepted as unresolved gaps for now
  • sbom:check is advisory-only to avoid blocking PRs on transient API failures
  • Concurrent license resolution (12 workers) with thread-safe per-domain rate limiting

Testing

  • mise run pre-commit passes
  • mise run sbom generates SBOM, resolves licenses, exports CSV end-to-end
  • mise run notices generates THIRD-PARTY-NOTICES with full license texts (43s)
  • Prototype validated against 6 NVIDIA container image SBOMs (751/801 missing licenses resolved)

Closes #237

…ooling

Add mise-integrated SBOM pipeline for container images using Syft.
Includes license resolution via crates.io/npm/PyPI APIs and CycloneDX
JSON to CSV conversion. Adds agent skill for on-demand SBOM operations.

Closes #237
…ith full license texts

Use cargo-about for Rust crate licenses and pip-licenses for Python
packages. Produces a single attribution file with per-package copyright
notices and full license text for open-source compliance.
@johntmyers johntmyers requested a review from drew March 11, 2026 22:29
@johntmyers johntmyers merged commit a05ef3f into main Mar 11, 2026
10 checks passed
@johntmyers johntmyers deleted the feat/237-sbom-tooling/jomyers branch March 11, 2026 22:34
drew pushed a commit that referenced this pull request Mar 16, 2026
…ooling (#239)

* feat(sbom): add SBOM generation, license resolution, and CSV export tooling

Add mise-integrated SBOM pipeline for container images using Syft.
Includes license resolution via crates.io/npm/PyPI APIs and CycloneDX
JSON to CSV conversion. Adds agent skill for on-demand SBOM operations.

Closes #237

* fix(sbom): chain task dependencies to run generate → resolve → csv sequentially

* fix(sbom): add concurrent license resolution, progress logging, and exclude dev artifacts

* feat(notices): add mise run notices to generate THIRD-PARTY-NOTICES with full license texts

Use cargo-about for Rust crate licenses and pip-licenses for Python
packages. Produces a single attribution file with per-package copyright
notices and full license text for open-source compliance.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add SBOM generation and license resolution tooling

2 participants