In this comprehensive guide, Andrew Lock demonstrates how to generate SBOMs for .NET NuGet packages using tools like GitHub’s SBOM export, Microsoft’s sbom-tool, anchore/sbom-action, and CycloneDX, highlighting practical considerations for developers and operators.

Creating a Software Bill of Materials (SBOM) for an Open-Source NuGet Package

Author: Andrew Lock


A Software Bill of Materials (SBOM) provides a comprehensive inventory of all components, dependencies, and packages included in a software artifact, such as an application or NuGet package. With increasing attention on software supply chain security, generating and understanding SBOMs is becoming essential for both software creators and consumers. This guide walks through the necessity of SBOMs, discusses their formats, and demonstrates several tools to generate them for .NET projects.

What is a Software Bill of Materials (SBOM)?

Analogous to a manufacturer’s bill of materials, an SBOM details the raw materials and components that constitute a software product. It enumerates the various dependencies, allowing insight into security vulnerabilities, licensing compliance, and overall supply chain risk.

Two leading SBOM formats are:

Both support JSON and are widely used.

Generating SBOMs for .NET NuGet Packages: Tools and Methods

Several tools can create SBOMs for .NET applications or NuGet packages. Below are hands-on examples with the most prominent options.

1. GitHub’s Built-in SBOM Export

GitHub repositories offer an Export SBOM feature under Insights > Dependency Graph:

GitHub Export SBOM

Clicking Export SBOM produces an SPDX JSON document that lists all detected dependencies, including packages from the main project and associated test projects. This approach is simple and direct but may include more dependencies than required depending on regulatory or operational needs.

Example excerpt from SPDX SBOM export:

{
  "spdxVersion": "SPDX-2.3",
  "dataLicense": "CC0-1.0",
  ...
  "packages": [
    {"name": "Nuke.Common", "versionInfo": "8.1.0", ...},
    {"name": "StyleCop.Analyzers", "versionInfo": "1.2.0-beta.556", ...},
    {"name": "xunit", "versionInfo": "2.4.2", ...}
  ]
}

Observations

  • SPDX includes extensive metadata per package.
  • The export includes all dependency types (including test and support packages).
  • Users should verify whether non-production dependencies are appropriate for their SBOM use cases.

2. Microsoft’s Open Source sbom-tool

Microsoft’s sbom-tool generates SPDX 2.2 SBOMs and integrates with build pipelines or runs locally as a .NET global tool.

Key Features

Installation and Usage

# Install as a .NET global tool

 dotnet tool install --global Microsoft.Sbom.DotNetTool

# Run after building your packages

 sbom-tool generate \
   -b ./artifacts/packages \
   -bc ./src/ \
   -pn NetEscapades.AspNetCore.SecurityHeaders \
   -pv 1.0.0-preview.03 \
   -ps "Andrew Lock" \
   -pm
  • -b: Path to built artifacts
  • -bc: Path to associated source code
  • -pn, -pv, -ps: Package name, version, supplier
  • -pm: Parse package metadata for license info

The resulting SBOM (manifest.spdx.json) is stored in a subfolder of the build output path. The tool targets applications primarily, and some preference is given to SBOMs for entire build drops.

Observations

  • Effective, especially for applications
  • May require separate folders for each package
  • Possible lack of clarity over inclusion of development dependencies

3. GitHub Action anchore/sbom-action (Syft)

anchore/sbom-action leverages the Syft SBOM tool within GitHub Actions.

Example GitHub Actions snippet:

- uses: anchore/sbom-action@commitSHA # Use a pinned SHA for security
  with:
    path: ./artifacts/bin/NetEscapades.AspNetCore.SecurityHeaders
    output-file: ./artifacts/sboms/netescapades-aspnetcore-securityheaders.spdx.json
    upload-artifact: false
  • Uses the deps.json file for dependency discovery
  • Emphasizes reproducibility and supply chain risk mitigation (pin the commit hash)

Observations

  • Extremely verbose SPDX output
  • Simple to integrate in CI/CD pipelines
  • Favors automated processes

4. CycloneDX Module for .NET

The CycloneDX module for .NET offers CycloneDX format SBOMs. Available as a .NET global tool, it is straightforward for .NET projects.

Installation and Usage

# Install CycloneDX as a .NET tool

 dotnet tool install --global CycloneDX

# Generate SBOM

 dotnet-CycloneDX .\src\NetEscapades.AspNetCore.SecurityHeaders\NetEscapades.AspNetCore.SecurityHeaders.csproj \
   --json \
   --recursive \
   --set-name NetEscapades.AspNetCore.SecurityHeaders \
   --set-version 1.0.0-preview.03 \
   --base-intermediate-output-path .\artifacts\ \
   --output .\artifacts\sboms \
   --filename netescapades-aspnetcore-securityheaders.bom.json \
   --set-type library
  • Outputs a readable, standards-compliant CycloneDX JSON document

Observations

  • Output is concise and easier to read
  • Machine-parsing is encouraged over manual inspection

Summary and Recommendations

  • SBOMs are essential for identifying software dependencies, licensing, and supply chain risks.
  • Multiple tools support SBOM generation for .NET, each with different strengths:
    • GitHub Export: Fast, automatic, but broad in dependency scope
    • Microsoft sbom-tool: Flexible, enterprise focus, good .NET integration
    • anchore/sbom-action: Ideal for CI/CD, very verbose output
    • CycloneDX for .NET: Concise, modern format, .NET-friendly

When integrating SBOMs into development workflows, consider regulatory requirements, desired SBOM format, and the scope of dependencies to include.


Andrew Lock focuses on open source .NET development and shares practical, hands-on guides and insights for developers.

This post appeared first on “Andrew Lock’s Blog”. Read the entire article here