From 25a616a17259e2c4de434bff45f0b0ed6c671e77 Mon Sep 17 00:00:00 2001 From: John Kjell Date: Mon, 5 Feb 2024 06:28:06 -0600 Subject: [PATCH] Replace export parameters in run with attestor option Signed-off-by: John Kjell --- attestation/link/link.go | 52 +++++++++++++++++++++++++++++++--------- run.go | 24 ++++++++++++------- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/attestation/link/link.go b/attestation/link/link.go index 0f5e7026..61805bdd 100644 --- a/attestation/link/link.go +++ b/attestation/link/link.go @@ -19,12 +19,14 @@ import ( "fmt" v0 "github.com/in-toto/attestation/go/predicates/link/v0" + v1 "github.com/in-toto/attestation/go/v1" "github.com/in-toto/go-witness/attestation" "github.com/in-toto/go-witness/attestation/commandrun" "github.com/in-toto/go-witness/attestation/environment" "github.com/in-toto/go-witness/attestation/material" "github.com/in-toto/go-witness/attestation/product" "github.com/in-toto/go-witness/cryptoutil" + "github.com/in-toto/go-witness/registry" "google.golang.org/protobuf/types/known/structpb" ) @@ -32,6 +34,8 @@ const ( Name = "link" Type = "https://in-toto.io/attestation/link/v0.3" RunType = attestation.PostProductRunType + + defaultExport = false ) // This is a hacky way to create a compile time error in case the attestor @@ -42,14 +46,36 @@ var ( ) func init() { - attestation.RegisterAttestation(Name, Type, RunType, func() attestation.Attestor { - return New() - }) + attestation.RegisterAttestation(Name, Type, RunType, + func() attestation.Attestor { return New() }, + registry.BoolConfigOption( + "export", + "Export the link attestation to its own file", + defaultExport, + func(a attestation.Attestor, export bool) (attestation.Attestor, error) { + linkAttestor, ok := a.(*Link) + if !ok { + return a, fmt.Errorf("unexpected attestor type: %T is not a link attestor", a) + } + WithExport(export)(linkAttestor) + return linkAttestor, nil + }, + ), + ) +} + +type Option func(*Link) + +func WithExport(export bool) Option { + return func(l *Link) { + l.export = export + } } type Link struct { PbLink v0.Link products map[string]attestation.Product + export bool } func New() *Link { @@ -68,6 +94,10 @@ func (l *Link) RunType() attestation.RunType { return RunType } +func (l *Link) Export() bool { + return l.export +} + func (l *Link) Attest(ctx *attestation.AttestationContext) error { l.PbLink.Name = "stepNameHere" for _, attestor := range ctx.CompletedAttestors() { @@ -75,14 +105,14 @@ func (l *Link) Attest(ctx *attestation.AttestationContext) error { case commandrun.Name: l.PbLink.Command = attestor.Attestor.(*commandrun.CommandRun).Cmd case material.Name: - // mats := attestor.Attestor.(*material.Attestor).Materials() - // for name, digestSet := range mats { - // digests, _ := digestSet.ToNameMap() - // l.Materials = append(l.Materials, &v1.ResourceDescriptor{ - // Name: name, - // Digest: digests, - // }) - // } + mats := attestor.Attestor.(*material.Attestor).Materials() + for name, digestSet := range mats { + digests, _ := digestSet.ToNameMap() + l.PbLink.Materials = append(l.PbLink.Materials, &v1.ResourceDescriptor{ + Name: name, + Digest: digests, + }) + } case environment.Name: envs := attestor.Attestor.(*environment.Attestor).Variables pbEnvs := make(map[string]interface{}, len(envs)) diff --git a/run.go b/run.go index 86a4994d..9cfdffb3 100644 --- a/run.go +++ b/run.go @@ -64,19 +64,21 @@ type RunResult struct { AttestorName string } +// Should this be deprecated? +// Deprecated: Use RunWithExports instead func Run(stepName string, signer cryptoutil.Signer, opts ...RunOption) (RunResult, error) { - results, err := run(stepName, signer, []string{}, opts) + results, err := run(stepName, signer, opts) if len(results) > 1 { return RunResult{}, errors.New("expected a single result, got multiple") } return results[0], err } -func ExportedRun(stepName string, signer cryptoutil.Signer, opts ...RunOption) ([]RunResult, error) { - return run(stepName, signer, []string{"link"}, opts) +func RunWithExports(stepName string, signer cryptoutil.Signer, opts ...RunOption) ([]RunResult, error) { + return run(stepName, signer, opts) } -func run(stepName string, signer cryptoutil.Signer, exportAtt []string, opts []RunOption) ([]RunResult, error) { +func run(stepName string, signer cryptoutil.Signer, opts []RunOption) ([]RunResult, error) { ro := runOptions{ stepName: stepName, signer: signer, @@ -106,14 +108,18 @@ func run(stepName string, signer cryptoutil.Signer, exportAtt []string, opts []R if r.Error != nil { errs = append(errs, r.Error) } else if r.Attestor.Name() == link.Name { + // TODO: Find a better way to set stepName r.Attestor.(*link.Link).PbLink.Name = ro.stepName - if subjecter, ok := r.Attestor.(attestation.Subjecter); ok { - linkEnvelope, err := createAndSignEnvelope(r.Attestor, r.Attestor.Type(), subjecter.Subjects(), dsse.SignWithSigners(ro.signer), dsse.SignWithTimestampers(ro.timestampers...)) - if err != nil { - return result, fmt.Errorf("failed to sign envelope: %w", err) + // TODO: Add Exporter interface to attestors + if r.Attestor.(*link.Link).Export() { + if subjecter, ok := r.Attestor.(attestation.Subjecter); ok { + linkEnvelope, err := createAndSignEnvelope(r.Attestor, r.Attestor.Type(), subjecter.Subjects(), dsse.SignWithSigners(ro.signer), dsse.SignWithTimestampers(ro.timestampers...)) + if err != nil { + return result, fmt.Errorf("failed to sign envelope: %w", err) + } + result = append(result, RunResult{SignedEnvelope: linkEnvelope, AttestorName: r.Attestor.Name()}) } - result = append(result, RunResult{SignedEnvelope: linkEnvelope, AttestorName: r.Attestor.Name()}) } } }