Add a GET /api/sbom endpoint that emits the proxy's cached package inventory as a CycloneDX or SPDX document.
The database already has everything a CycloneDX component needs: purl, SPDX-normalised license, supplier, repository URL, content hash, size, and vulnerabilities (internal/database/types.go). The git-pkgs/sbom module provides sbom.New() / sbom.AddPackage() / sbom.Encode() for both CycloneDX (JSON, XML) and SPDX JSON with no extra dependencies, so this is mostly a query-and-map job.
Query parameters:
format — cyclonedx-json (default), cyclonedx-xml, spdx-json
ecosystem — optional filter, e.g. npm
cached — when true, only include versions with a cached artifact (so hashes are populated)
Vulnerabilities from the vulnerabilities table can go into the CycloneDX vulnerabilities block when the format supports it (1.4+).
This is the inverse of proxy mirror --sbom and the open-source equivalent of JFrog Xray's component/exportDetails and Sonatype Lifecycle's /api/v2/cycloneDx/{version}/{appId} endpoints.
UI: a "Download SBOM" button on the packages list page (internal/server/templates/pages/packages_list.html) that hits this endpoint with the current ecosystem filter applied, plus an unfiltered one on the dashboard.
Add a
GET /api/sbomendpoint that emits the proxy's cached package inventory as a CycloneDX or SPDX document.The database already has everything a CycloneDX component needs: purl, SPDX-normalised license, supplier, repository URL, content hash, size, and vulnerabilities (
internal/database/types.go). Thegit-pkgs/sbommodule providessbom.New()/sbom.AddPackage()/sbom.Encode()for both CycloneDX (JSON, XML) and SPDX JSON with no extra dependencies, so this is mostly a query-and-map job.Query parameters:
format—cyclonedx-json(default),cyclonedx-xml,spdx-jsonecosystem— optional filter, e.g.npmcached— when true, only include versions with a cached artifact (so hashes are populated)Vulnerabilities from the
vulnerabilitiestable can go into the CycloneDXvulnerabilitiesblock when the format supports it (1.4+).This is the inverse of
proxy mirror --sbomand the open-source equivalent of JFrog Xray'scomponent/exportDetailsand Sonatype Lifecycle's/api/v2/cycloneDx/{version}/{appId}endpoints.UI: a "Download SBOM" button on the packages list page (
internal/server/templates/pages/packages_list.html) that hits this endpoint with the current ecosystem filter applied, plus an unfiltered one on the dashboard.