SLSA 定义

BuildKit 支持为它运行的构建创建 SLSA Provenance。

由 BuildKit 生成的来源格式由 SLSA 来源格式定义。

本页介绍了 BuildKit 如何填充每个字段,以及在生成证明 mode=minmode=max 时是否包含该字段。

builder.id

对应于 SLSA builder.id

包含在 mode=minmode=max 中。

builder.id 字段设置为构建的 URL(如果可用)。

    "builder": {
      "id": "https://github.com/docker/buildx/actions/runs/3709599520"
    },

此值可以使用builder-id证明参数进行设置。

buildType

对应于 SLSA buildType

包含在 mode=minmode=max 中。

buildType 字段设置为 https://mobyproject.org/buildkit@v1 可用于确定 provenance 内容的结构。

    "buildType": "https://mobyproject.org/buildkit@v1",

invocation.configSource

对应于 SLSA invocation.configSource

包含在 mode=minmode=max 中。

描述初始化构建的配置。

    "invocation": {
      "configSource": {
        "uri": "https://github.com/moby/buildkit.git#refs/tags/v0.11.0",
        "digest": {
          "sha1": "4b220de5058abfd01ff619c9d2ff6b09a049bea0"
        },
        "entryPoint": "Dockerfile"
      },
      ...
    },

对于从远程上下文初始化的构建,例如 Git 或 HTTP URL,此对象在 uridigest 字段中定义上下文 URL 及其不可变摘要。 对于使用本地前端的构建,例如 Dockerfile,entryPoint 字段定义了初始化构建的前端文件路径(filename 前端选项)。

invocation.parameters

对应于 SLSA invocation.parameters

部分包含 mode=min

描述传递给构建的构建输入。

    "invocation": {
      "parameters": {
        "frontend": "gateway.v0",
        "args": {
          "build-arg:BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
          "label:FOO": "bar",
          "source": "docker/dockerfile-upstream:master",
          "target": "release"
        },
        "secrets": [
          {
            "id": "GIT_AUTH_HEADER",
            "optional": true
          },
          ...
        ],
        "ssh": [],
        "locals": []
      },
      ...
    },

以下字段在 mode=minmode=max 中都包含:

  • locals 列出构建中使用的任何本地源,包括构建上下文和前端文件。

  • frontend 定义了用于构建的 BuildKit 前端类型。目前, 这可以是 dockerfile.v0gateway.v0

  • args 定义了传递给 BuildKit 前端的构建参数。

    0 对象中的键反映了 BuildKit 接收到的选项。例如,1 和 2 前缀用于构建参数和标签,3 键定义了所构建的目标阶段。4 键定义了网关前端的源镜像(如果使用的话)。

以下字段仅包含在 mode=max 中:

  • secrets 定义了在构建过程中使用的机密。请注意,实际的机密值并未包含在内。
  • ssh 定义了在构建过程中使用的 ssh 转发。

invocation.environment

对应于 SLSA invocation.environment

包含在 mode=minmode=max 中。

    "invocation": {
      "environment": {
        "platform": "linux/amd64"
      },
      ...
    },

The only value BuildKit currently sets is the platform of the current build machine. Note that this is not necessarily the platform of the build result that can be determined from the in-toto subject field.

materials

对应于 SLSA materials

包含在 mode=minmode=max 中。

定义构建中包含的所有外部构件。该值取决于构件的类型:

  • 包含镜像源代码的 Git 代码库的 URL
  • HTTP URL,如果您是从远程 tarball 构建,或者在 Dockerfile 中使用了 ADD 命令包含的
  • 在构建过程中使用的任何 Docker 镜像

Docker 镜像的 URL 将采用 包 URL 格式

所有构建材料将包含工件的不可变校验和。 从可变标签构建时,可以使用摘要信息来确定与构建运行时相比,工件是否已更新。

    "materials": [
      {
        "uri": "pkg:docker/alpine@3.17?platform=linux%2Famd64",
        "digest": {
          "sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
        }
      },
      {
        "uri": "https://github.com/moby/buildkit.git#refs/tags/v0.11.0",
        "digest": {
          "sha1": "4b220de5058abfd01ff619c9d2ff6b09a049bea0"
        }
      },
      ...
    ],

buildConfig

