Generate an SPDX Software Bill of Materials for Rust crates.

Related tags

Utilities rust spdx sbom
Overview

cargo-spdx

cargo-spdx is currently in development and not yet ready for use.

cargo-spdx provides a cargo subcommand to generate an SPDX Software Bill of Materials (SBOM) for a Rust crate.

Usage

cargo spdx creates an SBOM for the current crate.

cargo spdx build wraps cargo build, producing SBOMs for each produced binary.

See cargo spdx --help for more detail.

Contributing

Anyone is welcome to contribute. You can find the list of open issues in the issue tracker, or talk with the developers on the Rust Secure Code Working Group Zulip channel. Make sure to mention cargo-spdx or to tag alilleybrinker.

License

cargo-spdx is dual-licensed with the MIT or Apache 2.0 licenses.

Comments
  • add build subcommand produces SBOMs for cargo build produced binaries

    add build subcommand produces SBOMs for cargo build produced binaries

    This adds a cargo spdx build subcommand that wraps cargo build and creates SBOMs for the produced binaries. The SBOMs are stored alongside the binary, with the same name + SPDX extension.

    It uses the cargo's json messages to detect produced binaries and the dependencies produced in the build

    This approach also extends well to getting source file information outside of cargo: cargo's messages give info about rmeta files, which we can use to navigate to the dep-info files and get a list of the Rust source files. The messages also tell us about build script execution, which we may be able to leverage for linking to non-Rust built code.

    Usage

    cargo spdx --format json -H 'https://foo.bar' build -- --all-features --message-format=json
    

    The structs in document.rs were initially generated from the SPDX schema and tweaked (to configure serde to skip serializing optional fields if None).

    The binary is added as a File information to the SBOM. All packages detected are also added, and a relationship between each package and the binary is added to show that binary depends on the package.

    Various caveats of this first iteration:

    1. Only supports executables (i.e bin target kinds, not dylib/cdylib/staticlib)
    2. Package/file information is only output for JSON/yaml formats, until kv output support for those is added
    3. build subcommand doesn't respect --force by design, but need to make that clearer through the UI.
    opened by tofay 4
  • Pick a single SBOM format to support?

    Pick a single SBOM format to support?

    4.4 of the SPDX spec says :

    Interoperability between all the supported file formats shall be preserved. SPDX defines how to validate a document in
    each supported format, and how to translate a valid document without loss to each other supported format.
    

    Does cargo-spdx need to be able to generate tag value format SBOMs? Can we initially just always output JSON SBOMs and assume that downstream tooling can handle JSON.

    The tag value format doesn't have a deserializer in Rust, so continuing with this means cargo-spdx needs to write one, which will slow down development compared to if we just focus on one of the other formats. For these we can generate Rust structs from the schema and use serde for deserialization - that would narrow it down to json/yaml.

    opened by tofay 4
  • Add file information to SBOMs

    Add file information to SBOMs

    Follows on from https://github.com/alilleybrinker/cargo-spdx/pull/9. Not worth reviewing this in detail until that's resolved.

    Read the relevant rustc/cargo dep-info files to determine the source files used in the build.

    • For dependent libraries rustc produces an rmeta file and dep-info file. The rmeta file is included in the cargo build messages, and is used to navigate to the dep_info file
    • For the binary, cargo outputs the dep-info file next to the binary: https://doc.rust-lang.org/cargo/guide/build-cache.html#dep-info-files

    These are then included in the SBOM relative to the owning package root, to avoid leaking any host specific paths into the SBOMs. A relationship is added between each file and its owning package, which is already a dependency of the binary from changes in https://github.com/alilleybrinker/cargo-spdx/pull/9.

    opened by tofay 3
  • Add support for JSON and YAML output formats

    Add support for JSON and YAML output formats

    This PR adds support for JSON and YAML output support.

    The specification for JSON/RDF/YAML differs from the tag:value format in a couple of ways that caused me to change some of the structs in document.rs.

    1. different nesting. E.g creator information is nested beneath creationInfo for the former formats but not tag:value.
    2. field names.

    If cargo-spdx is going to support multiple formats then its internal structs should probably match the JSON/RDF/YAML representation to allow integration with serde, and since SPDX has a JSON schema the structs for the unimplemented parts of the specification can be generated automatically.

    enhancement 
    opened by tofay 1
  • use Args::parse() to get better UX from clap

    use Args::parse() to get better UX from clap

    This gives a better responses when users don't specify -h or don't pass in a valid argument combinartion.

    E.g before this change, I get an error when running cargo spdx -h:

    $ cargo spdx -h
    error: cargo-spdx 0.1.0
    Generate an SPDX SBOM for a crate
    
    USAGE:
        cargo spdx [OPTIONS]
    
    OPTIONS:
        -f, --format <FORMAT>        The output format to use: 'kv' (default), 'json', 'yaml', 'rdf'
        -F, --force                  Force the output, replacing any existing file with the same name
        -h, --help                   Print help information
        -H, --host-url <HOST_URL>    The URL where the SBOM will be hosted. Must be unique for each SBOM
        -n, --no-interact            Do not run interactively
        -o, --output <OUTPUT>        The path of the desired output file
        -V, --version                Print version information
    

    After:

    $ cargo spdx -h
    cargo-spdx 0.1.0
    Generate an SPDX SBOM for a crate
    
    USAGE:
        cargo spdx [OPTIONS]
    
    OPTIONS:
        -f, --format <FORMAT>        The output format to use: 'kv' (default), 'json', 'yaml', 'rdf'
        -F, --force                  Force the output, replacing any existing file with the same name
        -h, --help                   Print help information
        -H, --host-url <HOST_URL>    The URL where the SBOM will be hosted. Must be unique for each SBOM
        -n, --no-interact            Do not run interactively
        -o, --output <OUTPUT>        The path of the desired output file
        -V, --version                Print version information
    

    Second one has color terminal support too.

    opened by tofay 0
  • Consider using https://github.com/doubleopen-project/spdx-rs?

    Consider using https://github.com/doubleopen-project/spdx-rs?

    spdx-rs claims support for serialization/deserialization of SPDX documents in formats corresponding to the json schema (JSON/yaml), and tag/value.

    @alilleybrinker should we use that in cargo-spdx?

    opened by tofay 1
  • Detecting statically linked native libraries from build scripts

    Detecting statically linked native libraries from build scripts

    Rust binaries can statically link to native libraries generated by build scripts. These libraries should be included in the SBOM.

    cargo build JSON messages can show what libraries are linked (via the linked_libs field) , and the linker search paths configured by the build script. cargo-spdx could use this to look for the linked libraries.

    Examples (from cargo build --message-format json | grep build-script of cargo-spdx itself):

    {"reason":"build-script-executed","package_id":"openssl-sys 0.9.74 (registry+https://github.com/rust-lang/crates.io-index)","linked_libs":["static=ssl","static=crypto"],"linked_paths":["native=/home/tom/.target/debug/build/openssl-sys-15856e134bacc665/out/openssl-build/install/lib"],"cfgs":["const_fn","osslconf=\"OPENSSL_NO_COMP\"","osslconf=\"OPENSSL_NO_SSL3_METHOD\"","osslconf=\"OPENSSL_NO_SEED\"","ossl101","ossl102","ossl102f","ossl102h","ossl110","ossl110f","ossl110g","ossl110h","ossl111","ossl111b","ossl111c"],"env":[],"out_dir":"/home/tom/.target/debug/build/openssl-sys-15856e134bacc665/out"}
    {"reason":"build-script-executed","package_id":"libssh2-sys 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)","linked_libs":["static=ssh2"],"linked_paths":["native=/home/tom/.target/debug/build/libssh2-sys-eb5dddeb5944716b/out/build"],"cfgs":[],"env":[],"out_dir":"/home/tom/.target/debug/build/libssh2-sys-eb5dddeb5944716b/out"}
    {"reason":"build-script-executed","package_id":"libgit2-sys 0.13.4+1.4.2 (registry+https://github.com/rust-lang/crates.io-index)","linked_libs":["static=git2"],"linked_paths":["native=/home/tom/.target/debug/build/libgit2-sys-ebe9f6f73e42c271/out/build"],"cfgs":["libgit2_vendored"],"env":[],"out_dir":"/home/tom/.target/debug/build/libgit2-sys-ebe9f6f73e42c271/out"}
    

    The out_dir typically contains the sources used to build the linked library - suspect we should include SBOM entries for all files in the out_dir.

    opened by tofay 1
  • Generate element relationship information

    Generate element relationship information

    SPDX permits specification of the relationship between elements. There's a pretty substantial list of relationship types that can be represented, and of entities that can be related. The documentation gives come examples:

    Relationship: SPDXRef-grep CONTAINS SPDXRef-make
    RelationshipComment: Package grep contains file make
    
    Relationship: SPDXRef-DOCUMENT AMENDS DocumentRef-SPDXA:SPDXRef-DOCUMENT
    RelationshipComment: This current document is an amendment of the SPDXA document.
    
    Relationship: SPDXRef-CarolCompression DEPENDS_ON NONE
    RelationshipComment: The package CarolCompression can be considered as a root with no dependencies.
    
    Relationship: SPDXRef-BobBrowser CONTAINS NOASSERTION
    RelationshipComment: The package BobBrowser may have other packages embedded in it, but the author has insufficient information to treat this as other than unknown at this point in time.
    

    We need to generate this information for files in a crate, as well as for dependencies used.

    enhancement 
    opened by alilleybrinker 1
  • Handle licenses not found in the SPDX license list with the

    Handle licenses not found in the SPDX license list with the "Other licensing information" section

    The SPDX standard includes a lengthy list of known licenses. In many cases, projects just use those licenses, and no further license specification is necessary. However, sometimes projects don't use those licenses, or claim to use them but include their own modifications. In these cases, SPDX defines a mechanism for specifying non-standard licenses.

    cargo-spdx needs to support the following:

    • [ ] Detecting when non-standard licenses are in use.
    • [ ] Producing the proper outputs in the SPDX document to represent those licenses.
    enhancement 
    opened by alilleybrinker 0
