Skip to content

Commit

Permalink
Migrate to in-toto v1
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Dupuis <cd@atomist.com>
  • Loading branch information
cdupuis committed Oct 19, 2023
1 parent 8dfc926 commit 7399c6c
Show file tree
Hide file tree
Showing 141 changed files with 8,798 additions and 2,710 deletions.
Binary file added .DS_Store
Binary file not shown.
64 changes: 32 additions & 32 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import (
"github.com/containerd/containerd/snapshots"
"github.com/containerd/continuity/fs/fstest"
"github.com/distribution/reference"
intoto "github.com/in-toto/in-toto-golang/in_toto"
intotov1 "github.com/in-toto/attestation/go/v1"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/exporter/containerimage/exptypes"
Expand Down Expand Up @@ -8170,7 +8170,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 @@ -8189,7 +8189,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.Subject{

Check failure on line 8192 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.Subject
{
Name: purls[targets[0]],
Digest: map[string]string{
Expand All @@ -8205,13 +8205,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.Subject{{

Check failure on line 8214 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.Subject
Name: "/attestation.json",
Digest: map[string]string{
"sha256": successDigest.Encoded(),
Expand Down Expand Up @@ -8252,7 +8252,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 @@ -8261,20 +8261,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.Subject{{

Check failure on line 8264 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.Subject
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.Subject{{

Check failure on line 8277 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.Subject
Name: "/attestation.json",
Digest: map[string]string{
"sha256": successDigest.Encoded(),
Expand Down Expand Up @@ -8310,7 +8310,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 @@ -8319,20 +8319,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.Subject{{

Check failure on line 8322 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.Subject
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.Subject{{

Check failure on line 8335 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.Subject
Name: "/attestation.json",
Digest: map[string]string{
"sha256": successDigest.Encoded(),
Expand Down Expand Up @@ -8463,15 +8463,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.Subject{{

Check failure on line 8474 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.Subject
Name: name,
Digest: map[string]string{
"sha256": bases[i].Desc.Digest.Encoded(),
Expand Down Expand Up @@ -8530,9 +8530,9 @@ func testAttestationBundle(t *testing.T, sb integration.Sandbox) {
}
res.AddRef(pk, ref)

stmt := intoto.Statement{
StatementHeader: intoto.StatementHeader{
Type: intoto.StatementInTotoV01,
stmt := intotov1.Statement{
StatementHeader: intotov1.StatementHeader{

Check failure on line 8534 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

unknown field StatementHeader in struct literal of type "github.com/in-toto/attestation/go/v1".Statement

Check failure on line 8534 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.StatementHeader
Type: intotov1.StatementInTotoV01,

Check failure on line 8535 in client/client_test.go

View workflow job for this annotation

GitHub Actions / test (windows-2022)

undefined: intotov1.StatementInTotoV01
PredicateType: "https://example.com/attestations/v1.0",
},
Predicate: map[string]interface{}{
Expand Down Expand Up @@ -8616,13 +8616,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.Subject{{
Name: name,
Digest: map[string]string{
"sha256": bases[i].Desc.Digest.Encoded(),
Expand Down Expand Up @@ -8779,7 +8779,7 @@ EOF
Ref: refAttest,
Path: "/result.spdx",
InToto: result.InTotoAttestation{
PredicateType: intoto.PredicateSPDX,
PredicateType: intotov1.PredicateSPDX,
},
})
}
Expand Down Expand Up @@ -8839,10 +8839,10 @@ 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)
require.Equal(t, intotov1.PredicateSPDX, attest.PredicateType)
require.Subset(t, attest.Predicate, map[string]interface{}{"name": "frontend"})

// test the specified fallback scanner
Expand Down Expand Up @@ -8871,10 +8871,10 @@ 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)
require.Equal(t, intotov1.PredicateSPDX, attest.PredicateType)
require.Subset(t, attest.Predicate, map[string]interface{}{"name": "fallback"})

// test the builtin frontend scanner and the specified fallback scanner together
Expand Down Expand Up @@ -8903,10 +8903,10 @@ 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)
require.Equal(t, intotov1.PredicateSPDX, attest.PredicateType)
require.Subset(t, attest.Predicate, map[string]interface{}{"name": "frontend"})
}

Expand Down Expand Up @@ -9069,10 +9069,10 @@ 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)
require.Equal(t, intotov1.PredicateSPDX, attest.PredicateType)
require.Subset(t, attest.Predicate, map[string]interface{}{"name": "fallback"})
}

Expand Down Expand Up @@ -9175,7 +9175,7 @@ func testSBOMSupplements(t *testing.T, sb integration.Sandbox) {
Ref: refAttest,
Path: "/result.spdx",
InToto: result.InTotoAttestation{
PredicateType: intoto.PredicateSPDX,
PredicateType: intotov1.PredicateSPDX,
},
Metadata: map[string][]byte{
result.AttestationSBOMCore: []byte("result"),
Expand Down Expand Up @@ -9212,12 +9212,12 @@ func testSBOMSupplements(t *testing.T, sb integration.Sandbox) {

att := imgs.Find("unknown/unknown")
attest := struct {
intoto.StatementHeader
intotov1.StatementHeader
Predicate spdx.Document
}{}
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)
require.Equal(t, intotov1.PredicateSPDX, attest.PredicateType)

require.Equal(t, "DOCUMENT", string(attest.Predicate.SPDXIdentifier))
require.Len(t, attest.Predicate.Files, 2)
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 @@ -3,10 +3,11 @@ package attestation
import (
"context"
"encoding/json"
"google.golang.org/protobuf/types/known/structpb"
"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"
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

0 comments on commit 7399c6c

Please sign in to comment.