docs/attestations/slsa-provenance.md
BuildKit supports automatic creation of provenance attestations for the build process. Provenance attestations record information describing how a build was created, and is important for tracking the security of your software artifacts.
Provenance attestations created by BuildKit include details such as:
Provenance generated by BuildKit is wrapped inside in-toto attestations in the SLSA Provenance format (supports both v0.2 and v1).
For more information about how the attestation fields get generated, see SLSA definitions.
To build an image with provenance attestations using buildctl, use the attest:provenance option:
buildctl build \
--frontend=dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--opt attest:provenance=
You can also customize the attestations using parameters:
buildctl build \
--frontend=dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--opt attest:provenance=mode=min,inline-only=true
All BuildKit exporters support attaching attestations to build results.
When the final output format is a container image (image or oci exporter), provenance is attached
to the image using the format described in the attestation storage specification.
When creating a multi-platform image, each platform version of the image gets its own provenance.
If you use the local or tar exporter, the provenance will be written to a file named provenance.json
and exported with your build result, in the root directory.
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | min,max | max | Configures the amount of provenance to be generated. See mode |
builder-id | String | Explicitly set SLSA Builder ID field. See builder-id | |
filename | String | provenance.json | Set filename for provenance attestation when exported with local or tar exporter |
reproducible | true,false | false | Explicitly marked as reproducible. See reproducible |
inline-only | true,false | false | Only embed provenance into exporters that support inline content. See inline-only |
version | String | v1 | SLSA provenance version to use (v0.2 or v1) |
modeProvenance can be generated in one of two modes: min or max. By default,
when provenance is enabled, the mode parameter will be set to max.
In min mode, BuildKit generates only the bare minimum amount of provenance,
including:
However, the values of build arguments, the identities of secrets, and rich
layer metadata will not be included. mode=min should be safe to set on all
builds, as it does not leak information from any part of the build environment.
In max mode, BuildKit generates all of the above, as well as:
Wherever possible, you should prefer mode=max as it contains significantly
more detailed information for analysis. However, on some builds it may not be
appropriate, as it includes the values of various build arguments and metadata
about secrets - these builds should be refactored to prefer passing hidden
values through secrets wherever possible to prevent unnecessary information
leakage.
builder-idDepends on the SLSA version used:
| SLSA version | Field |
|---|---|
v1 | runDetails.builder.id |
v0.2 | builder.id |
reproducibleDepends on the SLSA version used:
| SLSA version | Field |
|---|---|
v1 | [runDetails.metadata.buildkit_reproducible |
v0.2 | metadata.reproducible |
inline-onlyBy default, provenance is by included in all exporters that support
attestations. The inline-only parameter allows configuring this behavior, to
only include the provenance results in exporters that support inline content,
specifically only exporters that produce container images.
Since other exporters produce attestations into separate files, in their filesystems, you may not want to include the provenance in these cases.
To inspect the provenance that was generated and attached to a container image,
you can use the docker buildx imagetools command to inspect the image in a
registry. Inspecting the attestation displays the format described in the
attestation storage specification.
For example, inspecting a simple Docker image based on alpine:latest:
FROM alpine:latest
Results in a provenance attestation similar to the following, for a mode=min
build:
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "pkg:docker/<registry>/<image>@<tag/digest>?platform=<platform>",
"digest": {
"sha256": "e8275b2b76280af67e26f068e5d585eb905f8dfd2f1918b3229db98133cb4862"
}
}
],
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-definitions.md",
"externalParameters": {
"configSource": {
"path": "Dockerfile"
},
"request": {
"frontend": "dockerfile.v0",
"args": {},
"locals": [
{
"name": "context"
},
{
"name": "dockerfile"
}
]
}
},
"internalParameters": {
"builderPlatform": "linux/amd64"
},
"resolvedDependencies": [
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
}
}
]
},
"runDetails": {
"builder": {
"id": ""
},
"metadata": {
"invocationId": "yirbp1aosi1vqjmi3z6bc75nb",
"startedOn": "2022-12-08T11:48:59.466513707Z",
"finishedOn": "2022-12-08T11:49:01.256820297Z",
"buildkit_reproducible": false,
"buildkit_completeness": {
"request": false,
"resolvedDependencies": false
},
"buildkit_metadata": {}
}
}
}
}
For a similar build, but with mode=max:
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "pkg:docker/<registry>/<image>@<tag/digest>?platform=<platform>",
"digest": {
"sha256": "e8275b2b76280af67e26f068e5d585eb905f8dfd2f1918b3229db98133cb4862"
}
}
],
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-definitions.md",
"externalParameters": {
"configSource": {
"path": "Dockerfile"
},
"request": {
"frontend": "dockerfile.v0",
"args": {},
"locals": [
{
"name": "context"
},
{
"name": "dockerfile"
}
]
}
},
"internalParameters": {
"builderPlatform": "linux/amd64",
"buildConfig": {
"llbDefinition": [
{
"id": "step0"
},
{
"id": "step1",
"inputs": [
"step0:0"
]
}
]
}
},
"resolvedDependencies": [
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
}
}
]
},
"runDetails": {
"builder": {
"id": ""
},
"metadata": {
"invocationId": "46ue2x93k3xj5l463dektwldw",
"startedOn": "2022-12-08T11:50:54.953375437Z",
"finishedOn": "2022-12-08T11:50:55.447841328Z",
"buildkit_reproducible": false,
"buildkit_completeness": {
"request": true,
"resolvedDependencies": false
},
"buildkit_metadata": {
"source": {
"infos": [
{
"filename": "Dockerfile"
}
]
},
"layers": {
"step0:0": [
[
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:c158987b05517b6f2c5913f3acef1f2182a32345a304fe357e3ace5fadcad715",
"size": 3370706
}
]
]
}
}
}
}
}
}