Skip to content

Commit

Permalink
Create SBOMs for images while creating packages
Browse files Browse the repository at this point in the history
  • Loading branch information
mikhailswift committed Apr 2, 2022
1 parent bea1002 commit 014ff1c
Show file tree
Hide file tree
Showing 7 changed files with 1,455 additions and 12 deletions.
19 changes: 11 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ go 1.16
require (
github.com/AlecAivazis/survey/v2 v2.3.2
github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d
github.com/aws/aws-sdk-go v1.40.56 // indirect
github.com/derailed/k9s v0.25.18
github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3
github.com/docker/cli v20.10.12+incompatible
Expand All @@ -15,7 +14,7 @@ require (
github.com/go-git/go-git/v5 v5.4.2
github.com/go-logr/logr v1.2.2
github.com/goccy/go-yaml v1.9.5
github.com/google/go-containerregistry v0.8.0
github.com/google/go-containerregistry v0.8.1-0.20220209165246-a44adc326839
github.com/mattn/go-colorable v0.1.12
github.com/mholt/archiver/v3 v3.5.1
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
Expand All @@ -24,14 +23,18 @@ require (
github.com/rancher/k3d/v5 v5.2.1
github.com/spf13/cobra v1.3.0
github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
github.com/testifysec/witness v0.1.7-0.20220307203322-6ec2d2b63a0e
golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506
helm.sh/helm/v3 v3.7.2
k8s.io/api v0.22.5
k8s.io/apimachinery v0.22.5
k8s.io/client-go v0.22.5
k8s.io/api v0.23.4
k8s.io/apimachinery v0.23.4
k8s.io/cli-runtime v0.23.4 // indirect
k8s.io/client-go v0.23.4
k8s.io/klog/v2 v2.40.1
sigs.k8s.io/kind v0.11.1
sigs.k8s.io/kustomize/api v0.8.11
sigs.k8s.io/kustomize/kyaml v0.11.0
sigs.k8s.io/kustomize/api v0.10.1
sigs.k8s.io/kustomize/kyaml v0.13.0
sigs.k8s.io/yaml v1.3.0
)

replace github.com/derailed/popeye => github.com/testifysec/popeye v0.9.9-0.20220307190025-d441c7496b07
1,378 changes: 1,378 additions & 0 deletions go.sum

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/internal/images/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ func init() {
homePath, _ := os.UserHomeDir()
cachePath = fmt.Sprintf("%s/%s", homePath, cachePath)
}

func CachePath() string {
return cachePath
}
6 changes: 4 additions & 2 deletions src/internal/images/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/pterm/pterm"
)

func PullAll(buildImageList []string, imageTarballPath string) {
func PullAll(buildImageList []string, imageTarballPath string) map[name.Tag]v1.Image {
var (
longer string
imageCount = len(buildImageList)
Expand Down Expand Up @@ -87,7 +87,7 @@ func PullAll(buildImageList []string, imageTarballPath string) {
_, _ = progressBar.Stop()
title = fmt.Sprintf("Pulling %v images (%s)", len(imageMap), utils.ByteFormat(float64(update.Total), 2))
pterm.Success.Println(title)
return
return tagToImage
case update.Error != nil:
message.Fatal(update.Error, "error writing image tarball")
default:
Expand All @@ -108,4 +108,6 @@ func PullAll(buildImageList []string, imageTarballPath string) {
progressBar.Add(chunk)
}
}

return tagToImage
}
2 changes: 2 additions & 0 deletions src/internal/packager/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type tempPaths struct {
seedImage string
images string
components string
sboms string
}

func createPaths() tempPaths {
Expand All @@ -50,6 +51,7 @@ func createPaths() tempPaths {
seedImage: basePath + "/seed-image.tar",
images: basePath + "/images.tar",
components: basePath + "/components",
sboms: basePath + "/sboms",
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/internal/packager/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/defenseunicorns/zarf/src/internal/helm"
"github.com/defenseunicorns/zarf/src/internal/images"
"github.com/defenseunicorns/zarf/src/internal/message"
"github.com/defenseunicorns/zarf/src/internal/sbom"
"github.com/defenseunicorns/zarf/src/internal/utils"
"github.com/mholt/archiver/v3"
)
Expand Down Expand Up @@ -50,7 +51,9 @@ func Create() {

if seedImage != "" {
// Load seed images into their own happy little tarball for ease of import on init
images.PullAll([]string{seedImage}, tempPath.seedImage)
pulledImages := images.PullAll([]string{seedImage}, tempPath.seedImage)
_ = utils.CreateDirectory(tempPath.sboms, 0700)
sbom.CatalogImages(pulledImages, tempPath.sboms)
}

var combinedImageList []string
Expand All @@ -63,7 +66,9 @@ func Create() {
// Images are handled separately from other component assets
if len(combinedImageList) > 0 {
uniqueList := removeDuplicates(combinedImageList)
images.PullAll(uniqueList, tempPath.images)
pulledImages := images.PullAll(uniqueList, tempPath.images)
_ = utils.CreateDirectory(tempPath.sboms, 0700)
sbom.CatalogImages(pulledImages, tempPath.sboms)
}

if config.IsZarfInitConfig() {
Expand Down
49 changes: 49 additions & 0 deletions src/internal/sbom/catalog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package sbom

import (
"encoding/json"
"fmt"
"os"
"path/filepath"

"github.com/defenseunicorns/zarf/src/internal/images"
"github.com/defenseunicorns/zarf/src/internal/message"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/testifysec/witness/pkg/attestation"
"github.com/testifysec/witness/pkg/attestation/syft"
)

func CatalogImages(tagToImage map[name.Tag]v1.Image, sbomDir string) {
imageCount := len(tagToImage)
spinner := message.NewProgressSpinner("Creating SBOMs for %d images.", imageCount)
actx, err := attestation.NewContext([]attestation.Attestor{})
if err != nil {
spinner.Fatalf(err, "Unable to make attestation context")
}

cachePath := images.CachePath()
currImage := 1
for tag, img := range tagToImage {
spinner.Updatef("Creating image SBOMs (%d of %d): %s", currImage, imageCount, tag)
sbomAttestor := syft.New(syft.WithImageSource(img, cachePath, tag.String()))
if err := sbomAttestor.Attest(actx); err != nil {
spinner.Fatalf(err, "Unable to build sbom for image %s", tag.String())
}

sbomFile, err := os.Create(filepath.Join(sbomDir, fmt.Sprintf("%s.json", sbomAttestor.SBOM.Source.ImageMetadata.ID)))
if err != nil {
spinner.Fatalf(err, "Unable to create SBOM file for image %s", tag.String())
}

defer sbomFile.Close()
enc := json.NewEncoder(sbomFile)
if err := enc.Encode(sbomAttestor); err != nil {
spinner.Fatalf(err, "Unable to write SBOM file for image %s", tag.String())
}

currImage++
}

spinner.Success()
}

0 comments on commit 014ff1c

Please sign in to comment.