Skip to content

Commit

Permalink
Replace export parameters in run with attestor option
Browse files Browse the repository at this point in the history
Signed-off-by: John Kjell <[email protected]>
  • Loading branch information
jkjell committed Feb 5, 2024
1 parent b40be47 commit 25a616a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 20 deletions.
52 changes: 41 additions & 11 deletions attestation/link/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,23 @@ 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"
)

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
Expand All @@ -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 {
Expand All @@ -68,21 +94,25 @@ 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() {
switch name := attestor.Attestor.Name(); name {
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))
Expand Down
24 changes: 15 additions & 9 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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()})
}
}
}
Expand Down

0 comments on commit 25a616a

Please sign in to comment.