-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add APIs for Statement v1 and SLSA Provenance v1 protos #268
Changes from 6 commits
e926196
88b340e
71434d6
fcf6985
4a2940d
eb994da
daa6a2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package common | ||
|
||
import ( | ||
"google.golang.org/protobuf/encoding/protojson" | ||
"google.golang.org/protobuf/proto" | ||
"google.golang.org/protobuf/types/known/structpb" | ||
) | ||
|
||
/* | ||
PredicatePbToStruct converts a given protobuf representation of | ||
an in-toto attestation Predicate into a generic Struct struct | ||
needed to construct an in-toto Attestation Framework v1 | ||
compliant Statement. If there are any marshalling problems, | ||
this function returns an error. | ||
*/ | ||
func PredicatePbToStruct(predicatePb proto.Message) (*structpb.Struct, error) { | ||
predJson, err := protojson.Marshal(predicatePb) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
predStruct := &structpb.Struct{} | ||
err = protojson.Unmarshal(predJson, predStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return predStruct, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package v1 | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
prov1 "github.com/in-toto/attestation/go/predicates/provenance/v1" | ||
ita1 "github.com/in-toto/attestation/go/v1" | ||
|
||
"google.golang.org/protobuf/types/known/structpb" | ||
"google.golang.org/protobuf/types/known/timestamppb" | ||
) | ||
|
||
const ( | ||
// PredicateSLSAProvenance represents a build provenance for an artifact. | ||
SLSAProvenancePredicateType = "https://slsa.dev/provenance/v1" | ||
) | ||
|
||
/* | ||
GenBuildDefinition is a helper function to construct | ||
a SLSA v1 BuildDefinition struct. | ||
Validation is handled in GenProvenance(). | ||
*/ | ||
func GenBuildDefinition(buildType string, externalParams *structpb.Struct, internalParams *structpb.Struct, resolvedDependencies []*ita1.ResourceDescriptor) *prov1.BuildDefinition { | ||
buildDef := &prov1.BuildDefinition{ | ||
BuildType: buildType, | ||
ExternalParameters: externalParams, | ||
InternalParameters: internalParams, | ||
ResolvedDependencies: resolvedDependencies, | ||
} | ||
|
||
return buildDef | ||
} | ||
|
||
/* | ||
GenRunDetails is a helper function to construct | ||
a SLSA v1 RunDetails struct. | ||
Validation is handled in GenProvenance(). | ||
*/ | ||
func GenRunDetails(builder *prov1.Builder, metadata *prov1.BuildMetadata, byproducts []*ita1.ResourceDescriptor) *prov1.RunDetails { | ||
runDetails := &prov1.RunDetails{ | ||
Builder: builder, | ||
Metadata: metadata, | ||
Byproducts: byproducts, | ||
} | ||
|
||
return runDetails | ||
} | ||
|
||
/* | ||
GenBuilder is a helper function to construct a | ||
SLSA v1 Builder struct. | ||
Validation is handled in GenProvenance(). | ||
*/ | ||
func GenBuilder(id string, version map[string]string, builderDependencies []*ita1.ResourceDescriptor) *prov1.Builder { | ||
builder := &prov1.Builder{ | ||
Id: id, | ||
Version: version, | ||
BuilderDependencies: builderDependencies, | ||
} | ||
|
||
return builder | ||
} | ||
|
||
/* | ||
GenBuildMetadata is a helper function to construct a | ||
SLSA v1 BuildMetadata struct. | ||
Because none of the fields of the object are required, this | ||
constructor does not validate the contents of the struct | ||
and always succeeds. | ||
*/ | ||
func GenBuildMetadata(invocationID string, startedOn time.Time, finishedOn time.Time) *prov1.BuildMetadata { | ||
buildMetadata := &prov1.BuildMetadata{ | ||
InvocationId: invocationID, | ||
StartedOn: timestamppb.New(startedOn), | ||
FinishedOn: timestamppb.New(finishedOn), | ||
} | ||
|
||
return buildMetadata | ||
} | ||
|
||
/* | ||
GenerateValidPredicate constructs a SLSA v1 Provenance struct. | ||
If the created object does not represent a valid Provenance, this | ||
function returns an error. | ||
*/ | ||
func GenerateValidPredicate(buildDefinition *prov1.BuildDefinition, runDetails *prov1.RunDetails) (*prov1.Provenance, error) { | ||
provenance := &prov1.Provenance{ | ||
BuildDefinition: buildDefinition, | ||
RunDetails: runDetails, | ||
} | ||
|
||
if err := provenance.Validate(); err != nil { | ||
return nil, fmt.Errorf("Invalid Provenance format: %w", err) | ||
marcelamelara marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
return provenance, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package v1 | ||
|
||
import ( | ||
"fmt" | ||
|
||
ita1 "github.com/in-toto/attestation/go/v1" | ||
"google.golang.org/protobuf/types/known/structpb" | ||
) | ||
|
||
/* | ||
GenerateValidResourceDescriptor constructs an in-toto Attestation Framework v1 | ||
ResourceDescriptor struct. If the created object does not represent a | ||
valid ResourceDescriptor, this function returns an error. | ||
*/ | ||
func GenerateValidResourceDescriptor(name string, uri string, digestSet map[string]string, content []byte, downloadLocation string, mediaType string, annotations *structpb.Struct) (*ita1.ResourceDescriptor, error) { | ||
rd := &ita1.ResourceDescriptor{ | ||
Name: name, | ||
Uri: uri, | ||
Digest: digestSet, | ||
Content: content, | ||
DownloadLocation: downloadLocation, | ||
MediaType: mediaType, | ||
Annotations: annotations, | ||
} | ||
|
||
err := rd.Validate() | ||
if err != nil { | ||
return nil, fmt.Errorf("Invalid resource descriptor: %w", err) | ||
marcelamelara marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
return rd, nil | ||
} | ||
|
||
/* | ||
RDListFromRecord converts a map of artifacts as collected | ||
by RecordArtifacts() in runlib.go and converts it into a list | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be expanded with the structure of the map? We may retire RecordArtifacts at some point, it'll be helpful to track this here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to be 100% sure I've understood what you're asking, you're suggesting we include |
||
of ITE-6 ResourceDescriptors to be used in v1 Statements. | ||
*/ | ||
func RDListFromRecord(evalArtifacts map[string]map[string]string) ([]*ita1.ResourceDescriptor, error) { | ||
var rds []*ita1.ResourceDescriptor | ||
for name, digestSet := range evalArtifacts { | ||
|
||
rd, err := GenerateValidResourceDescriptor(name, "", digestSet, nil, "", "", nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
rds = append(rds, rd) | ||
} | ||
|
||
return rds, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package v1 | ||
|
||
import ( | ||
"fmt" | ||
|
||
ita1 "github.com/in-toto/attestation/go/v1" | ||
"google.golang.org/protobuf/types/known/structpb" | ||
) | ||
|
||
/* | ||
GenerateValidStatement constructs an in-toto Attestation Framework v1 | ||
Statement struct. If the created object does not represent a | ||
compliant Statement, this function returns an error. | ||
*/ | ||
func GenerateValidStatement(subject []*ita1.ResourceDescriptor, predicateType string, predicate *structpb.Struct) (*ita1.Statement, error) { | ||
st := &ita1.Statement{ | ||
Type: ita1.StatementTypeUri, | ||
Subject: subject, | ||
PredicateType: predicateType, | ||
Predicate: predicate, | ||
} | ||
|
||
err := st.Validate() | ||
if err != nil { | ||
return nil, fmt.Errorf("Invalid in-toto Statement: %w", err) | ||
marcelamelara marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
return st, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if want this to be
internal/
, I don't think we want to accidentally have people use this. Or it could be a private function inattestation
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I had set it public since it's called from within
runlib
, but either moving this tointernal/
or even as a private function to be called only withinGenerateValidStatement()
could work. We would have to change the signature ofGenerateValidStatement()
to take a protobuf message instead of Struct in the latter case, not sure how I feel about that.