Owner
Andrew Lilley Brinker
I work on software supply chain security and build tools and libraries mostly in Rust. 🦀🏗️ "Lilley Brinker" is my last name.
Andrew Lilley Brinker
Dead simple, minimal SPDX License generator library written in Rust.

lice Dead simple, minimal SPDX License generator library written in Rust. Lice is in beta Install | User Docs | Crate Docs | Reference | Contributing

refcell.eth 9 Oct 22, 2023
A simple to use rust package to generate or parse Twitter snowflake IDs,generate time sortable 64 bits unique ids for distributed systems

A simple to use rust package to generate or parse Twitter snowflake IDs,generate time sortable 64 bits unique ids for distributed systems (inspired from twitter snowflake)

houseme 5 Oct 6, 2022
k-mer counter in Rust using the rust-bio and rayon crates

krust is a k-mer counter written in Rust and run from the command line that will output canonical k-mers and their frequency across the records in a f

null 14 Jan 7, 2023
A lean, minimal, and stable set of types for color interoperation between crates in Rust.

This library provides a lean, minimal, and stable set of types for color interoperation between crates in Rust. Its goal is to serve the same function that mint provides for (linear algebra) math types.

Gray Olson 16 Sep 21, 2022
Rust library to scan files and expand multi-file crates source code as a single tree

