Skip to content

Commit

Permalink
Merge pull request #3416 from jedevc/filter-frontend-provenance
Browse files Browse the repository at this point in the history
Filter frontend provenance attestations
  • Loading branch information
tonistiigi authored Jan 4, 2023
2 parents 8080c01 + 13a24b7 commit 617b78c
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 18 deletions.
35 changes: 30 additions & 5 deletions exporter/attestation/unbundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"os"
"path"
"strings"

"github.com/containerd/continuity/fs"
intoto "github.com/in-toto/in-toto-golang/in_toto"
Expand All @@ -20,6 +21,10 @@ import (
// Unbundle iterates over all provided result attestations and un-bundles any
// bundled attestations by loading them from the provided refs map.
func Unbundle(ctx context.Context, s session.Group, bundled []exporter.Attestation) ([]exporter.Attestation, error) {
if err := Validate(bundled); err != nil {
return nil, err
}

eg, ctx := errgroup.WithContext(ctx)
unbundled := make([][]exporter.Attestation, len(bundled))

Expand All @@ -28,6 +33,12 @@ func Unbundle(ctx context.Context, s session.Group, bundled []exporter.Attestati
eg.Go(func() error {
switch att.Kind {
case gatewaypb.AttestationKindInToto:
if strings.HasPrefix(att.InToto.PredicateType, "https://slsa.dev/provenance/") {
if att.ContentFunc == nil {
// provenance may only be set buildkit-side using ContentFunc
return errors.New("frontend may not set provenance attestations")
}
}
unbundled[i] = append(unbundled[i], att)
case gatewaypb.AttestationKindBundle:
if att.ContentFunc != nil {
Expand All @@ -52,6 +63,11 @@ func Unbundle(ctx context.Context, s session.Group, bundled []exporter.Attestati
if err != nil {
return err
}
for _, att := range atts {
if strings.HasPrefix(att.InToto.PredicateType, "https://slsa.dev/provenance/") {
return errors.New("frontend may not bundle provenance attestations")
}
}
unbundled[i] = append(unbundled[i], atts...)
}
return nil
Expand All @@ -65,10 +81,9 @@ func Unbundle(ctx context.Context, s session.Group, bundled []exporter.Attestati
for _, atts := range unbundled {
joined = append(joined, atts...)
}
for _, att := range joined {
if err := validate(att); err != nil {
return nil, err
}

if err := Validate(joined); err != nil {
return nil, err
}
return joined, nil
}
Expand Down Expand Up @@ -117,6 +132,7 @@ func unbundle(ctx context.Context, root string, bundle exporter.Attestation) ([]
}
unbundled = append(unbundled, exporter.Attestation{
Kind: gatewaypb.AttestationKindInToto,
Metadata: bundle.Metadata,
Path: path.Join(bundle.Path, entry.Name()),
ContentFunc: func() ([]byte, error) { return predicate, nil },
InToto: result.InTotoAttestation{
Expand All @@ -128,8 +144,17 @@ func unbundle(ctx context.Context, root string, bundle exporter.Attestation) ([]
return unbundled, nil
}

func Validate(atts []exporter.Attestation) error {
for _, att := range atts {
if err := validate(att); err != nil {
return err
}
}
return nil
}

func validate(att exporter.Attestation) error {
if att.Path == "" {
if att.Kind != gatewaypb.AttestationKindBundle && att.Path == "" {
return errors.New("attestation does not have set path")
}
if att.Ref == nil && att.ContentFunc == nil {
Expand Down
3 changes: 2 additions & 1 deletion exporter/containerimage/attestations.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ func supplementSBOM(ctx context.Context, s session.Group, target cache.Immutable

doc, err := decodeSPDX(content)
if err != nil {
return att, err
// ignore decoding error
return att, nil
}

layers, err := newFileLayerFinder(target, targetRemote)
Expand Down
2 changes: 1 addition & 1 deletion frontend/attestations/sbom/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func CreateSBOMScanner(ctx context.Context, resolver llb.ImageMetaResolver, scan
Kind: gatewaypb.AttestationKindBundle,
Ref: stsbom,
Metadata: map[string][]byte{
result.AttestationReasonKey: result.AttestationReasonSBOM,
result.AttestationReasonKey: []byte(result.AttestationReasonSBOM),
},
InToto: result.InTotoAttestation{
PredicateType: intoto.PredicateSPDX,
Expand Down
21 changes: 14 additions & 7 deletions frontend/gateway/forwarder/forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ func (c *bridgeClient) Solve(ctx context.Context, req client.SolveRequest) (*cli
if err != nil {
return nil, c.wrapSolveError(err)
}
for _, atts := range res.Attestations {
for _, att := range atts {
if att.ContentFunc != nil {
return nil, errors.Errorf("attestation callback cannot be sent through gateway")
}
}
}

c.mu.Lock()
cRes, err := result.ConvertResult(res, func(r solver.ResultProxy) (client.Reference, error) {
Expand Down Expand Up @@ -178,6 +185,13 @@ func (c *bridgeClient) toFrontendResult(r *client.Result) (*frontend.Result, err
if r == nil {
return nil, nil
}
for _, atts := range r.Attestations {
for _, att := range atts {
if att.ContentFunc != nil {
return nil, errors.Errorf("attestation callback cannot be sent through gateway")
}
}
}

res, err := result.ConvertResult(r, func(r client.Reference) (solver.ResultProxy, error) {
rr, ok := r.(*ref)
Expand All @@ -186,13 +200,6 @@ func (c *bridgeClient) toFrontendResult(r *client.Result) (*frontend.Result, err
}
return rr.acquireResultProxy(), nil
})
for _, atts := range res.Attestations {
for _, att := range atts {
if att.ContentFunc != nil {
return nil, errors.Errorf("attestation callback cannot be sent through gateway")
}
}
}
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion solver/llbsolver/proc/provenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func ProvenanceProcessor(attrs map[string]string) llbsolver.Processor {
res.AddAttestation(p.ID, llbsolver.Attestation{
Kind: gatewaypb.AttestationKindInToto,
Metadata: map[string][]byte{
result.AttestationReasonKey: result.AttestationReasonProvenance,
result.AttestationReasonKey: []byte(result.AttestationReasonProvenance),
result.AttestationInlineOnlyKey: []byte(strconv.FormatBool(inlineOnly)),
},
InToto: result.InTotoAttestation{
Expand Down
6 changes: 3 additions & 3 deletions solver/result/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const (
AttestationInlineOnlyKey = "inline-only"
)

var (
AttestationReasonSBOM = []byte("sbom")
AttestationReasonProvenance = []byte("provenance")
const (
AttestationReasonSBOM = "sbom"
AttestationReasonProvenance = "provenance"
)

type Attestation[T any] struct {
Expand Down

0 comments on commit 617b78c

Please sign in to comment.