mirror of https://github.com/docker/docs.git
build: add attestation docs (#16358)
Signed-off-by: David Karlsson <david.karlsson@docker.com>
This commit is contained in:
parent
e9cbddad67
commit
cc0021f9bc
|
@ -1,6 +1,7 @@
|
|||
ARM
|
||||
AWS
|
||||
Amazon
|
||||
Anchore
|
||||
Apple
|
||||
Artifactory
|
||||
Azure( Blob Storage)?
|
||||
|
@ -43,7 +44,10 @@ QEMU
|
|||
RHEL
|
||||
Raspbian
|
||||
S3
|
||||
SBOMs?
|
||||
SLES
|
||||
SLSA
|
||||
SPDX
|
||||
SQLite
|
||||
Slack
|
||||
Snyk
|
||||
|
|
|
@ -214,3 +214,9 @@ fetch-remote:
|
|||
- dest: "build/buildkit/toml-configuration.md"
|
||||
src:
|
||||
- "docs/buildkitd.toml.md"
|
||||
- dest: "build/attestations/slsa-definitions.md"
|
||||
src:
|
||||
- "docs/attestations/slsa-definitions.md"
|
||||
- dest: "build/attestations/attestation-storage.md"
|
||||
src:
|
||||
- "docs/attestations/attestation-storage.md"
|
||||
|
|
|
@ -1643,6 +1643,18 @@ manuals:
|
|||
title: Build contexts and linking targets
|
||||
- path: /build/bake/compose-file/
|
||||
title: Building from Compose file
|
||||
- sectiontitle: Attestations
|
||||
section:
|
||||
- path: /build/attestations/
|
||||
title: Overview
|
||||
- path: /build/attestations/sbom/
|
||||
title: SBOM
|
||||
- path: /build/attestations/slsa-provenance/
|
||||
title: Provenance
|
||||
- path: /build/attestations/slsa-definitions/
|
||||
title: SLSA definitions
|
||||
- path: /build/attestations/attestation-storage/
|
||||
title: Attestation storage
|
||||
- sectiontitle: BuildKit
|
||||
section:
|
||||
- path: /build/buildkit/
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
> This feature is supported in BuildKit version `{{ include.buildkit_v }}`
|
||||
> and Buildx version `{{ include.buildx_v }}`.
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: Attestation storage
|
||||
description: "How SBOM and provenance attestations are stored for images."
|
||||
keywords: build, attestations, sbom, provenance, storage, manifest
|
||||
fetch_remote:
|
||||
line_start: 2
|
||||
line_end: -1
|
||||
---
|
|
@ -0,0 +1,149 @@
|
|||
---
|
||||
title: Build attestations
|
||||
keywords: build, attestations, sbom, provenance
|
||||
description: >
|
||||
Introduction to SBOM and provenance attestations with Docker Build; what they
|
||||
are and why they exist
|
||||
---
|
||||
|
||||
{% include build-feature-state.md buildkit_v=">=0.11" buildx_v=">=0.10" %}
|
||||
|
||||
Build attestations describe how an image was built, and what it contains. The
|
||||
attestations are created at build-time by BuildKit, and become attached to the
|
||||
final image as metadata.
|
||||
|
||||
The purpose of attestations is to make it possible to inspect an image and see
|
||||
where it comes from, who created it and how, and what it contains. This enables
|
||||
you to make informed decisions about how an image impacts the supply chain security
|
||||
of your application. It also enables the use of policy engines for validating
|
||||
images based on policy rules you've defined.
|
||||
|
||||
Two types of build annotations are available:
|
||||
|
||||
- Software Bill of Material (SBOM): list of software artifacts that an image
|
||||
contains, or that were used to build the image.
|
||||
- Provenance: how an image was built.
|
||||
|
||||
## Purpose of attestations
|
||||
|
||||
The use of open source and third-party packages is more widespread than ever
|
||||
before. Developers share and reuse code because it helps increase productivity,
|
||||
allowing teams to create better products, faster.
|
||||
|
||||
Importing and using code created elsewhere without vetting it introduces a
|
||||
severe security risk. Even if you do review the software that you consume, new
|
||||
zero-day vulnerabilities are frequently discovered, requiring development teams
|
||||
take action to remediate them.
|
||||
|
||||
Build attestations make it easier to see the contents of an image, and where it
|
||||
comes from. Use attestations to analyze and decide whether to use an image, or
|
||||
to see if images you are already using are exposed to vulnerabilities.
|
||||
|
||||
## Creating attestations
|
||||
|
||||
When you build an image with `docker buildx build`, you can add attestation
|
||||
records to the resulting image using the `--provenance` and `--sbom` options.
|
||||
You can opt in to add either the SBOM or provenance attestation type, or both.
|
||||
|
||||
```console
|
||||
$ docker buildx build --sbom=true --provenance=true .
|
||||
```
|
||||
|
||||
BuildKit generates the attestations when building the image. The attestation
|
||||
records are wrapped in the in-toto JSON format and attached it to the image
|
||||
index in a manifest for the final image.
|
||||
|
||||
## Storage
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
BuildKit produces attestations in the
|
||||
[in-toto format](https://github.com/in-toto/attestation){: target="blank" rel="noopener" class="\_" },
|
||||
as defined by the
|
||||
[in-toto framework](https://in-toto.io/){: target="blank" rel="noopener" class="\_" },
|
||||
a standard supported by the Linux Foundation.
|
||||
|
||||
Attestations attach to images as a manifest in the image index. The data records
|
||||
of the attestations are stored as JSON blobs.
|
||||
|
||||
Because attestations attach to images as a manifest, it means that you can
|
||||
inspect the attestations for any image in a registry without having to pull the
|
||||
whole image.
|
||||
|
||||
All BuildKit exporters support attestations. The `local` and `tar` can't save
|
||||
the attestations to an image manifest, since it's outputting a directory of
|
||||
files or a tarball, not an image. Instead, these exporters write the
|
||||
attestations to one or more JSON files in the root directory of the export.
|
||||
|
||||
The following example shows a truncated in-toto JSON representation of an SBOM
|
||||
attestation.
|
||||
|
||||
```json
|
||||
{
|
||||
"_type": "https://in-toto.io/Statement/v0.1",
|
||||
"predicateType": "https://spdx.dev/Document",
|
||||
"subject": [
|
||||
{
|
||||
"name": "pkg:docker/<registry>/<image>@<tag/digest>?platform=<platform>",
|
||||
"digest": {
|
||||
"sha256": "e8275b2b76280af67e26f068e5d585eb905f8dfd2f1918b3229db98133cb4862"
|
||||
}
|
||||
}
|
||||
],
|
||||
"predicate": {
|
||||
"SPDXID": "SPDXRef-DOCUMENT",
|
||||
"creationInfo": {
|
||||
"created": "2022-12-15T11:47:54.546747383Z",
|
||||
"creators": ["Organization: Anchore, Inc", "Tool: syft-v0.60.3"],
|
||||
"licenseListVersion": "3.18"
|
||||
},
|
||||
"dataLicense": "CC0-1.0",
|
||||
"documentNamespace": "https://anchore.com/syft/dir/run/src/core-da0f600b-7f0a-4de0-8432-f83703e6bc4f",
|
||||
"name": "/run/src/core",
|
||||
// list of files that the image contains, e.g.:
|
||||
"files": [
|
||||
{
|
||||
"SPDXID": "SPDXRef-1ac501c94e2f9f81",
|
||||
"comment": "layerID: sha256:9b18e9b68314027565b90ff6189d65942c0f7986da80df008b8431276885218e",
|
||||
"fileName": "/bin/busybox",
|
||||
"licenseConcluded": "NOASSERTION"
|
||||
}
|
||||
],
|
||||
// list of packages that were identified for this image:
|
||||
"packages": [
|
||||
{
|
||||
"name": "busybox",
|
||||
"originator": "Person: Sören Tempel <soeren+alpine@soeren-tempel.net>",
|
||||
"sourceInfo": "acquired package info from APK DB: lib/apk/db/installed",
|
||||
"versionInfo": "1.35.0-r17",
|
||||
"SPDXID": "SPDXRef-980737451f148c56",
|
||||
"description": "Size optimized toolbox of many common UNIX utilities",
|
||||
"downloadLocation": "https://busybox.net/",
|
||||
"licenseConcluded": "GPL-2.0-only",
|
||||
"licenseDeclared": "GPL-2.0-only"
|
||||
// ...
|
||||
}
|
||||
],
|
||||
// files-packages relationship
|
||||
"relationships": [
|
||||
{
|
||||
"relatedSpdxElement": "SPDXRef-1ac501c94e2f9f81",
|
||||
"relationshipType": "CONTAINS",
|
||||
"spdxElementId": "SPDXRef-980737451f148c56"
|
||||
},
|
||||
...
|
||||
],
|
||||
"spdxVersion": "SPDX-2.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
To deep-dive into the specifics about how attestations are stored, see
|
||||
[Image Attestation Storage (BuildKit)](https://github.com/moby/buildkit/blob/master/docs/attestation-storage.md){: target="blank" rel="noopener" class="_"}.
|
||||
|
||||
## What's next
|
||||
|
||||
Learn more about the available attestation types and how to use them:
|
||||
|
||||
- [Provenance](slsa-provenance.md)
|
||||
- [SBOM](sbom.md)
|
|
@ -0,0 +1,290 @@
|
|||
---
|
||||
title: SBOM attestations
|
||||
keywords: build, attestations, sbom
|
||||
description: SBOM build attestations
|
||||
---
|
||||
|
||||
{% include build-feature-state.md buildkit_v=">=0.11" buildx_v=">=0.10" %}
|
||||
|
||||
Software Bill of Materials (SBOM) attestations describe what software artifacts
|
||||
an image contains, and artifacts used to create the image. Metadata included in
|
||||
an SBOM for describing software artifacts may include:
|
||||
|
||||
- Name of the artifact
|
||||
- Version
|
||||
- License type
|
||||
- Authors
|
||||
- Unique package identifier
|
||||
|
||||
There are benefits to indexing contents of an image during the build, as opposed
|
||||
to scanning a final image. When scanning happens as part of the build, you're
|
||||
able to detect software you use to build the image, that may not show up in the
|
||||
final image.
|
||||
|
||||
The SBOMs generated by BuildKit follow the SPDX standard. SBOMs attach to the
|
||||
final image as a JSON-encoded SPDX document, using the format defined by the
|
||||
[in-toto SPDX predicate](https://github.com/in-toto/attestation/blob/main/spec/predicates/spdx.md){:
|
||||
target="blank" rel="noopener" }.
|
||||
|
||||
## Create SBOM attestations
|
||||
|
||||
To create a provenance attestation, pass the `--attest type=sbom` option to the
|
||||
`docker buildx build` command:
|
||||
|
||||
```console
|
||||
$ docker buildx build --tag <namespace>/<image>:<version> \
|
||||
--attest type=sbom --push .
|
||||
```
|
||||
|
||||
Alternatively, you can use the shorthand `--sbom=true` option instead of `--attest type=sbom`.
|
||||
|
||||
## Verify SBOM attestations
|
||||
|
||||
Always validate the generated SBOM for your image before you push your image to a registry.
|
||||
|
||||
To validate, you can build the image using the `local` exporter.
|
||||
Building with the `local` exporter saves the build result to your local filesystem instead of creating an image.
|
||||
Attestations are written to a JSON file in the root directory of your export.
|
||||
|
||||
```console
|
||||
$ docker buildx build \
|
||||
--sbom=true \
|
||||
--output type=local,dest=out .
|
||||
```
|
||||
|
||||
The SBOM file appears in the root directory of the output, named `sbom.spdx.json`:
|
||||
|
||||
```console
|
||||
$ ls -1 ./out | grep sbom
|
||||
sbom.spdx.json
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
By default, BuildKit only scans the final stage of an image. The resulting SBOM
|
||||
doesn't include build-time dependencies installed in earlier stages, or that
|
||||
exist in the build context. This may cause you to overlook vulnerabilities in
|
||||
those dependencies, which could impact the security of your final build
|
||||
artifacts.
|
||||
|
||||
For instance, you might use [multi-stage builds](../building/multi-stage.md),
|
||||
with a `FROM scratch` stanza for your final stage to achieve a smaller image size.
|
||||
|
||||
```dockerfile
|
||||
FROM alpine AS build
|
||||
# build the software ...
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /path/to/bin /bin
|
||||
ENTRYPOINT [ "/bin" ]
|
||||
```
|
||||
|
||||
Scanning the resulting image built using this Dockerfile example would not
|
||||
reveal build-time dependencies used in the `build` stage.
|
||||
|
||||
To include build-time dependencies from your Dockerfile, you can set the build
|
||||
arguments `BUILDKIT_SBOM_SCAN_CONTEXT` and `BUILDKIT_SBOM_SCAN_STAGE`. This
|
||||
expands the scanning scope to include the build context and additional stages.
|
||||
|
||||
You can set the arguments as global arguments (after declaring the Dockerfile
|
||||
syntax directive, before the first `FROM` command) or individually in each
|
||||
stage. If set globally, the value propagates to each stage in the Dockerfile.
|
||||
|
||||
The `BUILDKIT_SBOM_SCAN_CONTEXT` and `BUILDKIT_SBOM_SCAN_STAGE` build arguments
|
||||
are special values. You can't perform variable substitution using these
|
||||
arguments, and you can't set them using environment variables from within the
|
||||
Dockerfile. The only way to set these values is using explicit `ARG` command in
|
||||
the Dockerfile.
|
||||
|
||||
### Scan build context
|
||||
|
||||
To scan the build context, set the `BUILDKIT_SBOM_SCAN_CONTEXT` to `true`.
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
ARG BUILDKIT_SBOM_SCAN_CONTEXT=true
|
||||
FROM alpine AS build
|
||||
# ...
|
||||
```
|
||||
|
||||
You can use the `--build-arg` CLI option to override the value specified in the
|
||||
Dockerfile.
|
||||
|
||||
```console
|
||||
$ docker buildx build --tag <image>:<version> \
|
||||
--attest type=sbom \
|
||||
--build-arg BUILDKIT_SBOM_SCAN_CONTEXT=false .
|
||||
```
|
||||
|
||||
Note that passing the option as a CLI argument only, without having declared it
|
||||
using `ARG` in the Dockerfile, will have no effect. You must specify the `ARG`
|
||||
in the Dockerfile, whereby you can override the context scanning behavior using
|
||||
`--build-arg`.
|
||||
|
||||
### Scan stages
|
||||
|
||||
To scan more than just the final stage, set the `BUILDKIT_SBOM_SCAN_STAGE`
|
||||
argument to true, either globally or in the specific stages that you want to
|
||||
scan. The following table demonstrates the different possible settings for this
|
||||
argument.
|
||||
|
||||
| Value | Description |
|
||||
| ----------------------------------- | ------------------------------------------------------ |
|
||||
| `BUILDKIT_SBOM_SCAN_STAGE=true` | Enables scanning for the current stage |
|
||||
| `BUILDKIT_SBOM_SCAN_STAGE=false` | Disables scanning for the current stage |
|
||||
| `BUILDKIT_SBOM_SCAN_STAGE=base,bin` | Enables scanning for the stages named `base` and `bin` |
|
||||
|
||||
Only stages that are built will be scanned. Stages that aren't dependencies of
|
||||
the target stage won't be built, or scanned.
|
||||
|
||||
The following Dockerfile example uses multi-stage builds to build a static website with
|
||||
[Hugo](https://gohugo.io/){: target="blank" rel="noopener" class="_"}.
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM alpine as hugo
|
||||
ARG BUILDKIT_SBOM_SCAN_STAGE=true
|
||||
WORKDIR /src
|
||||
COPY <<config.yml ./
|
||||
title: My Hugo website
|
||||
config.yml
|
||||
RUN apk add --upgrade hugo && hugo
|
||||
|
||||
FROM scratch
|
||||
COPY --from=hugo /src/public /
|
||||
```
|
||||
|
||||
Setting `ARG BUILDKIT_SBOM_SCAN_STAGE=true` in the `hugo` stage ensures that the final SBOM
|
||||
includes the information that Alpine Linux and Hugo were used to create the website.
|
||||
|
||||
Building this image with the `local` exporter creates two JSON files:
|
||||
|
||||
```console
|
||||
$ docker buildx build \
|
||||
--sbom=true \
|
||||
--output type=local,dest=out .
|
||||
$ ls -1 out | grep sbom
|
||||
sbom-hugo.spdx.json
|
||||
sbom.spdx.json
|
||||
```
|
||||
|
||||
## SBOM attestation example
|
||||
|
||||
The following JSON example shows what an SBOM attestation might look like.
|
||||
|
||||
```json
|
||||
{
|
||||
"_type": "https://in-toto.io/Statement/v0.1",
|
||||
"predicateType": "https://spdx.dev/Document",
|
||||
"subject": [
|
||||
{
|
||||
"name": "pkg:docker/<registry>/<image>@<tag/digest>?platform=<platform>",
|
||||
"digest": {
|
||||
"sha256": "e8275b2b76280af67e26f068e5d585eb905f8dfd2f1918b3229db98133cb4862"
|
||||
}
|
||||
}
|
||||
],
|
||||
"predicate": {
|
||||
"SPDXID": "SPDXRef-DOCUMENT",
|
||||
"creationInfo": {
|
||||
"created": "2022-12-16T15:27:25.517047753Z",
|
||||
"creators": ["Organization: Anchore, Inc", "Tool: syft-v0.60.3"],
|
||||
"licenseListVersion": "3.18"
|
||||
},
|
||||
"dataLicense": "CC0-1.0",
|
||||
"documentNamespace": "https://anchore.com/syft/dir/run/src/core/sbom-cba61a72-fa95-4b60-b63f-03169eac25ca",
|
||||
"name": "/run/src/core/sbom",
|
||||
"packages": [
|
||||
{
|
||||
"SPDXID": "SPDXRef-b074348b8f56ea64",
|
||||
"downloadLocation": "NOASSERTION",
|
||||
"externalRefs": [
|
||||
{
|
||||
"referenceCategory": "SECURITY",
|
||||
"referenceLocator": "cpe:2.3:a:org:repo:\\(devel\\):*:*:*:*:*:*:*",
|
||||
"referenceType": "cpe23Type"
|
||||
},
|
||||
{
|
||||
"referenceCategory": "PACKAGE_MANAGER",
|
||||
"referenceLocator": "pkg:golang/github.com/org/repo@(devel)",
|
||||
"referenceType": "purl"
|
||||
}
|
||||
],
|
||||
"filesAnalyzed": false,
|
||||
"licenseConcluded": "NONE",
|
||||
"licenseDeclared": "NONE",
|
||||
"name": "github.com/org/repo",
|
||||
"sourceInfo": "acquired package info from go module information: bin/server",
|
||||
"versionInfo": "(devel)"
|
||||
},
|
||||
{
|
||||
"SPDXID": "SPDXRef-1b96f57f8fed62d8",
|
||||
"checksums": [
|
||||
{
|
||||
"algorithm": "SHA256",
|
||||
"checksumValue": "0c13f1f3c1636491f716c2027c301f21f9dbed7c4a2185461ba94e3e58443408"
|
||||
}
|
||||
],
|
||||
"downloadLocation": "NOASSERTION",
|
||||
"externalRefs": [
|
||||
{
|
||||
"referenceCategory": "SECURITY",
|
||||
"referenceLocator": "cpe:2.3:a:go-chi:chi\\/v5:v5.0.0:*:*:*:*:*:*:*",
|
||||
"referenceType": "cpe23Type"
|
||||
},
|
||||
{
|
||||
"referenceCategory": "SECURITY",
|
||||
"referenceLocator": "cpe:2.3:a:go_chi:chi\\/v5:v5.0.0:*:*:*:*:*:*:*",
|
||||
"referenceType": "cpe23Type"
|
||||
},
|
||||
{
|
||||
"referenceCategory": "SECURITY",
|
||||
"referenceLocator": "cpe:2.3:a:go:chi\\/v5:v5.0.0:*:*:*:*:*:*:*",
|
||||
"referenceType": "cpe23Type"
|
||||
},
|
||||
{
|
||||
"referenceCategory": "PACKAGE_MANAGER",
|
||||
"referenceLocator": "pkg:golang/github.com/go-chi/chi/v5@v5.0.0",
|
||||
"referenceType": "purl"
|
||||
}
|
||||
],
|
||||
"filesAnalyzed": false,
|
||||
"licenseConcluded": "NONE",
|
||||
"licenseDeclared": "NONE",
|
||||
"name": "github.com/go-chi/chi/v5",
|
||||
"sourceInfo": "acquired package info from go module information: bin/server",
|
||||
"versionInfo": "v5.0.0"
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"relatedSpdxElement": "SPDXRef-1b96f57f8fed62d8",
|
||||
"relationshipType": "CONTAINS",
|
||||
"spdxElementId": "SPDXRef-043f7360d3c66bc31ba45388f16423aa58693289126421b71d884145f8837fe1"
|
||||
},
|
||||
{
|
||||
"relatedSpdxElement": "SPDXRef-b074348b8f56ea64",
|
||||
"relationshipType": "CONTAINS",
|
||||
"spdxElementId": "SPDXRef-043f7360d3c66bc31ba45388f16423aa58693289126421b71d884145f8837fe1"
|
||||
}
|
||||
],
|
||||
"spdxVersion": "SPDX-2.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## SBOM generator
|
||||
|
||||
BuildKit generates the SBOM using a scanner plugin. By default, it uses is the
|
||||
[BuildKit Syft scanner](https://github.com/docker/buildkit-syft-scanner){: target="blank" rel="noopener" }
|
||||
plugin. This plugin is built on top of
|
||||
[Anchore's Syft](https://github.com/anchore/syft){: target="blank" rel="noopener" },
|
||||
an open source tool for generating an SBOM.
|
||||
|
||||
You can select a different plugin to use with the `generator` option, specifying
|
||||
an image that implements the
|
||||
[BuildKit SBOM scanner protocol](https://github.com/moby/buildkit/blob/master/docs/sbom-protocol.md){ :target="blank" rel="noopener" }.
|
||||
|
||||
```console
|
||||
$ docker buildx build --attest type=sbom,generator=<image> .
|
||||
```
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: SLSA definitions
|
||||
description: "How BuildKit populates the fields in the SLSA provenance attestations."
|
||||
keywords: build, attestations, provenance, slsa, definitions, reference
|
||||
fetch_remote:
|
||||
line_start: 2
|
||||
line_end: -1
|
||||
---
|
|
@ -0,0 +1,318 @@
|
|||
---
|
||||
title: Provenance attestations
|
||||
keywords: build, attestations, provenance, slsa
|
||||
description: Provenance build attestations
|
||||
---
|
||||
|
||||
{% include build-feature-state.md buildkit_v=">=0.11" buildx_v=">=0.10" %}
|
||||
|
||||
The provenance attestations include facts about the build process, including
|
||||
details such as:
|
||||
|
||||
- Build timestamps
|
||||
- Build parameters and environment
|
||||
- Version control metadata
|
||||
- Source code details
|
||||
- Materials (files, scripts) consumed during the build
|
||||
|
||||
Provenance attestations follow the
|
||||
[SLSA provenance schema, version 0.2](https://slsa.dev/provenance/v0.2#schema).
|
||||
|
||||
For more information about how BuildKit populates these provenance properties, refer to
|
||||
[SLSA definitions](slsa-definitions.md).
|
||||
|
||||
## Create provenance attestations
|
||||
|
||||
To create a provenance attestation, pass the `--attest type=provenance` option
|
||||
to the `docker buildx build` command:
|
||||
|
||||
```console
|
||||
$ docker buildx build --tag <namespace>/<image>:<version> \
|
||||
--attest type=provenance,mode=[min,max] .
|
||||
```
|
||||
|
||||
Alternatively, you can use the shorthand `--provenance=true` option instead of `--attest type=provenance`.
|
||||
To specify the `mode` parameter using the shorthand option, use: `--provenance=mode=max`.
|
||||
|
||||
## Mode
|
||||
|
||||
You can use the `mode` parameter to define the level of detail to be included in
|
||||
the provenance attestation. Supported values are `mode=min`, and `mode=max`
|
||||
(default).
|
||||
|
||||
### Min
|
||||
|
||||
In `min` mode, the provenance attestations include a minimal set of information,
|
||||
such as:
|
||||
|
||||
- Build timestamps
|
||||
- The frontend used
|
||||
- Build materials
|
||||
- Source repository and revision
|
||||
- Build platform
|
||||
- Reproducibility
|
||||
|
||||
Values of build arguments, the identities of secrets, and rich layer metadata is
|
||||
not included `mode=min`. The `min`-level provenance is safe to use for all
|
||||
builds, as it doesn't leak information from any part of the build environment.
|
||||
|
||||
The following JSON example shows the information included in a provenance
|
||||
attestations created using the `min` mode:
|
||||
|
||||
```json
|
||||
{
|
||||
"_type": "https://in-toto.io/Statement/v0.1",
|
||||
"predicateType": "https://slsa.dev/provenance/v0.2",
|
||||
"subject": [
|
||||
{
|
||||
"name": "pkg:docker/<registry>/<image>@<tag/digest>?platform=<platform>",
|
||||
"digest": {
|
||||
"sha256": "e8275b2b76280af67e26f068e5d585eb905f8dfd2f1918b3229db98133cb4862"
|
||||
}
|
||||
}
|
||||
],
|
||||
"predicate": {
|
||||
"builder": { "id": "" },
|
||||
"buildType": "https://mobyproject.org/buildkit@v1",
|
||||
"materials": [
|
||||
{
|
||||
"uri": "pkg:docker/docker/dockerfile@1",
|
||||
"digest": {
|
||||
"sha256": "9ba7531bd80fb0a858632727cf7a112fbfd19b17e94c4e84ced81e24ef1a0dbc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uri": "pkg:docker/golang@1.19.4-alpine?platform=linux%2Farm64",
|
||||
"digest": {
|
||||
"sha256": "a9b24b67dc83b3383d22a14941c2b2b2ca6a103d805cac6820fd1355943beaf1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"invocation": {
|
||||
"configSource": { "entryPoint": "Dockerfile" },
|
||||
"parameters": {
|
||||
"frontend": "gateway.v0",
|
||||
"args": {
|
||||
"cmdline": "docker/dockerfile:1",
|
||||
"source": "docker/dockerfile:1",
|
||||
"target": "binaries"
|
||||
},
|
||||
"locals": [{ "name": "context" }, { "name": "dockerfile" }]
|
||||
},
|
||||
"environment": { "platform": "linux/arm64" }
|
||||
},
|
||||
"metadata": {
|
||||
"buildInvocationID": "c4a87v0sxhliuewig10gnsb6v",
|
||||
"buildStartedOn": "2022-12-16T08:26:28.651359794Z",
|
||||
"buildFinishedOn": "2022-12-16T08:26:29.625483253Z",
|
||||
"reproducible": false,
|
||||
"completeness": {
|
||||
"parameters": true,
|
||||
"environment": true,
|
||||
"materials": false
|
||||
},
|
||||
"https://mobyproject.org/buildkit@v1#metadata": {
|
||||
"vcs": {
|
||||
"revision": "a9ba846486420e07d30db1107411ac3697ecab68",
|
||||
"source": "git@github.com:<org>/<repo>.git"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Max
|
||||
|
||||
The `max` mode includes all of the information included in the `min` mode, as
|
||||
well as:
|
||||
|
||||
- The LLB definition of the build. These show the exact steps taken to produce
|
||||
the image.
|
||||
- Information about the Dockerfile, including a full base64-encoded version of
|
||||
the file.
|
||||
- Source maps describing the relationship between build steps and image layers.
|
||||
|
||||
When 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
|
||||
[build arguments](../../engine/reference/commandline/buildx_build.md#build-arg)
|
||||
and metadata about secrets and SSH mounts. If you pass sensitive information
|
||||
using build arguments, consider refactoring builds to pass secret values using
|
||||
[build secrets](../../engine/reference/commandline/buildx_build.md#secret), to
|
||||
prevent leaking of sensitive information.
|
||||
|
||||
## Example
|
||||
|
||||
<!-- TODO: add a link to the definitions page, imported from moby/buildkit -->
|
||||
|
||||
The following example shows what a JSON representation of a provenance
|
||||
attestation with `mode=max` looks like:
|
||||
|
||||
```json
|
||||
{
|
||||
"_type": "https://in-toto.io/Statement/v0.1",
|
||||
"predicateType": "https://slsa.dev/provenance/v0.2",
|
||||
"subject": [
|
||||
{
|
||||
"name": "pkg:docker/<registry>/<image>@<tag/digest>?platform=<platform>",
|
||||
"digest": {
|
||||
"sha256": "e8275b2b76280af67e26f068e5d585eb905f8dfd2f1918b3229db98133cb4862"
|
||||
}
|
||||
}
|
||||
],
|
||||
"predicate": {
|
||||
"builder": { "id": "" },
|
||||
"buildType": "https://mobyproject.org/buildkit@v1",
|
||||
"materials": [
|
||||
{
|
||||
"uri": "pkg:docker/docker/dockerfile@1",
|
||||
"digest": {
|
||||
"sha256": "9ba7531bd80fb0a858632727cf7a112fbfd19b17e94c4e84ced81e24ef1a0dbc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uri": "pkg:docker/golang@1.19.4-alpine?platform=linux%2Farm64",
|
||||
"digest": {
|
||||
"sha256": "a9b24b67dc83b3383d22a14941c2b2b2ca6a103d805cac6820fd1355943beaf1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildConfig": {
|
||||
"llbDefinition": [
|
||||
{
|
||||
"id": "step4",
|
||||
"op": {
|
||||
"Op": {
|
||||
"exec": {
|
||||
"meta": {
|
||||
"args": ["/bin/sh", "-c", "go mod download -x"],
|
||||
"env": [
|
||||
"PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"GOLANG_VERSION=1.19.4",
|
||||
"GOPATH=/go",
|
||||
"CGO_ENABLED=0"
|
||||
],
|
||||
"cwd": "/src"
|
||||
},
|
||||
"mounts": [
|
||||
{ "input": 0, "dest": "/", "output": 0 },
|
||||
{
|
||||
"input": -1,
|
||||
"dest": "/go/pkg/mod",
|
||||
"output": -1,
|
||||
"mountType": 3,
|
||||
"cacheOpt": { "ID": "//go/pkg/mod" }
|
||||
},
|
||||
{
|
||||
"input": 1,
|
||||
"selector": "/go.mod",
|
||||
"dest": "/src/go.mod",
|
||||
"output": -1,
|
||||
"readonly": true
|
||||
},
|
||||
{
|
||||
"input": 1,
|
||||
"selector": "/go.sum",
|
||||
"dest": "/src/go.sum",
|
||||
"output": -1,
|
||||
"readonly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"platform": { "Architecture": "arm64", "OS": "linux" },
|
||||
"constraints": {}
|
||||
},
|
||||
"inputs": ["step3:0", "step1:0"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"buildInvocationID": "edf52vxjyf9b6o5qd7vgx0gru",
|
||||
"buildStartedOn": "2022-12-15T15:38:13.391980297Z",
|
||||
"buildFinishedOn": "2022-12-15T15:38:14.274565297Z",
|
||||
"reproducible": false,
|
||||
"completeness": {
|
||||
"parameters": true,
|
||||
"environment": true,
|
||||
"materials": false
|
||||
},
|
||||
"https://mobyproject.org/buildkit@v1#metadata": {
|
||||
"vcs": {
|
||||
"revision": "a9ba846486420e07d30db1107411ac3697ecab68-dirty",
|
||||
"source": "git@github.com:<org>/<repo>.git"
|
||||
},
|
||||
"source": {
|
||||
"locations": {
|
||||
"step4": {
|
||||
"locations": [
|
||||
{
|
||||
"ranges": [
|
||||
{ "start": { "line": 5 }, "end": { "line": 5 } },
|
||||
{ "start": { "line": 6 }, "end": { "line": 6 } },
|
||||
{ "start": { "line": 7 }, "end": { "line": 7 } },
|
||||
{ "start": { "line": 8 }, "end": { "line": 8 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"infos": [
|
||||
{
|
||||
"filename": "Dockerfile",
|
||||
"data": "RlJPTSBhbHBpbmU6bGF0ZXN0Cg==",
|
||||
"llbDefinition": [
|
||||
{
|
||||
"id": "step0",
|
||||
"op": {
|
||||
"Op": {
|
||||
"source": {
|
||||
"identifier": "local://dockerfile",
|
||||
"attrs": {
|
||||
"local.differ": "none",
|
||||
"local.followpaths": "[\"Dockerfile\",\"Dockerfile.dockerignore\",\"dockerfile\"]",
|
||||
"local.session": "s4j58ngehdal1b5hn7msiqaqe",
|
||||
"local.sharedkeyhint": "dockerfile"
|
||||
}
|
||||
}
|
||||
},
|
||||
"constraints": {}
|
||||
}
|
||||
},
|
||||
{ "id": "step1", "op": { "Op": null }, "inputs": ["step0:0"] }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"layers": {
|
||||
"step2:0": [
|
||||
[
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"digest": "sha256:261da4162673b93e5c0e7700a3718d40bcc086dbf24b1ec9b54bca0b82300626",
|
||||
"size": 3259190
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"digest": "sha256:bc729abf26b5aade3c4426d388b5ea6907fe357dec915ac323bb2fa592d6288f",
|
||||
"size": 286218
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"digest": "sha256:7f1d6579712341e8062db43195deb2d84f63b0f2d1ed7c3d2074891085ea1b56",
|
||||
"size": 116878653
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"digest": "sha256:652874aefa1343799c619d092ab9280b25f96d97939d5d796437e7288f5599c9",
|
||||
"size": 156
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue