Skip to content

rtbot-dev/rules_sbom

Repository files navigation

rules_sbom

Release CI License Bazel

rules_sbom provides Bazel rules for generating Software Bill of Materials (SBOM) artifacts from Bazel targets using best-in-class external tooling.

The rules are production-ready and currently power SBOM generation in real workloads. They ship reproducible CycloneDX documents that track the dependencies that actually ship with your services as well as full workspace inventories.

Capabilities

  • Service-level SBOMs: point sbom_artifact at a single Bazel target (for example a binary, image, or library bundle) to enumerate only the artifacts that deploy with that unit.
  • Workspace-level SBOMs: aggregate manifests and lockfiles across the repository to emit a global view of every resolved dependency.
  • JavaScript and pnpm monorepos: the Syft wrapper synthesizes scoped package.json and lockfiles for each target, disables noisy catalogers, and can also ingest workspace-level node modules so you can switch between per-service and whole-repo reports.
  • Bundled Syft toolchain: pre-built binaries for macOS, Linux, and Windows ensure consistent output in CI and on developer machines.

Getting started

  1. Add the dependency in MODULE.bazel. Until this module lands in the Bazel Central Registry, pin the GitHub release with this override snippet:
    bazel_dep(name = "rules_sbom", version = "0.5.1")  # x-release-please-version
    
    archive_override(
        module_name = "rules_sbom",
        urls = ["https://github.com/rtbot-dev/rules_sbom/archive/refs/tags/v0.5.1.tar.gz"],  # x-release-please-version
        strip_prefix = "rules_sbom-0.5.1",  # x-release-please-version
        sha256 = "011146723a36380e907548defc9ed352bbe22d2ddc7ac320cede4162ad9dd89e",
    )
    Update the version and checksum whenever you move to a newer release.
  2. Provision the bundled Syft toolchain with built-in defaults:
    sbom_ext = use_extension("@rules_sbom//sbom:extensions.bzl", "sbom_setup")
    
    register_toolchains(
        "@rules_sbom//toolchains/syft:darwin_amd64_toolchain",
        "@rules_sbom//toolchains/syft:darwin_arm64_toolchain",
        "@rules_sbom//toolchains/syft:linux_amd64_toolchain",
        "@rules_sbom//toolchains/syft:linux_arm64_toolchain",
        "@rules_sbom//toolchains/syft:windows_amd64_toolchain",
    )
    The extension preinstalls Syft for macOS (amd64/arm64), Linux (amd64/arm64), and Windows (amd64) with default SHA256 sums. To customize the download set, create a small wrapper extension that calls rules_sbom_setup(..., platforms=[...], version="...", register_toolchains = False) and register the desired toolchains explicitly.
  3. Define SBOM targets:
    load("@rules_sbom//sbom:defs.bzl", "sbom_artifact")
    
    sbom_artifact(
        name = "my_binary_sbom",
        target = "//service:binary",
    )

The docs/ directory contains more detailed usage and toolchain notes (including Windows testing via Parallels CLI).

Generating SBOMs

Service-level SBOMs

The simplest configuration points sbom_artifact at the Bazel target you ship. The rule stages that target's runfiles, injects any language-specific metadata (for example package.json, go.mod, or requirements.txt), and hands the curated bundle to Syft:

load("@rules_sbom//sbom:defs.bzl", "sbom_artifact")

sbom_artifact(
    name = "payment_service_sbom",
    target = "//services/payment:binary",
)

Workspace-level SBOMs

To capture a global view, wrap the manifests, lockfiles, and other workspace inputs you care about in a filegroup, then ask sbom_artifact to process that group:

load("@rules_sbom//sbom:defs.bzl", "sbom_artifact")

filegroup(
    name = "workspace_inputs",
    srcs = [
        "//:requirements.txt",
        "//:poetry.lock",
        "//:go.mod",
        "//:go.sum",
    ],
)

sbom_artifact(
    name = "workspace_sbom",
    target = ":workspace_inputs",
)

This pattern works for any combination of languages—add whatever manifests make sense for your repository.

JavaScript and pnpm workspaces

JavaScript targets receive additional handling so you can switch between service and workspace scopes without manual staging:

  • Service SBOMs: point sbom_artifact at the Bazel binary (for example a js_binary). The wrapper reduces the runfiles to the service's published assets, synthesizes a scoped package.json/package-lock.json, and disables unrelated catalogers so the SBOM contains only the dependencies that ship with that service.

  • Workspace SBOMs: collect the node workspace inputs and hand them to sbom_artifact for a holistic view:

    load("@rules_sbom//sbom:defs.bzl", "sbom_artifact")
    
    filegroup(
        name = "pnpm_workspace_inputs",
        srcs = [
            "//:node_modules",
            "//:package.json",
            "//:pnpm-lock.yaml",
        ],
    )
    
    sbom_artifact(
        name = "pnpm_workspace_sbom",
        target = ":pnpm_workspace_inputs",
    )

Both modes produce CycloneDX documents tailored to pnpm monorepos without cross-service dependency bleed.

Examples

Each example maps directly onto the service-level recipe above; combine the manifests you need to produce a workspace-level SBOM.

Release workflow

Releases are automated with Release Please. Conventional commits drive the next version:

  • feat: bumps the minor version while we are pre-1.0.
  • fix: (or other non-feature commits) bumps the patch version.
  • Commits with BREAKING CHANGE: or a ! trigger a major bump.

Once changes land on main, the GitHub action opens a release PR. Merging that PR tags vX.Y.Z, publishes the GitHub release, and the Verify Release Tag workflow confirms that the tag matches the version declared in MODULE.bazel.

If you need to double-check a release manually, re-run the Release Please workflow from the Actions tab; it will only open a new PR when there are user-facing commits since the last tag.

Use bazel sync after upgrading to ensure the Syft toolchain archives download for your host platform; this refreshes the Syft binaries for the host OS/architecture and avoids stale CLI binaries across machines.

Every published release now includes ready-to-copy install snippets (Bzlmod and WORKSPACE) directly in the GitHub release notes for easy onboarding. If you need to pin Syft to a different version, call rules_sbom_setup(..., version="<syft_version>") from a custom module extension or in your WORKSPACE.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •