# Microsoft sbom-tool: generating and validating SPDX 2.2 and 3.0 SBOMs from build artifacts

> Microsoft's sbom-tool scans a build artifact directory and source tree to produce SPDX 2.2 or SPDX 3.0 Software Bills of Materials. It installs as a standalone binary, a dotnet global tool, or a NuGet API package, and covers the generate, validate and redact operations.

**microsoft/sbom-tool** — The SBOM tool is a highly scalable and enterprise ready tool to create SPDX 2.2 compatible SBOMs for any variety of artifacts.

- Repository: https://github.com/microsoft/sbom-tool
- Stars: 2,077 · Forks: 202
- Language: C#
- License: MIT
- Published: 2026-10-11 · Updated: 2026-10-11 · Language: en
- Canonical page: https://hysenlabs.com/projects/microsoft-sbom-tool

## sbom-tool creates a component inventory from build artifacts and source files, not just a manifest header

An SBOM that lists only top-level packages misses the transitive dependencies that determine actual risk. sbom-tool addresses this by combining two inputs: a drop path containing the files to be shipped, and a build components path pointing to the source folder. It hashes every file in the drop path and adds them to the files section of the SBOM, while simultaneously scanning the source folder for project files such as *.csproj and package.json to find what components were used during the build.

The result is an SPDX document that covers both shipped artifacts and the build graph that produced them. Generation defaults to SPDX 2.2; SPDX 3.0 output is available by passing the -mi SPDX:3.0 argument. Sample output files for both formats are available under samples/spdx_2.2/ and samples/spdx_3.0/ in the repository.

CI/CD integration is documented for GitHub Actions and Azure DevOps at docs/setting-up-github-actions.md and in the README's CI/CD integration section.

## Component detection scans project files and ClearlyDefined API resolves package metadata

Detecting what went into a build requires understanding multiple package systems. sbom-tool delegates this to the Component Detection library from microsoft/component-detection, which handles the scanning logic for supported ecosystems. The README states that component-detection scans for project files, with *.csproj and package.json given as examples, but the full list of supported component types lives in the component-detection repository.

Metadata resolution is a separate step. After detecting components, sbom-tool queries the ClearlyDefined API at clearlydefined/clearlydefined to populate package metadata for each component found. That API is an external service, which means a generate run in an air-gapped environment will produce an SBOM with components listed but without ClearlyDefined-sourced metadata.

sbom-tool is described as highly scalable and enterprise ready in its introduction, but no benchmark numbers or size limits appear in the README to define what those terms mean in practice.

## Installing on Linux, macOS or Windows and running the first generate command

On Linux, the README gives a two-command manual install:

```bash
curl -Lo sbom-tool https://github.com/microsoft/sbom-tool/releases/latest/download/sbom-tool-linux-x64
chmod +x sbom-tool
```

For macOS, use sbom-tool-osx-x64 in place of sbom-tool-linux-x64. On Windows, the preferred route is WinGet:

```shell
winget install Microsoft.SbomTool
```

Or Homebrew:

```shell
brew install sbom-tool
```

For .NET teams, a dotnet global tool is available:

```powershell
dotnet tool install --global Microsoft.Sbom.DotNetTool
```

Once installed, a generate run needs six parameters at minimum. The path given to -b is hashed file-by-file into the SBOM's files section. The -bc path is scanned for project files to find build dependencies. The -pn, -pv and -ps parameters describe the package being documented. The -nsb parameter is covered in the next section because its format has specific requirements. A full CLI reference is at docs/sbom-tool-cli-reference.md, and the arguments reference is at docs/sbom-tool-arguments.md.

## The -nsb namespace parameter requires an org-specific base URI and encodes package name and identity in the path

Every SPDX document needs a unique namespace field. sbom-tool generates this by combining the base URI from -nsb with the package name, package identifier and a newly generated GUID. The README gives a concrete example: passing https://companyName.com/teamName as -nsb produces a namespace like https://companyName.com/teamName/<packageName>/<packageVersion>/<new-guid>.

This design means the -nsb value should be consistent across an organisation so that all SBOMs from the same team share a recognisable namespace prefix. Changing the -nsb value retroactively produces SBOMs with different namespace patterns, which makes correlation harder across document sets.

The SPDX 2.2 namespace specification is at spdx.github.io/spdx-spec/v2.2.2/document-creation-information/#65-spdx-document-namespace-field, and the SPDX 3.0 format, where the namespace is part of namespaceMap, is at spdx.github.io/spdx-spec/v3.0.1/model/Core/Classes/SpdxDocument/. Both links appear in the README.

## Validate confirms an existing SBOM; Redact strips file references but only works on SPDX 2.2

Two additional subcommands address post-generation use cases. The validate subcommand takes the drop path and an output file, reads the SBOM at the expected location under that path, and writes a result. The SBOM location is not arbitrary: sbom-tool validate expects to find an SPDX 2.2 document at <drop path>\_manifest\spdx_2.2\manifest.spdx.json and an SPDX 3.0 document at <drop path>\_manifest\spdx_3.0\manifest.spdx.json. The -mi argument selects which SPDX format to validate.

The redact subcommand removes all file references from one or more SBOMs without modifying component or package information. A point stated plainly in the README: 'Currently we only support redacting SPDX 2.2 SBOMs.' The redact output directory cannot overlap with the source directory and must exist and be empty before the command runs.

There is no merge or diff subcommand documented in the README.

## The Docker runtime installs seven language runtimes and reveals the full scanning scope

The Docker install path is to clone the repository and build the image locally. The Dockerfile uses a multi-stage build: the build stage compiles the tool targeting net8.0 as a self-contained single file, and the runtime stage copies only the compiled binary.

The runtime stage installs seven packages before running the tool: python, golang, nuget, npm, cargo, ruby and maven. These are the language ecosystems the component detection library scans at runtime inside the container: Python, Go, .NET/NuGet, Node.js, Rust/Cargo, Ruby and Java/Maven. The README body mentions *.csproj and package.json as examples, but the Dockerfile gives the definitive list of what the containerised tool actually supports.

The build stage targets net8.0 while the runtime base image tag is mcr.microsoft.com/dotnet/runtime-deps:7.0.20-bullseye-slim-amd64. Because the tool is compiled as a self-contained executable, the runtime base image supplies only C library dependencies, not a .NET runtime. That tag number refers to the image build, not the required .NET framework.

## Microsoft.Sbom.Api NuGet package versus the CLI binary for programmatic integration

For teams that need to generate SBOMs from within a .NET application rather than from a CI/CD pipeline step, the NuGet package Microsoft.Sbom.Api provides the same generation logic as the CLI. The API reference is at docs/sbom-tool-api-reference.md. Installation requires adding and authenticating the Microsoft GitHub NuGet package registry, as described in the README, and then installing the Microsoft.Sbom.Api package.

The CLI binary approach is better for pipelines where SBOM generation is a one-step terminal command invoked by a build script. The API approach is better when SBOM generation needs to happen inside an existing .NET process, with the parameters driven by code.

The project is MIT-licensed. The last push to the repository was on 2026-09-21. Documentation for the contributing process is in the repository root, and security disclosures go through the SECURITY.md process.

## Conclusion

sbom-tool is the right choice for teams that need SPDX 2.2 or SPDX 3.0 compatible SBOMs from existing build artifact directories and want to integrate into GitHub Actions or Azure DevOps. Skip it when the source tree uses ecosystems outside the tool's supported set, or when SBOM redaction against SPDX 3.0 is required, since the redact command currently only handles SPDX 2.2. Before integrating into a pipeline, review the -nsb namespace parameter requirement: every generate run needs an org-specific base URI, and the resulting namespace URL pattern includes the package name, identifier and a new GUID.

## FAQ

### How do I install Microsoft sbom-tool?

On Windows, run winget install Microsoft.SbomTool. On macOS, use brew install sbom-tool. On Linux, download the sbom-tool-linux-x64 binary with curl from github.com/microsoft/sbom-tool and mark it executable. A dotnet global tool is also available via dotnet tool install --global Microsoft.Sbom.DotNetTool.

### What SPDX versions does sbom-tool support?

sbom-tool generates SPDX 2.2 by default. To generate SPDX 3.0, add the -mi SPDX:3.0 argument to the generate command. Validation handles both formats via the -mi argument. The redact command only handles SPDX 2.2.

### What is the -nsb parameter in sbom-tool generate?

The -nsb parameter sets the namespace URI base. sbom-tool appends the package name, identifier and a GUID to form the full SPDX document namespace. The README example uses https://companyName.com/teamName as the base value.

### Can sbom-tool run in an air-gapped environment?

sbom-tool uses the ClearlyDefined API to populate metadata for detected components. That API is an external service, so a generate run without network access will produce an SBOM with components listed but without ClearlyDefined metadata.

### What package ecosystems does sbom-tool scan?

The README states the tool scans for project files including *.csproj and package.json. The Docker image's runtime stage installs python, golang, nuget, npm, cargo, ruby and maven, which shows the full set of ecosystems the container supports.

## Sources

- [Issues](https://github.com/microsoft/sbom-tool/issues)
- [License: MIT](https://github.com/microsoft/sbom-tool/blob/main/LICENSE)
- [microsoft/sbom-tool on GitHub](https://github.com/microsoft/sbom-tool)
- [README](https://github.com/microsoft/sbom-tool/blob/main/README.md)
- [Releases](https://github.com/microsoft/sbom-tool/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/microsoft-sbom-tool
