astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
28.01k stars 805 forks source link

FR: Software Bill of Materials (SBOM) output #6012

Open chrisrodrigue opened 3 months ago

chrisrodrigue commented 3 months ago

uv is in a prime position to be able to emit an SBOM that reflects the state of the current uv-managed virtual environment, or ingest an SBOM to produce a managed virtual environment.

SBOM requirements supersede any existing PEP. Executive Order 14028 demands SBOM documentation from all vendors to the US government by September 2023. It is reasonable to assume that uv may indirectly fall under this executive order if there are downstream users of uv that provide software to the US government.

It would be awesome if uv could emit an SBOM in one of the industry standard formats. CycloneDX is one such SBOM standard. I think uv may already have all the metadata necessary to output one.

SBOM support would greatly improve the security posture of uv and uv-managed projects.

kdeldycke commented 3 months ago

As hinted previously, you can use my Meta Package Manager CLI in the mean time to export the SBOM of a uv environment:

$ mpm --uv sbom --spdx                   
info: User selection of managers by priority: > uv
info: Managers dropped by user: None
info: Print SPDX export to <stdout>
info: Export packages from uv...
{
    "SPDXID": "SPDXRef-DOCUMENT",
    "creationInfo": {
        "created": "2024-08-02T23:29:10Z",
        "creators": [
            "Tool: meta-package-manager-5.18.1"
        ]
    },
    "dataLicense": "CC0-1.0",
    "name": "macOS-Darwin-23.6.0-arm64",
    "spdxVersion": "SPDX-2.3",
    "documentNamespace": "https://github.com/kdeldycke/meta-package-manager/releases/tag/v5.18.1/fdcf50b29504cc4c0df620af2283ed3",
    "packages": [
        {
            "SPDXID": "SPDXRef-pkg-uv-alabaster-0.7.16",
            "downloadLocation": "https://www.example.com",
            "externalRefs": [
                {
                    "referenceCategory": "PACKAGE_MANAGER",
                    "referenceLocator": "pkg:uv/alabaster@0.7.16",
                    "referenceType": "purl"
                }
            ],
            "filesAnalyzed": false,
            "name": "alabaster",
            "primaryPackagePurpose": "INSTALL",
            "supplier": "Organization: UV",
            "versionInfo": "0.7.16"
        },
        {
            "SPDXID": "SPDXRef-pkg-uv-arrow-1.3.0",
            "downloadLocation": "https://www.example.com",
            "externalRefs": [
                {
                    "referenceCategory": "PACKAGE_MANAGER",
                    "referenceLocator": "pkg:uv/arrow@1.3.0",
                    "referenceType": "purl"
                }
            ],
            "filesAnalyzed": false,
            "name": "arrow",
            "primaryPackagePurpose": "INSTALL",
            "supplier": "Organization: UV",
            "versionInfo": "1.3.0"
        },
...
chrisrodrigue commented 4 weeks ago

Taking a CycloneDX BOM as input could also be an awesome way to set up a venv.

Any python components in the BOM would have a PyPI purl, which uv could read and sync with pyproject.toml and the managed venv.

See related issue here regarding purl support: https://github.com/astral-sh/uv/issues/8265

sanmai-NL commented 6 days ago

@chrisrodrigue, for the sake of completeness, can you please describe alternatives, including complementary tools, that can provide this information? If standard tools can output it for various build tools, why should uv implement this?

chrisrodrigue commented 5 days ago

Well, SBOM is a standardized specification describing the dependencies of a software project. It is highly relevant in the realm of security and enables interoperability between various CI/CD tools such as vulnerability scanners.

Trivy, Harbor, and Docker are just a few examples of tools that can understand SBOMs, but these are largely focused around OCI containers.

Tools that support generating SBOMs for Python projects usually only support poetry.lock or arbitrary virtual environments, rather than uv.lock. However, the uv.lock file contains most or all of the data necessary for a minimal SBOM, but it is non-standard.

uv is the best candidate for being able to convert its own uv.lock into an SBOM, and it could ingest an SBOM to reproduce a virtual environment from an already attested set of dependencies.

zanieb commented 3 days ago

This sounds cool as a uv export format option. I don't think it's on our immediate roadmap though.

chrisrodrigue commented 3 days ago

A uv export format option sounds perfect!

Notes: The CycloneDX spec is currently at version 1.6. It supports really rich metadata, but the only required fields in an SBOM are bomFormat and bomVersion. For components, the type and name fields are minimally required. I think it would be safe to use ”library” as the default type for packages, and the package name as the name.

For each component, the minimal correct metadata to have would likely be purl and hashes (for PyPI packages), or an externalReferences array (for non-PyPI packages) with the package source URL as the url, type set to ”distribution”, and the hashes array set with alg and content for each hash. Lastly, the dependencies array is used to capture the dependency graph. I would recommended supporting at least version 1.5 of the spec.

(Could a reverse uv import option that takes an SBOM to set up a project/venv also be useful?)

zanieb commented 3 days ago

(Could a reverse uv import option that takes an SBOM to set up a project/venv also be useful?)

Yeah this would also be cool, but would need quite a bit of design. It'd also be useful for importing existing pyproject.toml from other project managers like Poetry.

If someone is interested in working on uv export format, I'm supportive of it — we just won't be working on it ourselves right now.