Tamp.Syft 0.1.2

Prefix Reserved
dotnet add package Tamp.Syft --version 0.1.2
                    
NuGet\Install-Package Tamp.Syft -Version 0.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tamp.Syft" Version="0.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tamp.Syft" Version="0.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Tamp.Syft" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tamp.Syft --version 0.1.2
                    
#r "nuget: Tamp.Syft, 0.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tamp.Syft@0.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tamp.Syft&version=0.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Tamp.Syft&version=0.1.2
                    
Install as a Cake Tool

Tamp.Syft

Wrapper for anchore/syft — the leading OSS SBOM generator. Auto-detects 20+ package ecosystems (Rust, npm, .NET, Go, Java, Python, PHP, …) and emits CycloneDX (JSON/XML) or SPDX (JSON/tag-value) for directories, files, and container images.

Package Status
Tamp.Syft 0.1.0 (initial)

Why this exists

Microsoft Store cert pressure, federal supply-chain hygiene requirements (SLSA, CycloneDX), and increasingly common "ship me an SBOM with your release" asks from enterprise buyers all converge on the same need: every release artifact should ship with a Software Bill of Materials.

The OSS ecosystem has converged on syft as the canonical generator — Apache 2.0, single Go binary, no online dependencies, handles polyglot repos (Rust + Node + .NET + container images all in one scan). It's the recommended tool from Anchore, Microsoft's Secure Supply Chain Consumption Framework (S2C2F) reference, and is what GitHub's own anchore/sbom-action uses under the hood.

Tamp.Syft makes SBOM generation a typed step in the Tamp build graph:

  • Syft.Scan(...) for directories, files, or container images — multi-output supported (CycloneDX + SPDX from one invocation)
  • Syft.Convert(...) for format conversion (Syft↔SPDX↔CycloneDX)
  • Syft.Attest(...) for in-toto SBOM attestations uploaded to container registries (pairs with cosign for signing)
  • Syft.CatalogerList(...) for inspecting which package ecosystems syft will detect

Install

dotnet add package Tamp.Syft

Multi-targets net8 / net9 / net10. Requires Tamp.Core ≥ 1.6.0.

Tool installation

syft is a single Go binary:

Pin a specific version in CI — syft's verb shape has been stable, but pinning is the canonical move.

Quick start — scan a polyglot repo for CycloneDX + SPDX SBOMs

using Tamp;
using Tamp.Syft;

class Build : TampBuild
{
    public static int Main(string[] args) => Execute<Build>(args);

    [Parameter] readonly string Version = "1.0.6";

    [FromPath("syft")] readonly Tool SyftTool = null!;

    AbsolutePath Artifacts => RootDirectory / "artifacts";

    Target Sbom => _ => _
        .Description("[Compliance] Generate CycloneDX + SPDX SBOM for the repo")
        .Executes(() =>
        {
            Artifacts.CreateDirectory();
            return Syft.Scan(SyftTool, s => s
                .SetDirectorySource(RootDirectory)
                .SetSourceName("DasBook")
                .SetSourceVersion(Version)
                .SetSourceSupplier("Brewing Coder Software LLC")
                .AddOutputCycloneDxJson(Artifacts / $"DasBook-{Version}.cdx.json")
                .AddOutputSpdxJson(Artifacts / $"DasBook-{Version}.spdx.json")
                .AddExcludes("**/node_modules/**", "**/target/**", "**/bin/**", "**/obj/**", "**/.git/**")
                .SetQuiet());
        });
}

Run dotnet tamp Sbom --version 1.0.6 and you get DasBook-1.0.6.cdx.json + DasBook-1.0.6.spdx.json in artifacts/. Attach to the GitHub release, ship to Partner Center compliance, or upload alongside the MSIX.

What syft finds

