Back to Buildkit

SLSA provenance

docs/attestations/slsa-provenance.md

0.29.010.2 KB
Original Source

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:

  • Build parameters and environment.
  • Build timestamps.
  • Version control metadata for your build sources.
  • Build dependencies with their immutable checksums. For example, base images or external URLs used by the build.
  • Descriptions of all build steps, with their source and layer mappings.

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.

Build with provenance attestations

To build an image with provenance attestations using buildctl, use the attest:provenance option:

bash
buildctl build \
    --frontend=dockerfile.v0 \
    --local context=. \
    --local dockerfile=. \
    --opt attest:provenance=

You can also customize the attestations using parameters:

bash
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.

Parameters

ParameterTypeDefaultDescription
modemin,maxmaxConfigures the amount of provenance to be generated. See mode
builder-idStringExplicitly set SLSA Builder ID field. See builder-id
filenameStringprovenance.jsonSet filename for provenance attestation when exported with local or tar exporter
reproducibletrue,falsefalseExplicitly marked as reproducible. See reproducible
inline-onlytrue,falsefalseOnly embed provenance into exporters that support inline content. See inline-only
versionStringv1SLSA provenance version to use (v0.2 or v1)

mode

Provenance 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:

  • Build timestamps
  • The frontend used
  • The build materials

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:

  • The source Dockerfile, and rich layer metadata with sourcemaps to connect the source with the build result
  • The values of passed build arguments
  • Metadata about secrets and ssh mounts

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-id

Depends on the SLSA version used:

SLSA versionField
v1runDetails.builder.id
v0.2builder.id

reproducible

Depends on the SLSA version used:

SLSA versionField
v1[runDetails.metadata.buildkit_reproducible
v0.2metadata.reproducible

inline-only

By 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.

Output

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:

dockerfile
FROM alpine:latest

Results in a provenance attestation similar to the following, for a mode=min build:

json
{
  "_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:

json
{
  "_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
                }
              ]
            ]
          }
        }
      }
    }
  }
}