From 19869e5bed2b0170a5e468eb651f01eb87a38892 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Wed, 14 Oct 2026 22:36:15 -0300 Subject: [PATCH] sbom: a module of the binary's own tree is the binary's version Alloy v1.20.1 replaces its own modules with directories of its tree (`=> ../syntax`) and Grafana v13.2.4 builds its apps from a workspace; Go stamps both (devel), which Check refuses, and spin-ami's build stopped at the root's SBOM on thirty of them. They were compiled from the tree at the binary's tag, so they are that version, under the path they are published by. Modules takes the binary's version for it. Co-Authored-By: Claude Opus 5.5 (1M context) --- sbom/builders.go | 12 ++++++++++-- sbom/sbom_test.go | 8 ++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/sbom/builders.go b/sbom/builders.go index 7d22ccb..4b1f317 100644 --- a/sbom/builders.go +++ b/sbom/builders.go @@ -58,7 +58,7 @@ func Go(version, path string) (cdx.Component, error) { if err != nil { return cdx.Component{}, err } - deps := Modules(info) + deps := Modules(info, version) return cdx.Component{ Type: cdx.ComponentTypeApplication, Name: filepath.Base(path), Version: version, PackageURL: "pkg:golang/" + info.Main.Path + "@" + version, Hashes: sha(sum), Components: &deps, @@ -68,15 +68,23 @@ func Go(version, path string) (cdx.Component, error) { // Modules is what a Go build info says the binary is made of: the standard library of its // toolchain, and each module - the replacement where there is one, since that is what was // compiled - with the go.sum hash it was checked against. -func Modules(info *debug.BuildInfo) []cdx.Component { +// +// A module of the binary's own tree - replaced by a directory of it (Alloy's `=> ../syntax`), or a +// workspace's (Grafana's apps) - is stamped (devel), which no scanner matches: it was compiled +// from the tree at the binary's version, so it is that, under the path it is published by. +func Modules(info *debug.BuildInfo, version string) []cdx.Component { deps := []cdx.Component{{ Type: cdx.ComponentTypeLibrary, Name: "stdlib", Version: strings.TrimPrefix(info.GoVersion, "go"), PackageURL: "pkg:golang/stdlib@" + strings.TrimPrefix(info.GoVersion, "go"), }} for _, d := range info.Deps { + published := d.Path if d.Replace != nil { d = d.Replace } + if d.Version == "(devel)" { + d = &debug.Module{Path: published, Version: version} + } c := cdx.Component{Type: cdx.ComponentTypeLibrary, Name: d.Path, Version: d.Version, PackageURL: "pkg:golang/" + d.Path + "@" + d.Version} if d.Sum != "" { c.Properties = &[]cdx.Property{{Name: "go:sum", Value: d.Sum}} diff --git a/sbom/sbom_test.go b/sbom/sbom_test.go index 01fdf90..3ce3154 100644 --- a/sbom/sbom_test.go +++ b/sbom/sbom_test.go @@ -260,14 +260,17 @@ func TestDpkgListingIsTheDistributions(t *testing.T) { } // A module replaced is the replacement, which is what was compiled, with the go.sum hash it was -// checked against; the standard library is the toolchain's. +// checked against; the standard library is the toolchain's; and a module of the binary's own tree, +// which Go stamps (devel), is the binary's version under the path it is published by. func TestModulesAreWhatWasCompiled(t *testing.T) { info := &debug.BuildInfo{GoVersion: "go1.27.2", Deps: []*debug.Module{ {Path: "golang.org/x/net", Version: "v0.60.0", Sum: "h1:abc="}, {Path: "github.com/a/b", Version: "v1.0.0", Replace: &debug.Module{Path: "github.com/fork/b", Version: "v1.0.1", Sum: "h1:def="}}, + {Path: "github.com/grafana/alloy/syntax", Version: "v0.1.0", Replace: &debug.Module{Path: "../syntax", Version: "(devel)"}}, + {Path: "github.com/grafana/grafana/apps/playlist", Version: "(devel)"}, }} got := map[string]string{} - for _, c := range sbom.Modules(info) { + for _, c := range sbom.Modules(info, "v13.2.4") { sum := "" if c.Properties != nil { sum = (*c.Properties)[0].Value @@ -276,6 +279,7 @@ func TestModulesAreWhatWasCompiled(t *testing.T) { } assert.Equal(t, map[string]string{ "pkg:golang/stdlib@1.27.2": "", "pkg:golang/golang.org/x/net@v0.60.0": "h1:abc=", "pkg:golang/github.com/fork/b@v1.0.1": "h1:def=", + "pkg:golang/github.com/grafana/alloy/syntax@v13.2.4": "", "pkg:golang/github.com/grafana/grafana/apps/playlist@v13.2.4": "", }, got) }