Tested on the tamp-build/tamp repo (this project's own dogfood scan):

BOM format: CycloneDX v1.6 | components: 108 | tools: syft
ecosystems detected: 18 nuget, 8 github, 8 maven (+ test-tooling)

For a Tauri-based desktop project like DasBook, expect a similar mix — Rust crates (Cargo.lock), npm packages (package-lock.json), .NET dependencies (packages.lock.json), and embedded transitive build tooling.

Verb surface

syft scan

Setter Effect
SetDirectorySource(path) dir:<path> — scan a directory tree
SetFileSource(path) file:<path> — scan a single file (jar, msix, container archive)
SetImageSource(image) bare image ref — uses Docker daemon, falls back to registry
SetRegistrySource(image) registry:<image> — pull directly from registry, no daemon
SetDockerArchiveSource(path) / SetOciArchiveSource(path) tar-on-disk variants
AddOutputCycloneDxJson(file?) -o cyclonedx-json[=file]
AddOutputCycloneDxXml(file?) -o cyclonedx-xml[=file]
AddOutputSpdxJson(file?) -o spdx-json[=file]
AddOutputSpdxTagValue(file?) -o spdx-tag-value[=file]
AddOutputSyftJson(file?) -o syft-json[=file] — native format, lossless
AddOutputGitHubJson(file?) -o github-json[=file] — for dependency-graph API submission
AddOutputPurls(file?) -o purls[=file] — flat package-URL list
AddOutput(spec) escape hatch for arbitrary format=path tokens
AddExclude(glob) --exclude
AddSelectCataloger(spec) --select-catalogers +foo / -foo
SetScope("squashed"\|"all-layers"\|"deep-squashed") image-layer selection (validated)
SetSourceName(name) / SetSourceVersion(v) / SetSourceSupplier(s) metadata stamping
SetPlatform("linux/arm64") image platform
SetParallelism(n) cataloger worker count (validated ≥1)
AddEnrich("javascript"\|"python"\|...) online + local enrichment
SetBasePath(path) symlink containment root

syft convert

Setter Effect
SetSourceSbom(path) / ReadFromStdin() input SBOM (or - for stdin)
AddOutputCycloneDxJson(...) / AddOutputSpdxJson(...) / AddOutput(...) output format(s)
SetTemplatePath(path) for the template=file.txt output format

syft attest

Setter Effect
SetImage(ref) container image to attest
AddOutputCycloneDxJson(...) / AddOutputSpdxJson(...) predicate format
SetKey(path) cosign-style signing key path
SetKeyPassword(Secret) Secret-typed, routed via COSIGN_PASSWORD env var (cosign convention) — masked in CommandPlan.Secrets, never on the command line

Other

  • Syft.Version(tool) — diagnostic
  • Syft.CatalogerList(tool) — print available catalogers + config
  • Syft.Raw(tool, ...) — escape hatch

Secrets handling

SyftAttestSettings.SetKeyPassword(Secret) accepts a Tamp.Core.Secret and routes it via the COSIGN_PASSWORD environment variable — cosign's canonical password channel — not via command-line flag. Even with the env-var route the Secret is registered in CommandPlan.Secrets so Tamp's process trace masks it in printed output.

Built against Tamp.Core 1.6.0 — TAMP004 analyzer recognizes SyftAttestSettings as an approved Reveal context via the standard *Settings heuristic. No per-satellite InternalsVisibleTo entry required.

Pairs with

  • Tamp.Cargo + Tamp.Tauri.V2 — Rust + Tauri toolchain whose dependency tree gets cataloged
  • Tamp.Msix — point syft scan file:DasBook.msix at a built MSIX to enumerate what's inside the package
  • Tamp.MicrosoftStoreCli — generate the SBOM at pack time, attach to the Partner Center submission
  • Tamp.GitHubAttest (forthcoming, TAM-195) — the SLSA build-provenance side; SBOM (this package) is "what's inside", provenance is "how/where it was built"

Releasing

Releases follow the Tamp dogfood pattern.

Settings authoring style

Examples above use the fluent Set*-chain shape. Every wrapper verb also accepts a new XxxSettings { ... } object-init form — both produce identical CommandPlans. The fluent shape stays canonical in docs and the tamp init template; opt into object-init scaffolding via tamp init --settings-style=init.

See Build Script Authoring → Two authoring styles on the wiki for the side-by-side comparison.

License

MIT. See LICENSE.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.2 97 9/27/2026
0.1.1 98 9/27/2026
0.1.0 143 5/13/2026