Quickstart: SBOM

Pencheff produces SPDX 2.3 and CycloneDX 1.5 Software Bills of Materials from any repository using the same manifest parsers that back SCA — so the SBOM is consistent with the findings list by construction, not regenerated from a different parser.

1. What gets covered

EcosystemManifest
Pythonrequirements.txt, Pipfile.lock, poetry.lock, pyproject.toml
Node.jspackage-lock.json, yarn.lock, pnpm-lock.yaml, package.json
Java / Kotlinpom.xml, build.gradle, build.gradle.kts
Gogo.sum, go.mod
RubyGemfile.lock
RustCargo.lock
.NETpackages.lock.json, *.csproj
PHPcomposer.lock
OS packagesdpkg / rpm / apk inside container scans

Each component carries name, version, purl (Package URL), license (SPDX expression where derivable), and supplier when the manifest exposes one.

2. Generate it

  1. Open any repository page.
  2. Click Generate SBOM. The SBOM generates from the latest commit on the default branch and renders in both Table and JSON views.
  3. Re-running replaces the previous SBOM. Download as JSON when you need to ship to a customer or a compliance attestation.

3. What it ties into

  • SCA finding cards link straight to the SBOM component row, so an auditor can pivot from “this CVE is in your build” to “here is the exact SBOM line item, with PURL and supplier.”
  • Compliance reports (NIST 800-53, SOC 2, ISO 27001:2022) cite the generated SBOM as the source-of-record for SR-3 / SC-12 / A.5.21 attestations.
  • GitHub Action uploads the latest SBOM as a workflow artifact alongside the findings report.
  • syft upgrade path — if syft is installed Pencheff shells out to it for richer data (transitive deps for Go / Java, better license detection). The native parsers are the fallback so air-gapped builds still work.

4. CycloneDX example

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.5",
  "serialNumber": "urn:uuid:…",
  "metadata": {
    "timestamp": "2026-04-21T...Z",
    "tools": [{
      "vendor": "pencheff",
      "name": "pencheff-sbom",
      "version": "1.0"
    }],
    "component": { "type": "application", "name": "your-repo" }
  },
  "components": [
    {
      "type": "library",
      "bom-ref": "pkg:pypi/[email protected]",
      "name": "httpx",
      "version": "0.27.0",
      "purl": "pkg:pypi/[email protected]",
      "licenses": [{ "license": { "id": "BSD-3-Clause" } }],
      "properties": [
        { "name": "pencheff:ecosystem", "value": "PyPI" },
        { "name": "pencheff:scope", "value": "runtime" }
      ]
    }
  ]
}

Repository SBOM API

POST /repos/{repo_id}/sbom   → generate (replaces previous)
GET  /repos/{repo_id}/sbom   → fetch latest

Next