From b9d5d30c00db384bfe6420ab2bb6b5f2e7d25dba Mon Sep 17 00:00:00 2001 From: Will Dollman Date: Mon, 11 Nov 2024 16:33:33 +0000 Subject: [PATCH] Update SBOM file format and extract different payload (#1123) * Update SBOM file format and extract different payload * Update changelog * Strip any leading v from version string --- CHANGELOG.md | 5 +++++ cmd/src/sbom_fetch.go | 25 ++++++++++++++++--------- cmd/src/sbom_utils.go | 10 ++++++++++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1840d10e07..ea5ea301b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ All notable changes to `src-cli` are documented in this file. ## Unreleased +## 5.9.1 + +- Update SBOM output file extension from `.json` to `.cdx.json` [#1123](https://github.com/sourcegraph/src-cli/pull/1123) +- Improve SBOM compatibility with scanning tools [#1123](https://github.com/sourcegraph/src-cli/pull/1123) + ## 5.9.0 ## 5.8.2 diff --git a/cmd/src/sbom_fetch.go b/cmd/src/sbom_fetch.go index 894e34658d..4f82e3f222 100644 --- a/cmd/src/sbom_fetch.go +++ b/cmd/src/sbom_fetch.go @@ -10,7 +10,6 @@ import ( "net/http" "os" "os/exec" - "path" "path/filepath" "strings" "unicode" @@ -71,12 +70,12 @@ Examples: if versionFlag == nil || *versionFlag == "" { return cmderrors.Usage("version is required") } - c.version = *versionFlag + c.version = sanitizeVersion(*versionFlag) if outputDirFlag == nil || *outputDirFlag == "" { return cmderrors.Usage("output directory is required") } - c.outputDir = getOutputDir(*outputDirFlag, *versionFlag) + c.outputDir = getOutputDir(*outputDirFlag, c.version) if internalReleaseFlag == nil || !*internalReleaseFlag { c.internalRelease = false @@ -283,7 +282,19 @@ func extractSBOM(attestationBytes []byte) (string, error) { return "", fmt.Errorf("failed to decode payload: %w", err) } - return string(decodedPayload), nil + // Unmarshal the decoded payload to extract predicate + var payload map[string]json.RawMessage + if err := json.Unmarshal(decodedPayload, &payload); err != nil { + return "", fmt.Errorf("failed to unmarshal decoded payload: %w", err) + } + + // Extract just the predicate field + predicate, ok := payload["predicate"] + if !ok { + return "", fmt.Errorf("no predicate field found in payload") + } + + return string(predicate), nil } func (c sbomConfig) storeSBOM(sbom string, image string) error { @@ -296,7 +307,7 @@ func (c sbomConfig) storeSBOM(sbom string, image string) error { }, image) // Create the output file path - outputFile := filepath.Join(c.outputDir, safeImageName+".json") + outputFile := filepath.Join(c.outputDir, safeImageName+".cdx.json") // Ensure the output directory exists if err := os.MkdirAll(c.outputDir, 0755); err != nil { @@ -311,10 +322,6 @@ func (c sbomConfig) storeSBOM(sbom string, image string) error { return nil } -func getOutputDir(parentDir, version string) string { - return path.Join(parentDir, "sourcegraph-"+version) -} - // getImageReleaseListURL returns the URL for the list of images in a release, based on the version and whether it's an internal release. func (c *sbomConfig) getImageReleaseListURL() string { if c.internalRelease { diff --git a/cmd/src/sbom_utils.go b/cmd/src/sbom_utils.go index 9bce46e748..17f12f7e7c 100644 --- a/cmd/src/sbom_utils.go +++ b/cmd/src/sbom_utils.go @@ -6,6 +6,7 @@ import ( "io" "net/http" "os/exec" + "path" "strings" "time" ) @@ -190,3 +191,12 @@ func spinner(name string, stop chan bool) { } } } + +func getOutputDir(parentDir, version string) string { + return path.Join(parentDir, "sourcegraph-"+version) +} + +// sanitizeVersion removes any leading "v" from the version string +func sanitizeVersion(version string) string { + return strings.TrimPrefix(version, "v") +}