syn-file-expand This library allows you to load full source code of multi-file crates into a single syn::File. Features: Based on syn crate. Handling

Vitaly Shukela 11 Jul 27, 2022
Automatically cross-compiles the sysroot crates core, compiler_builtins, and alloc.

cargo-xbuild Cargo-xbuild is a wrapper for cargo build, which cross compiles the sysroot crates core, compiler_builtins, and alloc for custom targets.

Rust OSDev 241 Dec 30, 2022
A snapshot of name squatting on crates.io

Machine-readable database of public packages on crates.io which meet an arbitrary, unwritten, sensible definition of name squatting: squatted.csv Form

David Tolnay 69 Feb 1, 2023
Verify that registry crates in your Cargo.lock are reproducible from the git repository

cargo-goggles Verify that registry crates in your Cargo.lock are reproducible from the git repository. This cargo subcommand analyzes the following pr

M4SS - Industrial IoT Solutions 36 Jul 16, 2024
Rust Shop is a fake cloud-based software company that you can fork.

RustShop RustShop is an attempt at building a template and utilities to help quickly set up and manage a production grade cloud-based system. The core

null 56 Dec 17, 2022
🚧 (Alpha stage software) Binary that supports remote filesystem and process operations. 🚧

distant Binary to connect with a remote machine to edit files and run programs. ?? (Alpha stage software) This program is in rapid development and may

Chip Senkbeil 296 Dec 28, 2022
Openfare - Monetize software with one commit.

OpenFare ?? Monetize software with one commit. ?? OpenFare monetizes any software library with one code change. The goal: fund the next million softwa

null 172 Dec 2, 2022
Booru software for the 21st century. (Name is supposed to be like Puro, the big monster, but I failed..)

Pooru Booru software for the 21st century. Setup Setup is a little funky, but I hope to fix this funkyness down the road. First and foremost, you will

null 2 May 8, 2022
High-performance BitTorrent tracker compatible with UNIT3D tracker software

UNIT3D-Announce High-performance backend BitTorrent tracker compatible with UNIT3D tracker software. Usage # Clone this repository $ git clone https:/

HDInnovations 4 Feb 6, 2023
A set of bison skeleton files that can be used to generate a Bison grammar that is written in Rust.

rust-bison-skeleton A set of bison skeleton files that can be used to generate a Bison grammar that is written in Rust. Technically it's more like a B

Ilya Bylich 12 Dec 14, 2022
Rust macro that uses GPT3 codex to generate code at compiletime

gpt3_macro Rust macro that uses GPT3 codex to generate code at compiletime. Just describe what you want the function to do and (optionally) define a f

Maximilian von Gaisberg 59 Dec 18, 2022
Generate bindings to use Rust code in Qt and QML

Rust Qt Binding Generator This code generator gets you started quickly to use Rust code from Qt and QML. In other words, it helps to create a Qt based

KDE GitHub Mirror 768 Dec 24, 2022
Generate Rust register maps (`struct`s) from SVD files

svd2rust Generate Rust register maps (structs) from SVD files This project is developed and maintained by the Tools team. Documentation API Minimum Su

Rust Embedded 518 Dec 30, 2022
📝 Generate your README.md from Rust doc comments

cargo-onedoc ?? Generate README.md from doc comments. Only write your documentation once! This crate provides a Cargo subcommand that can generate Mar

Ross MacArthur 2 Dec 14, 2022
Rust library to generate word cloud images from text and images !

wordcloud-rs A Rust library to generate word-clouds from text and images! Example Code use std::collections::HashMap; use std::fs; use lazy_static::la

Teo Orthlieb 2 Dec 8, 2022