Skip to content

Commit 617b78c

Browse files
authored
Merge pull request moby#3416 from jedevc/filter-frontend-provenance
Filter frontend provenance attestations
2 parents 8080c01 + 13a24b7 commit 617b78c

File tree

6 files changed

+51
-18
lines changed

6 files changed

+51
-18
lines changed

exporter/attestation/unbundle.go

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"os"
77
"path"
8+
"strings"
89

910
"github.com/containerd/continuity/fs"
1011
intoto "github.com/in-toto/in-toto-golang/in_toto"
@@ -20,6 +21,10 @@ import (
2021
// Unbundle iterates over all provided result attestations and un-bundles any
2122
// bundled attestations by loading them from the provided refs map.
2223
func Unbundle(ctx context.Context, s session.Group, bundled []exporter.Attestation) ([]exporter.Attestation, error) {
24+
if err := Validate(bundled); err != nil {
25+
return nil, err
26+
}
27+
2328
eg, ctx := errgroup.WithContext(ctx)
2429
unbundled := make([][]exporter.Attestation, len(bundled))
2530

@@ -28,6 +33,12 @@ func Unbundle(ctx context.Context, s session.Group, bundled []exporter.Attestati
2833
eg.Go(func() error {
2934
switch att.Kind {
3035
case gatewaypb.AttestationKindInToto:
36+
if strings.HasPrefix(att.InToto.PredicateType, "https://slsa.dev/provenance/") {
37+
if att.ContentFunc == nil {
38+
// provenance may only be set buildkit-side using ContentFunc
39+
return errors.New("frontend may not set provenance attestations")
40+
}
41+
}
3142
unbundled[i] = append(unbundled[i], att)
3243
case gatewaypb.AttestationKindBundle:
3344
if att.ContentFunc != nil {
@@ -52,6 +63,11 @@ func Unbundle(ctx context.Context, s session.Group, bundled []exporter.Attestati
5263
if err != nil {
5364
return err
5465
}
66+
for _, att := range atts {
67+
if strings.HasPrefix(att.InToto.PredicateType, "https://slsa.dev/provenance/") {
68+
return errors.New("frontend may not bundle provenance attestations")
69+
}
70+
}
5571
unbundled[i] = append(unbundled[i], atts...)
5672
}
5773
return nil
@@ -65,10 +81,9 @@ func Unbundle(ctx context.Context, s session.Group, bundled []exporter.Attestati
6581
for _, atts := range unbundled {
6682
joined = append(joined, atts...)
6783
}
68-
for _, att := range joined {
69-
if err := validate(att); err != nil {
70-
return nil, err
71-
}
84+
85+
if err := Validate(joined); err != nil {
86+
return nil, err
7287
}
7388
return joined, nil
7489
}
@@ -117,6 +132,7 @@ func unbundle(ctx context.Context, root string, bundle exporter.Attestation) ([]
117132
}
118133
unbundled = append(unbundled, exporter.Attestation{
119134
Kind: gatewaypb.AttestationKindInToto,
135+
Metadata: bundle.Metadata,
120136
Path: path.Join(bundle.Path, entry.Name()),
121137
ContentFunc: func() ([]byte, error) { return predicate, nil },
122138
InToto: result.InTotoAttestation{
@@ -128,8 +144,17 @@ func unbundle(ctx context.Context, root string, bundle exporter.Attestation) ([]
128144
return unbundled, nil
129145
}
130146

147+
func Validate(atts []exporter.Attestation) error {
148+
for _, att := range atts {
149+
if err := validate(att); err != nil {
150+
return err
151+
}
152+
}
153+
return nil
154+
}
155+
131156
func validate(att exporter.Attestation) error {
132-
if att.Path == "" {
157+
if att.Kind != gatewaypb.AttestationKindBundle && att.Path == "" {
133158
return errors.New("attestation does not have set path")
134159
}
135160
if att.Ref == nil && att.ContentFunc == nil {

exporter/containerimage/attestations.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ func supplementSBOM(ctx context.Context, s session.Group, target cache.Immutable
4343

4444
doc, err := decodeSPDX(content)
4545
if err != nil {
46-
return att, err
46+
// ignore decoding error
47+
return att, nil
4748
}
4849

4950
layers, err := newFileLayerFinder(target, targetRemote)

frontend/attestations/sbom/sbom.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func CreateSBOMScanner(ctx context.Context, resolver llb.ImageMetaResolver, scan
8888
Kind: gatewaypb.AttestationKindBundle,
8989
Ref: stsbom,
9090
Metadata: map[string][]byte{
91-
result.AttestationReasonKey: result.AttestationReasonSBOM,
91+
result.AttestationReasonKey: []byte(result.AttestationReasonSBOM),
9292
},
9393
InToto: result.InTotoAttestation{
9494
PredicateType: intoto.PredicateSPDX,

frontend/gateway/forwarder/forward.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ func (c *bridgeClient) Solve(ctx context.Context, req client.SolveRequest) (*cli
6767
if err != nil {
6868
return nil, c.wrapSolveError(err)
6969
}
70+
for _, atts := range res.Attestations {
71+
for _, att := range atts {
72+
if att.ContentFunc != nil {
73+
return nil, errors.Errorf("attestation callback cannot be sent through gateway")
74+
}
75+
}
76+
}
7077

7178
c.mu.Lock()
7279
cRes, err := result.ConvertResult(res, func(r solver.ResultProxy) (client.Reference, error) {
@@ -178,6 +185,13 @@ func (c *bridgeClient) toFrontendResult(r *client.Result) (*frontend.Result, err
178185
if r == nil {
179186
return nil, nil
180187
}
188+
for _, atts := range r.Attestations {
189+
for _, att := range atts {
190+
if att.ContentFunc != nil {
191+
return nil, errors.Errorf("attestation callback cannot be sent through gateway")
192+
}
193+
}
194+
}
181195

182196
res, err := result.ConvertResult(r, func(r client.Reference) (solver.ResultProxy, error) {
183197
rr, ok := r.(*ref)
@@ -186,13 +200,6 @@ func (c *bridgeClient) toFrontendResult(r *client.Result) (*frontend.Result, err
186200
}
187201
return rr.acquireResultProxy(), nil
188202
})
189-
for _, atts := range res.Attestations {
190-
for _, att := range atts {
191-
if att.ContentFunc != nil {
192-
return nil, errors.Errorf("attestation callback cannot be sent through gateway")
193-
}
194-
}
195-
}
196203
if err != nil {
197204
return nil, err
198205
}

solver/llbsolver/proc/provenance.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func ProvenanceProcessor(attrs map[string]string) llbsolver.Processor {
5050
res.AddAttestation(p.ID, llbsolver.Attestation{
5151
Kind: gatewaypb.AttestationKindInToto,
5252
Metadata: map[string][]byte{
53-
result.AttestationReasonKey: result.AttestationReasonProvenance,
53+
result.AttestationReasonKey: []byte(result.AttestationReasonProvenance),
5454
result.AttestationInlineOnlyKey: []byte(strconv.FormatBool(inlineOnly)),
5555
},
5656
InToto: result.InTotoAttestation{

solver/result/attestation.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ const (
1212
AttestationInlineOnlyKey = "inline-only"
1313
)
1414

15-
var (
16-
AttestationReasonSBOM = []byte("sbom")
17-
AttestationReasonProvenance = []byte("provenance")
15+
const (
16+
AttestationReasonSBOM = "sbom"
17+
AttestationReasonProvenance = "provenance"
1818
)
1919

2020
type Attestation[T any] struct {

0 commit comments

Comments
 (0)