To generate an SBOM for a .NET project, install the CycloneDX .NET global tool, then point it at your solution or project file and choose an output folder. It writes a CycloneDX file in JSON or XML. Pointed at a solution, it aggregates every project in it into one document.
Steps
- Install the tool: dotnet tool install with the global option and the package name CycloneDX.
- If the command is not found, restart the terminal and check that the dotnet tools folder in your home directory is on your PATH.
- Run it against the solution.
dotnet-CycloneDX MyApp.sln -o ./sbom -F Json
- For a single project file, add the recursive project reference option so referenced projects are scanned too.
- Validate the output and store it with the build.
What you can point it at
Accepted inputs include solution files, C#, F# and VB project files, packages.config, and a directory. A directory is scanned recursively for packages.config files only, so a modern SDK style repo should be pointed at a solution or project file instead.
Settings worth setting on purpose
| Concern | Default | What to do |
|---|---|---|
| Output format | Auto | Choose Json explicitly if your tooling expects it |
| Spec version | 1.7 | Lower it if a downstream tool rejects the newest version |
| Test and dev packages | Included, marked with scope excluded | Skip test projects, or filter dev only packages |
| Target framework | All, aggregated | Limit to one framework if you ship one |
| Package restore | Runs | Disable only if restore already ran |
The scope marking is useful. An excluded scope tells a reader the package is not shipped, which reduces false alarms later.
The GitHub license lookup trap
The tool can look up licenses through GitHub. Unauthenticated, that is limited to 60 calls per hour, and the project says BOM generation fails if you hit the limit. Supply a token in CI or leave the lookup off. The lookup also only covers master branch license references, so treat results as a hint.
In containers
If you run the tool from its Docker image, pass your user and group IDs so restore can write to the mounted volume and output files are not owned by root.
Try it yourself
Click through it at your own pace, or open it full screen.
Check how each component shows its version and ecosystem, the same fields a NuGet package needs in an SBOM.
Quick check
Should test projects be in a shipped SBOM?
Usually not. Exclude them, or keep them marked as excluded scope so readers can tell them apart.
Why did generation fail only in CI?
A common cause is the unauthenticated GitHub license lookup hitting its hourly limit. Use a token or disable it.
Safeguard's SBOM and dependency scanning can read the CycloneDX file this produces, and a free scan is at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.