Skip to content

Commit

Permalink
Refactor persisting provenance to environment
Browse files Browse the repository at this point in the history
  • Loading branch information
marcofranssen committed Oct 26, 2021
1 parent 77d30ee commit 563ba76
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 31 deletions.
20 changes: 2 additions & 18 deletions cmd/slsa-provenance/cli/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,9 @@ func Generate(w io.Writer) *ffcli.Command {
return errors.Wrap(err, "failed to generate provenance")
}

// NOTE: At L1, writing the in-toto Statement type is sufficient but, at
// higher SLSA levels, the Statement must be encoded and wrapped in an
// Envelope to support attaching signatures.
payload, _ := json.MarshalIndent(stmt, "", " ")
fmt.Fprintf(w, "Saving provenance to %s:\n\n%s\n", *outputPath, string(payload))
fmt.Fprintf(w, "Saving provenance to %s\n", *outputPath)

if err := os.WriteFile(*outputPath, payload, 0755); err != nil {
return errors.Wrap(err, "failed to write provenance")
}

if renv, ok := env.(*github.ReleaseEnvironment); ok {
stmtFile, err := os.Open(*outputPath)
if err != nil {
return fmt.Errorf("failed to open provenance statement: %w", err)
}
renv.AttachProvenanceStatement(ctx, *tagName, stmtFile)
}

return nil
return env.PersistProvenanceStatement(ctx, stmt, *outputPath)
},
}
}
Expand Down
38 changes: 32 additions & 6 deletions lib/github/provenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"os"
"strings"

"github.com/google/go-github/v39/github"
"github.com/pkg/errors"

"github.com/philips-labs/slsa-provenance-action/lib/intoto"
Expand Down Expand Up @@ -52,6 +51,22 @@ func (e *Environment) GenerateProvenanceStatement(ctx context.Context, artifactP
return stmt, nil
}

// PersistProvenanceStatement writes the provenance statement at the given path
func (e *Environment) PersistProvenanceStatement(ctx context.Context, stmt *intoto.Statement, path string) error {
// NOTE: At L1, writing the in-toto Statement type is sufficient but, at
// higher SLSA levels, the Statement must be encoded and wrapped in an
// Envelope to support attaching signatures.
payload, err := json.MarshalIndent(stmt, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal provenance: %w", err)
}
if err := os.WriteFile(path, payload, 0755); err != nil {
return fmt.Errorf("failed to write provenance: %w", err)
}

return nil
}

// ReleaseEnvironment implements intoto.Provenancer to Generate provenance based on a GitHub release
type ReleaseEnvironment struct {
*Environment
Expand Down Expand Up @@ -106,15 +121,26 @@ func (e *ReleaseEnvironment) GenerateProvenanceStatement(ctx context.Context, ar
return e.Environment.GenerateProvenanceStatement(ctx, artifactPath)
}

// AttachProvenanceStatement attaches the provenance statement to the release
func (e *ReleaseEnvironment) AttachProvenanceStatement(ctx context.Context, file *os.File) (*github.ReleaseAsset, error) {
// PersistProvenanceStatement writes the provenance statement at the given path and uploads it to the GitHub release
func (e *ReleaseEnvironment) PersistProvenanceStatement(ctx context.Context, stmt *intoto.Statement, path string) error {
err := e.Environment.PersistProvenanceStatement(ctx, stmt, path)
if err != nil {
return err
}

stmtFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("failed to open provenance statement: %w", err)
}

owner := e.Context.RepositoryOwner
repo := repositoryName(e.Context.Repository)
releaseID, err := e.GetReleaseID(ctx, e.tagName)
_, err = e.rc.AddProvenanceToRelease(ctx, owner, repo, e.releaseID, stmtFile)
if err != nil {
return nil, err
return fmt.Errorf("failed to upload provenance to release: %w", err)
}
return e.rc.AddProvenanceToRelease(ctx, owner, repo, releaseID, file)

return nil
}

// GetReleaseID fetches a release and caches the releaseID in the environment
Expand Down
8 changes: 1 addition & 7 deletions lib/github/provenance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package github_test

import (
"context"
"encoding/json"
"fmt"
"os"
"path"
Expand Down Expand Up @@ -353,14 +352,9 @@ func TestGenerateProvenanceFromGitHubRelease(t *testing.T) {
assertMetadata(assert, predicate.Metadata, ghContext, repoURL)
assertRecipe(assert, predicate.Recipe)

payload, _ := json.MarshalIndent(stmt, "", " ")
stmtPath := path.Join(artifactPath, "build.provenance")
err = os.WriteFile(stmtPath, payload, 0755)
assert.NoError(err)

stmtFile, err := os.Open(stmtPath)
assert.NoError(err)
_, err = env.AttachProvenanceStatement(ctx, stmtFile)
err = env.PersistProvenanceStatement(ctx, stmt, stmtPath)
assert.NoError(err)
}

Expand Down
1 change: 1 addition & 0 deletions lib/intoto/intoto.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
// Provenancer generates provenance statements for given artifacts
type Provenancer interface {
GenerateProvenanceStatement(ctx context.Context, artifactPath string) (*Statement, error)
PersistProvenanceStatement(ctx context.Context, stmt *Statement, path string) error
}

// Envelope wraps an in-toto statement to be able to attach signatures to the Statement
Expand Down

0 comments on commit 563ba76

Please sign in to comment.