Skip to content

Commit

Permalink
Add purls to SPDX sbom (#677)
Browse files Browse the repository at this point in the history
* Add purl to SPDX go dependencies

Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]>

* Fix pkg:oci purls in SPDX sbom

This commit modifies the top level purl in the SPDX sbom to
use an oci purl, indicating it describes an image.

Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]>
  • Loading branch information
puerco authored Mar 30, 2022
1 parent 895cff9 commit 4ac50b0
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
22 changes: 22 additions & 0 deletions internal/sbom/cyclonedx.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,34 @@ import (
"encoding/json"
"fmt"
"strings"

v1 "github.com/google/go-containerregistry/pkg/v1"
)

func bomRef(path, version string) string {
return fmt.Sprintf("pkg:golang/%s@%s?type=module", path, version)
}

func goRef(path, version string) string {
// Try to lowercase the first 2 path elements to comply with spec
// https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#golang
p := strings.Split(path, "/")
if len(p) > 2 {
path = strings.Join(
append(
[]string{strings.ToLower(p[0]), strings.ToLower(p[1])},
p[2:(len(p)-1)]...,
), "/",
)
}
return fmt.Sprintf("pkg:golang/%s@%s?type=module", path, version)
}

func ociRef(path string, imgDigest v1.Hash) string {
parts := strings.Split(path, "/")
return fmt.Sprintf("pkg:oci/%s@%s", parts[len(parts)-1], imgDigest.String())
}

func h1ToSHA256(s string) string {
if !strings.HasPrefix(s, "h1:") {
return ""
Expand Down
12 changes: 10 additions & 2 deletions internal/sbom/spdx.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import (
"strings"
"text/template"
"time"

v1 "github.com/google/go-containerregistry/pkg/v1"
)

const dateFormat = "2006-01-02T15:04:05Z"

func GenerateSPDX(koVersion string, date time.Time, mod []byte) ([]byte, error) {
func GenerateSPDX(koVersion string, date time.Time, mod []byte, imgDigest v1.Hash) ([]byte, error) {
var err error
mod, err = massageGoVersionM(mod)
if err != nil {
Expand All @@ -43,6 +45,7 @@ func GenerateSPDX(koVersion string, date time.Time, mod []byte) ([]byte, error)
BuildInfo: *bi,
Date: date.Format(dateFormat),
KoVersion: koVersion,
ImgDigest: imgDigest,
}); err != nil {
return nil, err
}
Expand All @@ -52,11 +55,14 @@ func GenerateSPDX(koVersion string, date time.Time, mod []byte) ([]byte, error)
type tmplInfo struct {
BuildInfo
Date, UUID, KoVersion string
ImgDigest v1.Hash
}

// TODO: use k8s.io/release/pkg/bom
var tmpl = template.Must(template.New("").Funcs(template.FuncMap{
"dots": func(s string) string { return strings.ReplaceAll(s, "/", ".") },
"dots": func(s string) string { return strings.ReplaceAll(s, "/", ".") },
"goRef": func(p, v string) string { return goRef(p, v) },
"ociRef": func(p string, d v1.Hash) string { return ociRef(p, d) },
"h1toSHA256": func(s string) (string, error) {
if !strings.HasPrefix(s, "h1:") {
return "", fmt.Errorf("malformed sum prefix: %q", s)
Expand Down Expand Up @@ -88,6 +94,7 @@ PackageLicenseDeclared: NOASSERTION
PackageCopyrightText: NOASSERTION
PackageLicenseComments: NOASSERTION
PackageComment: NOASSERTION
ExternalRef: PACKAGE-MANAGER purl {{ ociRef .Path .ImgDigest }}
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-{{ .BuildInfo.Main.Path | dots }}
Expand All @@ -108,6 +115,7 @@ PackageLicenseDeclared: NOASSERTION
PackageCopyrightText: NOASSERTION
PackageLicenseComments: NOASSERTION
PackageComment: NOASSERTION
ExternalRef: PACKAGE-MANAGER purl {{ goRef .Path .Version }}
{{ end }}
`))
7 changes: 5 additions & 2 deletions pkg/build/gobuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,11 @@ func spdx(version string) sbomber {
if err != nil {
return nil, "", err
}

b, err = sbom.GenerateSPDX(version, cfg.Created.Time, b)
imgDigest, err := img.Digest()
if err != nil {
return nil, "", err
}
b, err = sbom.GenerateSPDX(version, cfg.Created.Time, b, imgDigest)
if err != nil {
return nil, "", err
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/commands/deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,13 @@ If the image was not built using ko, or if it was built without embedding depend
[]byte(n),
[]byte(path.Join("/ko-app", filepath.Base(filepath.Clean(h.Name)))),
1)
imgDigest, err := img.Digest()
if err != nil {
return err
}
switch sbomType {
case "spdx":
b, err := sbom.GenerateSPDX(Version, cfg.Created.Time, mod)
b, err := sbom.GenerateSPDX(Version, cfg.Created.Time, mod, imgDigest)
if err != nil {
return err
}
Expand Down

0 comments on commit 4ac50b0

Please sign in to comment.