SLSA 定义

BuildKit 支持为其执行的构建创建 SLSA Provenance

BuildKit 生成的 provenance 格式由SLSA Provenance 格式定义。

本页面描述了 BuildKit 如何填充每个字段,以及在使用 attestations 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 attestations 参数设置此值。

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 前端的构建参数。

    args 对象内部的键反映了 BuildKit 接收到的选项。例如,build-arglabel 前缀用于构建参数和标签,target 键定义了构建的目标阶段。如果使用了 Gateway 前端,source 键定义了其源镜像。

以下字段仅包含于 mode=max

  • secrets 定义了构建期间使用的 secrets。请注意,不包含实际的 secret 值。
  • ssh 定义了构建期间使用的 ssh 转发。

invocation.environment

对应于SLSA invocation.environment

包含于 mode=minmode=max

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

BuildKit 当前唯一设置的值是当前构建机器的 platform。请注意,这不一定是构建结果的平台,构建结果的平台可以从 in-toto subject 字段确定。

materials

对应于SLSA materials

包含于 mode=minmode=max

定义作为构建一部分的所有外部制品。该值取决于制品的类型

  • 包含镜像源代码的 Git 仓库的 URL
  • 如果你是从远程 tarball 构建,或在 Dockerfile 中使用 ADD 命令包含的文件,其 HTTP URL
  • 构建期间使用的任何 Docker 镜像

Docker 镜像的 URL 将采用Package 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

定义 provenance 信息是否完整。

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

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

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

    "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

如果构建是完全独立的(hermetic)并且没有访问网络,则此扩展字段设置为 true。在 Dockerfile 中,如果构建不使用 RUN 命令或通过 --network=none 标志禁用网络,则该构建被认为是完全独立的。

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

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

部分包含于 mode=min

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

    "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 命令检查仓库中的镜像。检查证明将显示 证明存储规范 中描述的格式。

例如,对于基于 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
              }
            ]
          ]
        }
      }
    }
  }
}
页面选项