Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
59 changes: 30 additions & 29 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"github.com/containerd/containerd/snapshots"
"github.com/containerd/continuity/fs/fstest"
"github.com/distribution/reference"
intotov1 "github.com/in-toto/attestation/go/v1"
intoto "github.com/in-toto/in-toto-golang/in_toto"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/client/llb"
Expand Down Expand Up @@ -71,6 +72,7 @@ import (
"golang.org/x/crypto/ssh/agent"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/structpb"
)

func init() {
Expand Down Expand Up @@ -8171,7 +8173,7 @@ func testExportAttestations(t *testing.T, sb integration.Sandbox) {
require.Equal(t, len(att.Layers), len(att.Img.RootFS.DiffIDs))
require.Equal(t, len(att.Img.History), 0)

var attest intoto.Statement
var attest intotov1.Statement
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))

purls := map[string]string{}
Expand All @@ -8190,7 +8192,7 @@ func testExportAttestations(t *testing.T, sb integration.Sandbox) {
require.Equal(t, "https://in-toto.io/Statement/v0.1", attest.Type)
require.Equal(t, "https://example.com/attestations/v1.0", attest.PredicateType)
require.Equal(t, map[string]interface{}{"success": true}, attest.Predicate)
subjects := []intoto.Subject{
subjects := []intotov1.ResourceDescriptor{
{
Name: purls[targets[0]],
Digest: map[string]string{
Expand All @@ -8206,13 +8208,13 @@ func testExportAttestations(t *testing.T, sb integration.Sandbox) {
}
require.Equal(t, subjects, attest.Subject)

var attest2 intoto.Statement
var attest2 intotov1.Statement
require.NoError(t, json.Unmarshal(att.LayersRaw[1], &attest2))

require.Equal(t, "https://in-toto.io/Statement/v0.1", attest2.Type)
require.Equal(t, "https://example.com/attestations2/v1.0", attest2.PredicateType)
require.Nil(t, attest2.Predicate)
subjects = []intoto.Subject{{
subjects = []intotov1.ResourceDescriptor{{
Name: "/attestation.json",
Digest: map[string]string{
"sha256": successDigest.Encoded(),
Expand Down Expand Up @@ -8253,7 +8255,7 @@ func testExportAttestations(t *testing.T, sb integration.Sandbox) {
require.NoError(t, err)

for _, p := range ps {
var attest intoto.Statement
var attest intotov1.Statement
dt, err := os.ReadFile(path.Join(dir, strings.ReplaceAll(platforms.Format(p), "/", "_"), "test.attestation.json"))
require.NoError(t, err)
require.NoError(t, json.Unmarshal(dt, &attest))
Expand All @@ -8262,20 +8264,20 @@ func testExportAttestations(t *testing.T, sb integration.Sandbox) {
require.Equal(t, "https://example.com/attestations/v1.0", attest.PredicateType)
require.Equal(t, map[string]interface{}{"success": true}, attest.Predicate)

require.Equal(t, []intoto.Subject{{
require.Equal(t, []intotov1.ResourceDescriptor{{
Name: "greeting",
Digest: result.ToDigestMap(digest.Canonical.FromString("hello " + platforms.Format(p) + "!")),
}}, attest.Subject)

var attest2 intoto.Statement
var attest2 intotov1.Statement
dt, err = os.ReadFile(path.Join(dir, strings.ReplaceAll(platforms.Format(p), "/", "_"), "test.attestation2.json"))
require.NoError(t, err)
require.NoError(t, json.Unmarshal(dt, &attest2))

require.Equal(t, "https://in-toto.io/Statement/v0.1", attest2.Type)
require.Equal(t, "https://example.com/attestations2/v1.0", attest2.PredicateType)
require.Nil(t, attest2.Predicate)
subjects := []intoto.Subject{{
subjects := []intotov1.ResourceDescriptor{{
Name: "/attestation.json",
Digest: map[string]string{
"sha256": successDigest.Encoded(),
Expand Down Expand Up @@ -8311,7 +8313,7 @@ func testExportAttestations(t *testing.T, sb integration.Sandbox) {
require.NoError(t, err)

for _, p := range ps {
var attest intoto.Statement
var attest intotov1.Statement
item := m[path.Join(strings.ReplaceAll(platforms.Format(p), "/", "_"), "test.attestation.json")]
require.NotNil(t, item)
require.NoError(t, json.Unmarshal(item.Data, &attest))
Expand All @@ -8320,20 +8322,20 @@ func testExportAttestations(t *testing.T, sb integration.Sandbox) {
require.Equal(t, "https://example.com/attestations/v1.0", attest.PredicateType)
require.Equal(t, map[string]interface{}{"success": true}, attest.Predicate)

require.Equal(t, []intoto.Subject{{
require.Equal(t, []intotov1.ResourceDescriptor{{
Name: "greeting",
Digest: result.ToDigestMap(digest.Canonical.FromString("hello " + platforms.Format(p) + "!")),
}}, attest.Subject)

var attest2 intoto.Statement
var attest2 intotov1.Statement
item = m[path.Join(strings.ReplaceAll(platforms.Format(p), "/", "_"), "test.attestation2.json")]
require.NotNil(t, item)
require.NoError(t, json.Unmarshal(item.Data, &attest2))

require.Equal(t, "https://in-toto.io/Statement/v0.1", attest2.Type)
require.Equal(t, "https://example.com/attestations2/v1.0", attest2.PredicateType)
require.Nil(t, attest2.Predicate)
subjects := []intoto.Subject{{
subjects := []intotov1.ResourceDescriptor{{
Name: "/attestation.json",
Digest: map[string]string{
"sha256": successDigest.Encoded(),
Expand Down Expand Up @@ -8464,15 +8466,15 @@ func testAttestationDefaultSubject(t *testing.T, sb integration.Sandbox) {
atts := imgs.Filter("unknown/unknown")
require.Equal(t, len(ps), len(atts.Images))
for i, att := range atts.Images {
var attest intoto.Statement
var attest intotov1.Statement
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))

require.Equal(t, "https://in-toto.io/Statement/v0.1", attest.Type)
require.Equal(t, "https://example.com/attestations/v1.0", attest.PredicateType)
require.Equal(t, map[string]interface{}{"success": true}, attest.Predicate)

name := fmt.Sprintf("pkg:docker/%s/buildkit/testattestationsemptysubject@latest?platform=%s", url.QueryEscape(registry), url.QueryEscape(platforms.Format(ps[i])))
subjects := []intoto.Subject{{
subjects := []intotov1.ResourceDescriptor{{
Name: name,
Digest: map[string]string{
"sha256": bases[i].Desc.Digest.Encoded(),
Expand Down Expand Up @@ -8531,14 +8533,13 @@ func testAttestationBundle(t *testing.T, sb integration.Sandbox) {
}
res.AddRef(pk, ref)

stmt := intoto.Statement{
StatementHeader: intoto.StatementHeader{
Type: intoto.StatementInTotoV01,
PredicateType: "https://example.com/attestations/v1.0",
},
Predicate: map[string]interface{}{
"foo": "1",
},
pred, _ := structpb.NewStruct(map[string]interface{}{
"foo": "1",
})
stmt := &intotov1.Statement{
Type: intotov1.StatementTypeUri,
PredicateType: "https://example.com/attestations/v1.0",
Predicate: pred,
}
buff := bytes.NewBuffer(nil)
enc := json.NewEncoder(buff)
Expand Down Expand Up @@ -8617,13 +8618,13 @@ func testAttestationBundle(t *testing.T, sb integration.Sandbox) {
require.Equal(t, len(ps)*1, len(atts.Images))
for i, att := range atts.Images {
require.Equal(t, 1, len(att.LayersRaw))
var attest intoto.Statement
var attest intotov1.Statement
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))

require.Equal(t, "https://example.com/attestations/v1.0", attest.PredicateType)
require.Equal(t, map[string]interface{}{"foo": "1"}, attest.Predicate)
name := fmt.Sprintf("pkg:docker/%s/buildkit/testattestationsbundle@latest?platform=%s", url.QueryEscape(registry), url.QueryEscape(platforms.Format(ps[i])))
subjects := []intoto.Subject{{
subjects := []intotov1.ResourceDescriptor{{
Name: name,
Digest: map[string]string{
"sha256": bases[i].Desc.Digest.Encoded(),
Expand Down Expand Up @@ -8840,7 +8841,7 @@ EOF
require.Equal(t, 2, len(imgs.Images))

att := imgs.Find("unknown/unknown")
attest := intoto.Statement{}
attest := intotov1.Statement{}
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))
require.Equal(t, "https://in-toto.io/Statement/v0.1", attest.Type)
require.Equal(t, intoto.PredicateSPDX, attest.PredicateType)
Expand Down Expand Up @@ -8872,7 +8873,7 @@ EOF
require.Equal(t, 2, len(imgs.Images))

att = imgs.Find("unknown/unknown")
attest = intoto.Statement{}
attest = intotov1.Statement{}
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))
require.Equal(t, "https://in-toto.io/Statement/v0.1", attest.Type)
require.Equal(t, intoto.PredicateSPDX, attest.PredicateType)
Expand Down Expand Up @@ -8904,7 +8905,7 @@ EOF
require.Equal(t, 2, len(imgs.Images))

att = imgs.Find("unknown/unknown")
attest = intoto.Statement{}
attest = intotov1.Statement{}
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))
require.Equal(t, "https://in-toto.io/Statement/v0.1", attest.Type)
require.Equal(t, intoto.PredicateSPDX, attest.PredicateType)
Expand Down Expand Up @@ -9070,7 +9071,7 @@ EOF

att := imgs.Find("unknown/unknown")
require.NotNil(t, att)
attest := intoto.Statement{}
attest := intotov1.Statement{}
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))
require.Equal(t, "https://in-toto.io/Statement/v0.1", attest.Type)
require.Equal(t, intoto.PredicateSPDX, attest.PredicateType)
Expand Down Expand Up @@ -9213,7 +9214,7 @@ func testSBOMSupplements(t *testing.T, sb integration.Sandbox) {

att := imgs.Find("unknown/unknown")
attest := struct {
intoto.StatementHeader
intotov1.Statement
Predicate spdx.Document
}{}
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))
Expand Down
4 changes: 2 additions & 2 deletions docs/attestations/attestation-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ The contents of each layer will be a blob dependent on its `mediaType`.

```json
{
"_type": "https://in-toto.io/Statement/v0.1",
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "<NAME>",
Expand Down Expand Up @@ -198,7 +198,7 @@ Attestation body containing the SBOM data listing the packages used during the b

```json
{
"_type": "https://in-toto.io/Statement/v0.1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://spdx.dev/Document",
"subject": [
{
Expand Down
2 changes: 1 addition & 1 deletion docs/attestations/sbom.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ the following SBOM:

```json
{
"_type": "https://in-toto.io/Statement/v0.1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://spdx.dev/Document",
"subject": [
{
Expand Down
4 changes: 2 additions & 2 deletions docs/attestations/slsa-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ in a provenance attestation similar to the following, for a `mode=min` build:

```json
{
"_type": "https://in-toto.io/Statement/v0.1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
{
Expand Down Expand Up @@ -463,7 +463,7 @@ For a similar build, but with `mode=max`:

```json
{
"_type": "https://in-toto.io/Statement/v0.1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
{
Expand Down
39 changes: 24 additions & 15 deletions exporter/attestation/make.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import (
"os"

"github.com/containerd/continuity/fs"
intoto "github.com/in-toto/in-toto-golang/in_toto"
intotov1 "github.com/in-toto/attestation/go/v1"
"github.com/moby/buildkit/exporter"
gatewaypb "github.com/moby/buildkit/frontend/gateway/pb"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/solver/result"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
"google.golang.org/protobuf/types/known/structpb"
)

// ReadAll reads the content of an attestation.
Expand Down Expand Up @@ -56,9 +57,9 @@ func ReadAll(ctx context.Context, s session.Group, att exporter.Attestation) ([]

// MakeInTotoStatements iterates over all provided result attestations and
// generates intoto attestation statements.
func MakeInTotoStatements(ctx context.Context, s session.Group, attestations []exporter.Attestation, defaultSubjects []intoto.Subject) ([]intoto.Statement, error) {
func MakeInTotoStatements(ctx context.Context, s session.Group, attestations []exporter.Attestation, defaultSubjects []*intotov1.ResourceDescriptor) ([]*intotov1.Statement, error) {
eg, ctx := errgroup.WithContext(ctx)
statements := make([]intoto.Statement, len(attestations))
statements := make([]*intotov1.Statement, len(attestations))

for i, att := range attestations {
i, att := i, att
Expand All @@ -74,7 +75,7 @@ func MakeInTotoStatements(ctx context.Context, s session.Group, attestations []e
if err != nil {
return err
}
statements[i] = *stmt
statements[i] = stmt
case gatewaypb.AttestationKindBundle:
return errors.New("bundle attestation kind must be un-bundled first")
}
Expand All @@ -87,13 +88,13 @@ func MakeInTotoStatements(ctx context.Context, s session.Group, attestations []e
return statements, nil
}

func makeInTotoStatement(ctx context.Context, content []byte, attestation exporter.Attestation, defaultSubjects []intoto.Subject) (*intoto.Statement, error) {
func makeInTotoStatement(ctx context.Context, content []byte, attestation exporter.Attestation, defaultSubjects []*intotov1.ResourceDescriptor) (*intotov1.Statement, error) {
if len(attestation.InToto.Subjects) == 0 {
attestation.InToto.Subjects = []result.InTotoSubject{{
Kind: gatewaypb.InTotoSubjectKindSelf,
}}
}
subjects := []intoto.Subject{}
subjects := []*intotov1.ResourceDescriptor{}
for _, subject := range attestation.InToto.Subjects {
subjectName := "_"
if subject.Name != "" {
Expand All @@ -110,14 +111,14 @@ func makeInTotoStatement(ctx context.Context, content []byte, attestation export
}

for _, name := range subjectNames {
subjects = append(subjects, intoto.Subject{
subjects = append(subjects, &intotov1.ResourceDescriptor{
Name: name,
Digest: defaultSubject.Digest,
})
}
}
case gatewaypb.InTotoSubjectKindRaw:
subjects = append(subjects, intoto.Subject{
subjects = append(subjects, &intotov1.ResourceDescriptor{
Name: subjectName,
Digest: result.ToDigestMap(subject.Digest...),
})
Expand All @@ -126,13 +127,21 @@ func makeInTotoStatement(ctx context.Context, content []byte, attestation export
}
}

stmt := intoto.Statement{
StatementHeader: intoto.StatementHeader{
Type: intoto.StatementInTotoV01,
PredicateType: attestation.InToto.PredicateType,
Subject: subjects,
},
Predicate: json.RawMessage(content),
var pred map[string]interface{}
err := json.Unmarshal(content, &pred)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal attestation predicate")
}
predicate, err := structpb.NewStruct(pred)
if err != nil {
return nil, errors.Wrap(err, "failed to convert attestation predicate to struct")
}

stmt := intotov1.Statement{
Type: intotov1.StatementTypeUri,
Subject: subjects,
PredicateType: attestation.InToto.PredicateType,
Predicate: predicate,
}
return &stmt, nil
}
4 changes: 2 additions & 2 deletions exporter/attestation/unbundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"

"github.com/containerd/continuity/fs"
intoto "github.com/in-toto/in-toto-golang/in_toto"
intotov1 "github.com/in-toto/attestation/go/v1"
"github.com/moby/buildkit/exporter"
gatewaypb "github.com/moby/buildkit/frontend/gateway/pb"
"github.com/moby/buildkit/session"
Expand Down Expand Up @@ -137,7 +137,7 @@ func unbundle(ctx context.Context, root string, bundle exporter.Attestation) ([]
return nil, err
}
dec := json.NewDecoder(f)
var stmt intoto.Statement
var stmt intotov1.Statement
if err := dec.Decode(&stmt); err != nil {
return nil, errors.Wrap(err, "cannot decode in-toto statement")
}
Expand Down
Loading