对应于 SLSA buildConfig

仅包含在 mode=max 中。

定义在构建过程中执行的构建步骤。

BuildKit 在内部使用 LLB 定义来执行构建步骤。构建步骤的 LLB 定义在 buildConfig.llbDefinition 字段中定义。

每个 LLB 步骤是 LLB ProtoBuf API 的 JSON 定义。 LLB 图中顶点的依赖关系可以在每个步骤的 inputs 字段中找到。

  "buildConfig": {
    "llbDefinition": [
      {
        "id": "step0",
        "op": {
          "Op": {
            "exec": {
              "meta": {
                "args": [
                  "/bin/sh",
                  "-c",
                  "go build ."
                ],
                "env": [
                  "PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                  "GOPATH=/go",
                  "GOFLAGS=-mod=vendor",
                ],
                "cwd": "/src",
              },
              "mounts": [...]
            }
          },
          "platform": {...},
        },
        "inputs": [
          "step8:0",
          "step2:0",
        ]
      },
      ...
    ]
  },

metadata.buildInvocationId

对应于 SLSA metadata.buildInvocationId

包含在 mode=minmode=max 中。

构建调用的唯一标识符。当使用单个构建请求构建多平台镜像时,此值将被镜像的所有平台版本共享。

    "metadata": {
      "buildInvocationID": "rpv7a389uzil5lqmrgwhijwjz",
      ...
    },

metadata.buildStartedOn

对应于 SLSA metadata.buildStartedOn

包含在 mode=minmode=max 中。

构建开始的时间戳。

    "metadata": {
      "buildStartedOn": "2021-11-17T15:00:00Z",
      ...
    },

metadata.buildFinishedOn

对应于 SLSA metadata.buildFinishedOn

包含在 mode=minmode=max 中。

构建完成的时间戳。

    "metadata": {
      "buildFinishedOn": "2021-11-17T15:01:00Z",
      ...
    },

metadata.completeness

对应于 SLSA metadata.completeness

包含在 mode=minmode=max 中。

定义出处信息是否完整。

completeness.parameters 为真,如果所有构建参数都包含在 invocation.parameters 字段中。使用 min 模式构建时,构建参数不包含在可证明信息中,参数不完整。未使用前端的直接 LLB 构建参数也不完整。

completeness.environment 对于 BuildKit 构建始终为真。

completeness.materials 为真,如果 materials 字段包含了构建的所有依赖项。当从本地目录中的未跟踪源进行构建时,材料是不完整的,而当从远程 Git 仓库构建时,BuildKit 可以跟踪所有材料,此时 completeness.materials 为真。

    "metadata": {
      "completeness": {
        "parameters": true,
        "environment": true,
        "materials": true
      },
      ...
    },

metadata.reproducible

对应于 SLSA metadata.reproducible

定义构建结果是否应该是字节到字节可重现的。用户可以通过reproducible=true证明参数设置此值。

    "metadata": {
      "reproducible": false,
      ...
    },

metadata.https://mobyproject.org/buildkit@v1#hermetic

包含在 mode=minmode=max 中。

此扩展字段在构建是自洽且未访问网络时设置为 true。在 Dockerfile 中,如果构建未使用 RUN 命令或使用 --network=none 标志禁用网络,则该构建是自洽的。

    "metadata": {
      "https://mobyproject.org/buildkit@v1#hermetic": true,
      ...
    },

metadata.https://mobyproject.org/buildkit@v1#metadata

部分包含 mode=min

此扩展字段定义了不属于 SLSA 凭证规范的 BuildKit 特定附加元数据。

    "metadata": {
      "https://mobyproject.org/buildkit@v1#metadata": {
        "source": {...},
        "layers": {...},
        "vcs": {...},
      },
      ...
    },

source

仅包含在 mode=max 中。

定义了 LLB 构建步骤的源映射,这些步骤在 buildConfig.llbDefinition 字段中定义,映射到它们的原始源代码(例如, Dockerfile 命令)。 source.locations 字段包含在 LLB 步骤中执行的所有 Dockerfile 命令的范围。 source.infos 数组包含源代码本身。如果在创建 LLB 定义时,BuildKit 前端提供了此映射,则会存在此映射。

layers

仅包含在 mode=max 中。

