pixi-sbom¶
A pixi extension that writes a Software Bill of Materials from a lockfile: every conda and PyPI
package of one environment on one platform, with purls, licenses and the dependency graph, as
CycloneDX 1.6 / 1.7 or SPDX 2.3 / 3.0.1 JSON that validates against the
official schemas. It reads pixi.lock, uv.lock, pylock.toml, poetry.lock, pdm.lock, conda-lock.yml and
explicit conda specs, or an installed conda environment or venv, and needs neither an installed environment nor pixi
itself: a uv or Poetry project runs it as uvx pixi-sbom (Using pixi-sbom without pixi).
pixi global install pixi-sbom
pixi sbom # sbom.cdx.json next to pixi.lock
pixi sbom --output - | grype # straight into a scanner
pixi sbom --fetch-licenses --deny-license GPL-3.0-only --require-license # a license gate, exit 3 on violation
Where to go¶
-
pixi global, a release binary, or a build from source; how pixi finds the extension.
-
Every option, the license policy, terminal reports, batch mode, environment variables, exit codes and error codes.
-
uses: millsks/pixi-sbom@v1: inputs, outputs, the policy gate, a worked example. -
Scanning with grype, license tables in PR comments, diffing SBOMs between commits, air-gapped runners.
-
CycloneDX 1.6 / 1.7 against SPDX 2.3 / 3.0.1, by consumer.
-
Field by field: purls, licenses, the dependency graph, reproducibility.
Why a lockfile-based SBOM¶
Pixi environments mix conda and PyPI packages, and scanners have no conda vulnerability data: a conda-only Python
environment scans as clean no matter what it contains. pixi sbom gives conda-forge Python packages their PyPI
identity from the same mapping pixi uses, fetches licenses for every package kind from the package cache, the channel
archive or the wheel, and produces byte-identical documents under SOURCE_DATE_EPOCH so CI can diff them.
Contributors: the architecture and development pages describe the pipeline, the modules and the change harness. Releases are listed in the changelog.