Skip to content

Commit

Permalink
Implement first draft to generate provenance for containers
Browse files Browse the repository at this point in the history
Signed-off-by: Marco Franssen <marco.franssen@philips.com>
  • Loading branch information
marcofranssen committed Dec 22, 2021
1 parent 4dc7f6f commit 0c0ed88
Show file tree
Hide file tree
Showing 17 changed files with 890 additions and 37 deletions.
83 changes: 83 additions & 0 deletions cmd/slsa-provenance/cli/container.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package cli

import (
"fmt"

"github.com/docker/docker/client"
"github.com/spf13/cobra"

"github.com/philips-labs/slsa-provenance-action/cmd/slsa-provenance/cli/options"
"github.com/philips-labs/slsa-provenance-action/lib/github"
"github.com/philips-labs/slsa-provenance-action/lib/oci"
)

// OCI creates an instance of *cobra.Command to generate oci provenance
func OCI() *cobra.Command {
o := &options.OCIOptions{}

cmd := &cobra.Command{
Use: "container",
Short: "Generate provenance on container assets",
RunE: func(cmd *cobra.Command, args []string) error {
outputPath, err := o.GetOutputPath()
if err != nil {
return err
}

gh, err := o.GetGitHubContext()
if err != nil {
return err
}

runner, err := o.GetRunnerContext()
if err != nil {
return err
}

materials, err := o.GetExtraMaterials()
if err != nil {
return err
}

repo, err := o.GetRepository()
if err != nil {
return err
}

digest, err := o.GetDigest()
if err != nil {
return err
}

tags, err := o.GetTags()
if err != nil {
return err
}

cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return err
}
subjecter := oci.NewContainerSubjecter(cli, repo, digest, tags...)

env := &github.Environment{
Context: gh,
Runner: runner,
}
stmt, err := env.GenerateProvenanceStatement(cmd.Context(), subjecter)
if err != nil {
return fmt.Errorf("failed to generate provenance: %w", err)
}

stmt.Predicate.Materials = append(stmt.Predicate.Materials, materials...)

fmt.Fprintf(cmd.OutOrStdout(), "Saving provenance to %s\n", outputPath)

return env.PersistProvenanceStatement(cmd.Context(), stmt, outputPath)
},
}

o.AddFlags(cmd)

return cmd
}
4 changes: 3 additions & 1 deletion cmd/slsa-provenance/cli/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/philips-labs/slsa-provenance-action/cmd/slsa-provenance/cli/options"
"github.com/philips-labs/slsa-provenance-action/lib/github"
"github.com/philips-labs/slsa-provenance-action/lib/intoto"
)

// Files creates an instance of *cobra.Command to manage file provenance
Expand Down Expand Up @@ -46,7 +47,8 @@ func Files() *cobra.Command {
Runner: runner,
}

stmt, err := env.GenerateProvenanceStatement(cmd.Context(), artifactPath, materials...)
subjecter := intoto.NewFilePathSubjecter(artifactPath)
stmt, err := env.GenerateProvenanceStatement(cmd.Context(), subjecter, materials...)
if err != nil {
return fmt.Errorf("failed to generate provenance: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/slsa-provenance/cli/files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestGenerateFilesCliOptions(t *testing.T) {
},
{
name: "invalid --artifact-path",
err: fmt.Errorf("failed to generate provenance: resource path not found: [provided=%s]", unknownFile),
err: fmt.Errorf("failed to generate provenance: lstat non-existing-folder/unknown-file: no such file or directory"),
arguments: []string{
"--artifact-path",
unknownFile,
Expand Down
1 change: 1 addition & 0 deletions cmd/slsa-provenance/cli/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func Generate() *cobra.Command {
cmd.AddCommand(
Files(),
GitHubRelease(),
OCI(),
)

return cmd
Expand Down
2 changes: 1 addition & 1 deletion cmd/slsa-provenance/cli/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func TestGenerate(t *testing.T) {

cmd := cli.Generate()

assert.Len(cmd.Commands(), 2)
assert.Len(cmd.Commands(), 3)
output, err := executeCommand(cmd)

assert.NoError(err)
Expand Down
6 changes: 4 additions & 2 deletions cmd/slsa-provenance/cli/github-release.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/philips-labs/slsa-provenance-action/cmd/slsa-provenance/cli/options"
"github.com/philips-labs/slsa-provenance-action/lib/github"
"github.com/philips-labs/slsa-provenance-action/lib/intoto"
"github.com/philips-labs/slsa-provenance-action/lib/transport"
)

Expand Down Expand Up @@ -59,9 +60,10 @@ func GitHubRelease() *cobra.Command {
Writer: cmd.OutOrStdout(),
}
rc := github.NewReleaseClient(tc)
env := github.NewReleaseEnvironment(*gh, *runner, tagName, rc)
env := github.NewReleaseEnvironment(*gh, *runner, tagName, rc, artifactPath)

stmt, err := env.GenerateProvenanceStatement(cmd.Context(), artifactPath, materials...)
subjecter := intoto.NewFilePathSubjecter(artifactPath)
stmt, err := env.GenerateProvenanceStatement(cmd.Context(), subjecter, materials...)
if err != nil {
return fmt.Errorf("failed to generate provenance: %w", err)
}
Expand Down
44 changes: 44 additions & 0 deletions cmd/slsa-provenance/cli/options/oci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package options

import "github.com/spf13/cobra"

// OCIOptions Commandline flags used for the generate oci command.
type OCIOptions struct {
GenerateOptions
Repository string
Digest string
Tags []string
}

// GetRepository The oci repository to search for the given tags.
func (o *OCIOptions) GetRepository() (string, error) {
if o.Repository == "" {
return "", RequiredFlagError("repository")
}
return o.Repository, nil
}

// GetDigest The digest to validate the tag digests against.
func (o *OCIOptions) GetDigest() (string, error) {
if o.Digest == "" {
return "", RequiredFlagError("repository")
}
return o.Digest, nil
}

// GetTags The tags to add as provenance subjects.
func (o *OCIOptions) GetTags() ([]string, error) {
if len(o.Tags) == 0 {
return []string{"latest"}, nil
}

return o.Tags, nil
}

// AddFlags Registers the flags with the cobra.Command.
func (o *OCIOptions) AddFlags(cmd *cobra.Command) {
o.GenerateOptions.AddFlags(cmd)
cmd.PersistentFlags().StringVar(&o.Repository, "repository", "", "The repository of the oci artifact.")
cmd.PersistentFlags().StringVar(&o.Digest, "digest", "", "The digest for the oci artifact.")
cmd.PersistentFlags().StringSliceVar(&o.Tags, "tags", nil, "The given tags for this oci release.")
}
15 changes: 15 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,38 @@ module github.com/philips-labs/slsa-provenance-action
go 1.17

require (
github.com/docker/docker v20.10.10+incompatible
github.com/google/go-github/v41 v41.0.0
github.com/spf13/cobra v1.3.0
github.com/stretchr/testify v1.7.0
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
)

require (
github.com/Microsoft/go-winio v0.4.17 // indirect
github.com/containerd/containerd v1.5.7 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect
golang.org/x/net v0.0.0-20211108170745-6635138e15ea // indirect
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
google.golang.org/grpc v1.42.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
Expand Down
Loading

0 comments on commit 0c0ed88

Please sign in to comment.