Skip to content

Commit

Permalink
Allow injection of extra materials via files
Browse files Browse the repository at this point in the history
Some build systems could create files that contain materials used during
the build (like docker images, operating system packages etc.). These
files would contain a JSON array with Items. When set on the
command-line flag `-extra_materials`, slsa-provenance will read and
parse these files and add the found materials to the statement.

Signed-off-by: Pieter Lexis <pieter.lexis@powerdns.com>
  • Loading branch information
pieterlexis committed Nov 9, 2021
1 parent f471992 commit 920b639
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 4 deletions.
27 changes: 23 additions & 4 deletions cmd/slsa-provenance/cli/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"strings"

"github.com/peterbourgon/ff/v3/ffcli"
"github.com/pkg/errors"
Expand All @@ -26,11 +28,16 @@ func Generate(w io.Writer) *ffcli.Command {
flagset = flag.NewFlagSet("slsa-provenance generate", flag.ExitOnError)
tagName = flagset.String("tag_name", "", `The github release to generate provenance on.
(if set the artifacts will be downloaded from the release and the provenance will be added as an additional release asset.)`)
artifactPath = flagset.String("artifact_path", "", "The file or dir path of the artifacts for which provenance should be generated.")
outputPath = flagset.String("output_path", "build.provenance", "The path to which the generated provenance should be written.")
githubContext = flagset.String("github_context", "", "The '${github}' context value.")
runnerContext = flagset.String("runner_context", "", "The '${runner}' context value.")
artifactPath = flagset.String("artifact_path", "", "The file or dir path of the artifacts for which provenance should be generated.")
outputPath = flagset.String("output_path", "build.provenance", "The path to which the generated provenance should be written.")
githubContext = flagset.String("github_context", "", "The '${github}' context value.")
runnerContext = flagset.String("runner_context", "", "The '${runner}' context value.")
extraMaterials = []string{}
)
flagset.Func("extra_materials", "Files that contain JSON encoded provenance to be included into the provenance", func(s string) error {
extraMaterials = append(extraMaterials, strings.Fields(s)...)
return nil
})

flagset.SetOutput(w)

Expand Down Expand Up @@ -80,6 +87,18 @@ func Generate(w io.Writer) *ffcli.Command {
return errors.Wrap(err, "failed to generate provenance")
}

for _, extra := range extraMaterials {
content, err := ioutil.ReadFile(extra)
if err != nil {
return errors.Wrapf(err, "Could not load extra materials from %s", extra)
}
var materials []intoto.Item
if err = json.Unmarshal(content, &materials); err != nil {
return errors.Wrapf(err, "Invalid JSON in extra materials file %s", extra)
}
stmt.Predicate.Materials = append(stmt.Predicate.Materials, materials...)
}

fmt.Fprintf(w, "Saving provenance to %s\n", *outputPath)

return env.PersistProvenanceStatement(ctx, stmt, *outputPath)
Expand Down
48 changes: 48 additions & 0 deletions cmd/slsa-provenance/cli/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,54 @@ func TestGenerateCliOptions(t *testing.T) {
runnerContext,
},
},
{
name: "With extra materials",
err: nil,
arguments: []string{
"-artifact_path",
path.Join(rootDir, "bin/slsa-provenance"),
"-github_context",
githubContext,
"-output_path",
provenanceFile,
"-runner_context",
runnerContext,
"-extra_materials",
path.Join(rootDir, "test-data/materials-valid.json"),
},
},
{
name: "With broken extra materials",
err: fmt.Errorf("Invalid JSON in extra materials file %s: unexpected end of JSON input", path.Join(rootDir, "test-data/materials-broken.not-json")),
arguments: []string{
"-artifact_path",
path.Join(rootDir, "bin/slsa-provenance"),
"-github_context",
githubContext,
"-output_path",
provenanceFile,
"-runner_context",
runnerContext,
"-extra_materials",
path.Join(rootDir, "test-data/materials-broken.not-json"),
},
},
{
name: "With non-existent extra materials",
err: fmt.Errorf("Could not load extra materials from non-existing-folder/unknown-file: open non-existing-folder/unknown-file: no such file or directory"),
arguments: []string{
"-artifact_path",
path.Join(rootDir, "bin/slsa-provenance"),
"-github_context",
githubContext,
"-output_path",
provenanceFile,
"-runner_context",
runnerContext,
"-extra_materials",
fmt.Sprintf("%s %s", path.Join(rootDir, "test-data/materials-valid.json"), "non-existing-folder/unknown-file"),
},
},
}

for _, tc := range testCases {
Expand Down
7 changes: 7 additions & 0 deletions test-data/materials-broken.not-json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"uri": "pkg:deb/debian/stunnel4@5.50-3?arch=amd64",
"digest": {
"sha256": "e1731ae217fcbc64d4c00d707dcead45c828c5f762bcf8cc56d87de511e096fa"
}
}
8 changes: 8 additions & 0 deletions test-data/materials-valid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"uri": "pkg:deb/debian/stunnel4@5.50-3?arch=amd64",
"digest": {
"sha256": "e1731ae217fcbc64d4c00d707dcead45c828c5f762bcf8cc56d87de511e096fa"
}
}
]

0 comments on commit 920b639

Please sign in to comment.