定义在buildConfig.llbDefinition中定义的LLB构建步骤挂载的层映射到等效层的OCI描述符。当层数据可用时会出现此映射,通常是在为镜像进行签名时,或者构建步骤在构建过程中拉取了镜像数据时。

vcs

包含在 mode=minmode=max 中。

为构建所使用的版本控制系统定义可选的元数据。如果构建使用来自 Git 仓库的远程上下文,BuildKit 会自动提取版本控制系统的详细信息并显示在 invocation.configSource 字段中。但如果构建使用的是来自本地目录的源代码,即使该目录包含 Git 仓库,VCS 信息也会丢失。在这种情况下,构建客户端可以发送额外的 vcs:sourcevcs:revision 构建选项,BuildKit 将把这些选项添加到来源证明中作为额外的元数据。请注意,与 invocation.configSource 字段不同,BuildKit 不会验证 vcs 的值,因此不能信任这些值,只能将其作为元数据提示使用。

输出

要检查生成并附加到容器镜像的出处, 您可以使用 docker buildx imagetools 命令在注册表中检查镜像。检查 attestation 会显示 attestation 存储规范 中描述的格式。

例如,检查基于 alpine:latest 的简单 Docker 镜像会产生类似于以下内容的出处证明,适用于 mode=min 构建:

{
  "_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/alpine@latest?platform=linux%2Famd64",
        "digest": {
          "sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "Dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {},
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dockerfile"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64"
      }
    },
    "metadata": {
      "buildInvocationID": "yirbp1aosi1vqjmi3z6bc75nb",
      "buildStartedOn": "2022-12-08T11:48:59.466513707Z",
      "buildFinishedOn": "2022-12-08T11:49:01.256820297Z",
      "reproducible": false,
      "completeness": {
        "parameters": true,
        "environment": true,
        "materials": false
      },
      "https://mobyproject.org/buildkit@v1#metadata": {}
    }
  }
}

对于类似的构建,但使用 mode=max

{
  "_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/alpine@latest?platform=linux%2Famd64",
        "digest": {
          "sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
        }
      }
    ],
    "invocation": {
      "configSource": {
        "entryPoint": "Dockerfile"
      },
      "parameters": {
        "frontend": "dockerfile.v0",
        "args": {},
        "locals": [
          {
            "name": "context"
          },
          {
            "name": "dockerfile"
          }
        ]
      },
      "environment": {
        "platform": "linux/amd64"
      }
    },
    "buildConfig": {
      "llbDefinition": [
        {
          "id": "step0",
          "op": {
            "Op": {
              "source": {
                "identifier": "docker-image://docker.io/library/alpine:latest@sha256:8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
              }
            },
            "platform": {
              "Architecture": "amd64",
              "OS": "linux"
            },
            "constraints": {}
          }
        },
        {
          "id": "step1",
          "op": {
            "Op": null
          },
          "inputs": ["step0:0"]
        }
      ]
    },
    "metadata": {
      "buildInvocationID": "46ue2x93k3xj5l463dektwldw",
      "buildStartedOn": "2022-12-08T11:50:54.953375437Z",
      "buildFinishedOn": "2022-12-08T11:50:55.447841328Z",
      "reproducible": false,
      "completeness": {
        "parameters": true,
        "environment": true,
        "materials": false
      },
      "https://mobyproject.org/buildkit@v1#metadata": {
        "source": {
          "locations": {
            "step0": {
              "locations": [
                {
                  "ranges": [
                    {
                      "start": {
                        "line": 1
                      },
                      "end": {
                        "line": 1
                      }
                    }
                  ]
                }
              ]
            }
          },
          "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": "q2jnwdkas0i0iu4knchd92jaz",
                          "local.sharedkeyhint": "dockerfile"
                        }
                      }
                    },
                    "constraints": {}
                  }
                },
                {
                  "id": "step1",
                  "op": {
                    "Op": null
                  },
                  "inputs": ["step0:0"]
                }
              ]
            }
          ]
        },
        "layers": {
          "step0:0": [
            [
              {
                "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
                "digest": "sha256:c158987b05517b6f2c5913f3acef1f2182a32345a304fe357e3ace5fadcad715",
                "size": 3370706
              }
            ]
          ]
        }
      }
    }
  }
}