Skip to content

Commit

Permalink
Add testcase for generating provenance statements
Browse files Browse the repository at this point in the history
Co-authored-by: Brend Smits <brend.smits@philips.com>
  • Loading branch information
marcofranssen and Brend-Smits committed Oct 22, 2021
1 parent b4245a7 commit 7ab4fb5
Show file tree
Hide file tree
Showing 5 changed files with 342 additions and 24 deletions.
9 changes: 8 additions & 1 deletion lib/intoto/intoto.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import (
"github.com/philips-labs/slsa-provenance-action/lib/github"
)

const (
// SlsaPredicateType the predicate type for SLSA intoto statements
SlsaPredicateType = "https://slsa.dev/provenance/v0.1"
// StatementType the type of the intoto statement
StatementType = "https://in-toto.io/Statement/v0.1"
)

// Envelope wraps an in-toto statement to be able to attach signatures to the Statement
type Envelope struct {
PayloadType string `json:"payloadType"`
Expand All @@ -16,7 +23,7 @@ type Envelope struct {

// SLSAProvenanceStatement builds a in-toto statement with predicate type https://slsa.dev/provenance/v0.1
func SLSAProvenanceStatement(opts ...StatementOption) *Statement {
stmt := &Statement{PredicateType: "https://slsa.dev/provenance/v0.1", Type: "https://in-toto.io/Statement/v0.1"}
stmt := &Statement{PredicateType: SlsaPredicateType, Type: StatementType}
for _, opt := range opts {
opt(stmt)
}
Expand Down
22 changes: 10 additions & 12 deletions lib/intoto/intoto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,29 @@ import (
func TestSLSAProvenanceStatement(t *testing.T) {
assert := assert.New(t)

predicateType := "https://slsa.dev/provenance/v0.1"
statementType := "https://in-toto.io/Statement/v0.1"
repoURI := "https://github.com/philips-labs/slsa-provenance-action"
builderID := repoURI + "/Attestations/GitHubHostedActions@v1"
buildInvocationID := repoURI + "/actions/runs/123498765"
recipeType := "https://github.com/Attestations/GitHubActionsWorkflow@v1"

stmt := SLSAProvenanceStatement()
assert.Equal(predicateType, stmt.PredicateType)
assert.Equal(statementType, stmt.Type)
assert.Equal(SlsaPredicateType, stmt.PredicateType)
assert.Equal(StatementType, stmt.Type)
assert.Len(stmt.Subject, 0)

stmt = SLSAProvenanceStatement(
WithSubject(make([]Subject, 4)),
)
assert.Equal(predicateType, stmt.PredicateType)
assert.Equal(statementType, stmt.Type)
assert.Equal(SlsaPredicateType, stmt.PredicateType)
assert.Equal(StatementType, stmt.Type)
assert.Len(stmt.Subject, 4)

stmt = SLSAProvenanceStatement(
WithSubject(make([]Subject, 3)),
WithBuilder(builderID),
)
assert.Equal(predicateType, stmt.PredicateType)
assert.Equal(statementType, stmt.Type)
assert.Equal(SlsaPredicateType, stmt.PredicateType)
assert.Equal(StatementType, stmt.Type)
assert.Len(stmt.Subject, 3)
assert.Equal(builderID, stmt.Predicate.Builder.ID)

Expand All @@ -43,8 +41,8 @@ func TestSLSAProvenanceStatement(t *testing.T) {
WithBuilder(builderID),
)
m := stmt.Predicate.Metadata
assert.Equal(predicateType, stmt.PredicateType)
assert.Equal(statementType, stmt.Type)
assert.Equal(SlsaPredicateType, stmt.PredicateType)
assert.Equal(StatementType, stmt.Type)
assert.Len(stmt.Subject, 0)
assert.Equal(builderID, stmt.Predicate.Builder.ID)
assert.Equal(buildInvocationID, m.BuildInvocationID)
Expand Down Expand Up @@ -73,8 +71,8 @@ func TestSLSAProvenanceStatement(t *testing.T) {
),
)
r := stmt.Predicate.Recipe
assert.Equal(predicateType, stmt.PredicateType)
assert.Equal(statementType, stmt.Type)
assert.Equal(SlsaPredicateType, stmt.PredicateType)
assert.Equal(StatementType, stmt.Type)
assert.Len(stmt.Subject, 1)
assert.Equal(builderID, stmt.Predicate.Builder.ID)
assert.Equal(recipeType, r.Type)
Expand Down
21 changes: 13 additions & 8 deletions lib/slsa/provenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"os"

"github.com/pkg/errors"
Expand All @@ -14,19 +13,25 @@ import (
)

const (
gitHubHostedIDSuffix = "/Attestations/GitHubHostedActions@v1"
selfHostedIDSuffix = "/Attestations/SelfHostedActions@v1"
recipeType = "https://github.com/Attestations/GitHubActionsWorkflow@v1"
payloadContentType = "application/vnd.in-toto+json"
// GitHubHostedIDSuffix the GitHub hosted attestation type
GitHubHostedIDSuffix = "/Attestations/GitHubHostedActions@v1"
// SelfHostedIDSuffix the GitHub self hosted attestation type
SelfHostedIDSuffix = "/Attestations/SelfHostedActions@v1"
// RecipeType the attestion type for a recipe
RecipeType = "https://github.com/Attestations/GitHubActionsWorkflow@v1"
// PayloadContentType used to define the Envelope content type
// See: https://github.com/in-toto/attestation#provenance-example
PayloadContentType = "application/vnd.in-toto+json"
)

func builderID(repoURI string) string {
if os.Getenv("GITHUB_ACTIONS") == "true" {
return repoURI + gitHubHostedIDSuffix
return repoURI + GitHubHostedIDSuffix
}
return repoURI + selfHostedIDSuffix
return repoURI + SelfHostedIDSuffix
}

// GenerateProvenanceStatement generates a in-toto provenance statement based on the github context
func GenerateProvenanceStatement(ctx context.Context, gh github.Context, runner github.RunnerContext, artifactPath string) (*intoto.Statement, error) {
subjects, err := subjects(artifactPath)
if os.IsNotExist(err) {
Expand All @@ -50,7 +55,7 @@ func GenerateProvenanceStatement(ctx context.Context, gh github.Context, runner
// NOTE: This is inexact as multiple workflows in a repo can have the same name.
// See https://github.com/github/feedback/discussions/4188
intoto.WithRecipe(
recipeType,
RecipeType,
gh.Workflow,
nil,
event.Inputs,
Expand Down
Loading

0 comments on commit 7ab4fb5

Please sign in to comment.