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
53 changes: 27 additions & 26 deletions build/provenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/containerd/containerd/v2/core/content/proxy"
"github.com/docker/buildx/util/confutil"
"github.com/docker/buildx/util/progress"
slsa02 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2"
slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/client"
provenancetypes "github.com/moby/buildkit/solver/llbsolver/provenance/types"
Expand All @@ -22,15 +24,6 @@ import (
"golang.org/x/sync/errgroup"
)

type provenancePredicate struct {
Builder *provenanceBuilder `json:"builder,omitempty"`
provenancetypes.ProvenancePredicateSLSA02
}

type provenanceBuilder struct {
ID string `json:"id,omitempty"`
}

func setRecordProvenance(ctx context.Context, c *client.Client, sr *client.SolveResponse, ref string, mode confutil.MetadataProvenanceMode, pw progress.Writer) error {
if mode == confutil.MetadataProvenanceModeDisabled {
return nil
Expand Down Expand Up @@ -69,7 +62,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
continue
}
if ev.Record.Result != nil {
desc := lookupProvenance(ev.Record.Result)
desc, predicateType := lookupProvenance(ev.Record.Result)
if desc == nil {
continue
}
Expand All @@ -78,7 +71,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
if err != nil {
return errors.Wrapf(err, "failed to load provenance blob from build record")
}
prv, err := encodeProvenance(dt, mode)
prv, err := encodeProvenance(dt, predicateType, mode)
if err != nil {
return err
}
Expand All @@ -92,7 +85,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
})
} else if ev.Record.Results != nil {
for platform, res := range ev.Record.Results {
desc := lookupProvenance(res)
desc, predicateType := lookupProvenance(res)
if desc == nil {
continue
}
Expand All @@ -101,7 +94,7 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
if err != nil {
return errors.Wrapf(err, "failed to load provenance blob from build record")
}
prv, err := encodeProvenance(dt, mode)
prv, err := encodeProvenance(dt, predicateType, mode)
if err != nil {
return err
}
Expand All @@ -119,35 +112,43 @@ func fetchProvenance(ctx context.Context, c *client.Client, ref string, mode con
return out, eg.Wait()
}

func lookupProvenance(res *controlapi.BuildResultInfo) *ocispecs.Descriptor {
func lookupProvenance(res *controlapi.BuildResultInfo) (*ocispecs.Descriptor, string) {
for _, a := range res.Attestations {
if a.MediaType == "application/vnd.in-toto+json" && strings.HasPrefix(a.Annotations["in-toto.io/predicate-type"], "https://slsa.dev/provenance/") {
return &ocispecs.Descriptor{
Digest: digest.Digest(a.Digest),
Size: a.Size,
MediaType: a.MediaType,
Annotations: a.Annotations,
}
}, a.Annotations["in-toto.io/predicate-type"]
}
}
return nil
return nil, ""
}

func encodeProvenance(dt []byte, mode confutil.MetadataProvenanceMode) (string, error) {
var prv provenancePredicate
if err := json.Unmarshal(dt, &prv); err != nil {
func encodeProvenance(dt []byte, predicateType string, mode confutil.MetadataProvenanceMode) (string, error) {
var pred *provenancetypes.ProvenancePredicateSLSA1
if predicateType == slsa02.PredicateSLSAProvenance {
var pred02 *provenancetypes.ProvenancePredicateSLSA02
if err := json.Unmarshal(dt, &pred02); err != nil {
return "", errors.Wrapf(err, "failed to unmarshal provenance")
}
pred = provenancetypes.ConvertSLSA02ToSLSA1(pred02)
} else if err := json.Unmarshal(dt, &pred); err != nil {
return "", errors.Wrapf(err, "failed to unmarshal provenance")
}
if prv.Builder != nil && prv.Builder.ID == "" {
// reset builder if id is empty
prv.Builder = nil
}
if mode == confutil.MetadataProvenanceModeMin {
// reset fields for minimal provenance
prv.BuildConfig = nil
prv.Metadata = nil
pred.BuildDefinition.InternalParameters.BuildConfig = nil
pred.RunDetails.Metadata = nil
}
dtprv, err := json.Marshal(prv)
dtprv, err := json.Marshal(struct {
PredicateType string `json:"predicateType"`
provenancetypes.ProvenancePredicateSLSA1
}{
PredicateType: slsa1.PredicateSLSAProvenance,
ProvenancePredicateSLSA1: *pred,
})
if err != nil {
return "", errors.Wrapf(err, "failed to marshal provenance")
}
Expand Down
18 changes: 9 additions & 9 deletions docs/reference/buildx_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,13 @@ executing the build and evaluating [build checks](https://docs.docker.com/refere

For Dockerfiles, the available methods are:

| Command | Description |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `build` (default) | Execute the build and evaluate build checks for the current build target. |
| `check` | Evaluate build checks for the either the entire Dockerfile or the selected target, without executing a build. |
| `outline` | Show the build arguments that you can set for a target, and their default values. |
| `targets` | List all the build targets in the Dockerfile. |
| `subrequests.describe` | List all the frontend methods that the current frontend supports. |
| Command | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------|
| `build` (default) | Execute the build and evaluate build checks for the current build target. |
| `check` | Evaluate build checks for the either the entire Dockerfile or the selected target, without executing a build. |
| `outline` | Show the build arguments that you can set for a target, and their default values. |
| `targets` | List all the build targets in the Dockerfile. |
| `subrequests.describe` | List all the frontend methods that the current frontend supports. |

Note that other frontends may implement these or other methods.
To see the list of available methods for the frontend you're using,
Expand Down Expand Up @@ -948,7 +948,7 @@ $ docker buildx build --secret [type=file,]id=<ID>[,src=<FILEPATH>] .
##### `type=file` attributes

| Key | Description | Default |
| --------------- | ----------------------------------------------------------------------------------------------------- | -------------------------- |
|-----------------|-------------------------------------------------------------------------------------------------------|----------------------------|
| `id` | ID of the secret. | N/A (this key is required) |
| `src`, `source` | Filepath of the file containing the secret value (absolute or relative to current working directory). | `id` if unset. |

Expand Down Expand Up @@ -982,7 +982,7 @@ $ docker buildx build --secret [type=env,]id=<ID>[,env=<VARIABLE>] .
##### `type=env` attributes

| Key | Description | Default |
| ---------------------- | ----------------------------------------------- | -------------------------- |
|------------------------|-------------------------------------------------|----------------------------|
| `id` | ID of the secret. | N/A (this key is required) |
| `env`, `src`, `source` | Environment variable to source the secret from. | `id` if unset. |

Expand Down
10 changes: 8 additions & 2 deletions tests/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/docker/buildx/bake"
"github.com/docker/buildx/util/gitutil"
"github.com/docker/buildx/util/gitutil/gittestutil"
slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/frontend/subrequests/lint"
"github.com/moby/buildkit/identity"
Expand Down Expand Up @@ -1396,9 +1397,14 @@ target "default" {
dtprv, err := json.Marshal(md.Default.BuildProvenance)
require.NoError(t, err)

var prv provenancetypes.ProvenancePredicateSLSA02
type provenancePredicate struct {
PredicateType string `json:"predicateType"`
provenancetypes.ProvenancePredicateSLSA1
}
var prv provenancePredicate
require.NoError(t, json.Unmarshal(dtprv, &prv))
require.Equal(t, provenancetypes.BuildKitBuildType, prv.BuildType)
require.Equal(t, slsa1.PredicateSLSAProvenance, prv.PredicateType)
require.Equal(t, "https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-definitions.md", prv.BuildDefinition.BuildType)
}

func testBakeMetadataWarnings(t *testing.T, sb integration.Sandbox) {
Expand Down
10 changes: 8 additions & 2 deletions tests/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/docker/buildx/util/confutil"
"github.com/docker/buildx/util/gitutil"
"github.com/docker/buildx/util/gitutil/gittestutil"
slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/frontend/subrequests/lint"
"github.com/moby/buildkit/frontend/subrequests/outline"
Expand Down Expand Up @@ -833,9 +834,14 @@ func buildMetadataProvenance(t *testing.T, sb integration.Sandbox, metadataMode
dtprv, err := json.Marshal(md.BuildProvenance)
require.NoError(t, err)

var prv provenancetypes.ProvenancePredicateSLSA02
type provenancePredicate struct {
PredicateType string `json:"predicateType"`
provenancetypes.ProvenancePredicateSLSA1
}
var prv provenancePredicate
require.NoError(t, json.Unmarshal(dtprv, &prv))
require.Equal(t, provenancetypes.BuildKitBuildType, prv.BuildType)
require.Equal(t, slsa1.PredicateSLSAProvenance, prv.PredicateType)
require.Equal(t, "https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-definitions.md", prv.BuildDefinition.BuildType)
}

func testBuildMetadataWarnings(t *testing.T, sb integration.Sandbox) {
Expand Down