镜像证明存储

Buildkit 支持创建证明并将其附加到构建工件。这些证明可以提供构建过程中的宝贵信息,包括但不限于:软件供应链清单SLSA 来源,构建日志等。

本文档描述了用于存储证明的当前自定义格式,该格式旨在与当今的现有注册表实现兼容。将来,我们可能会支持以其他格式导出证明。

证明存储为镜像索引中的清单对象,类似于 OCI 工件的风格。

属性

证明清单

证明清单附加到根镜像索引对象,位于单独的OCI 镜像清单下。每个证明清单可以包含多个证明 Blob,清单中的所有证明都应用于单个平台清单。标准 OCI 和 Docker 清单的所有属性继续适用。

镜像config 描述符将指向有效的镜像配置,但是,它不包含证明特定详细信息,应予以忽略,因为它仅出于兼容性目的而包含。

layers 中的每个镜像层都将包含单个证明 Blob的描述符。每层的mediaType将根据其内容进行设置,其中之一是

  • application/vnd.in-toto+json(目前,唯一支持的选项)

    指示 in-toto 证明 Blob

任何未知的mediaType都应予以忽略。

为了帮助证明遍历,以下注释可以在每个层描述符上设置

  • in-toto.io/predicate-type

    如果包含的证明是 in-toto 证明(目前,唯一支持的选项),则将设置此注释。注释将被设置为包含与证明中存在的predicateType属性相同的数值。

    如果存在,此注释可用于查找他们要寻找的特定证明,以避免拉取其他证明的内容。

证明 Blob

每层的內容將根据其mediaType而有所不同。

  • application/vnd.in-toto+json

    Blob 内容将包含完整的in-toto 证明语句

    {
      "_type": "https://in-toto.io/Statement/v0.1",
      "subject": [
        {
          "name": "<NAME>",
          "digest": {"<ALGORITHM>": "<HEX_VALUE>"}
        },
        ...
      ],
      "predicateType": "<URI>",
      "predicate": { ... }
    }

    证明的主体应设置为与证明清单描述符中描述的目标清单相同的摘要,或其内部的某个对象。

证明清单描述符

证明清单附加到根镜像索引,在manifests键中,位于所有原始可运行清单之后。标准 OCI 和 Docker 清单描述符的所有属性继续适用。

为了防止容器运行时意外拉取或运行清单中描述的镜像,证明清单的platform属性将设置为unknown/unknown,如下所示

"platform": {
  "architecture": "unknown",
  "os": "unknown"
}

为了帮助索引遍历,以下注释将设置在清单描述符描述符上

  • vnd.docker.reference.type

    此注释描述工件的类型,并将设置为attestation-manifest。如果指定了任何其他值,则应忽略整个清单。

  • vnd.docker.reference.digest

    此注释将包含镜像索引中证明清单引用的对象的摘要。

    如果存在,此注释可用于为所选镜像清单查找匹配的证明清单。

示例

示例:显示附加到linux/amd64镜像的 SBOM 证明

镜像索引(sha256:94acc2ca70c40f3f6291681f37ce9c767e3d251ce01c7e4e9b98ccf148c26260

此镜像索引定义了两个描述符:AMD64 镜像sha256:23678f31..和该镜像的证明清单sha256:02cb9aa7..

{
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "schemaVersion": 2,
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:23678f31b3b3586c4fb318aecfe64a96a1f0916ba8faf9b2be2abee63fa9e827",
      "size": 1234,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:02cb9aa7600e73fcf41ee9f0f19cc03122b2d8be43d41ce4b21335118f5dd943",
      "size": 1234,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:23678f31b3b3586c4fb318aecfe64a96a1f0916ba8faf9b2be2abee63fa9e827",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
         "architecture": "unknown",
         "os": "unknown"
      }
    }
  ]
}

证明清单(sha256:02cb9aa7600e73fcf41ee9f0f19cc03122b2d8be43d41ce4b21335118f5dd943

此证明清单包含一个证明,该证明是一个 in-toto 证明,其中包含一个“https://spdx.dev/Document”谓词,表示它正在为镜像定义 SBOM。

{
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "schemaVersion": 2,
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:a781560066f20ec9c28f2115a95a886e5e71c7c7aa9d8fd680678498b82f3ea3",
    "size": 123
  },
  "layers": [
    {
      "mediaType": "application/vnd.in-toto+json",
      "digest": "sha256:133ae3f9bcc385295b66c2d83b28c25a9f294ce20954d5cf922dda860429734a",
      "size": 1234,
      "annotations": {
        "in-toto.io/predicate-type": "https://spdx.dev/Document"
      }
    }
  ]
}

镜像配置(sha256:a781560066f20ec9c28f2115a95a886e5e71c7c7aa9d8fd680678498b82f3ea3

{
  "architecture": "unknown",
  "os": "unknown",
  "config": {},
  "rootfs": {
    "type": "layers",
    "diff_ids": [
      "sha256:133ae3f9bcc385295b66c2d83b28c25a9f294ce20954d5cf922dda860429734a"
    ]
  }
}

层内容(sha256:1ea07d5e55eb47ad0e6bbfa2ec180fb580974411e623814e519064c88f022f5c

包含 SBOM 数据的证明主体,以 SPDX 格式列出构建期间使用的软件包。

{
  "_type": "https://in-toto.io/Statement/v0.1",
  "predicateType": "https://spdx.dev/Document",
  "subject": [
    {
      "name": "_",
      "digest": {
        "sha256": "23678f31b3b3586c4fb318aecfe64a96a1f0916ba8faf9b2be2abee63fa9e827"
      }
    }
  ],
  "predicate": {
    "SPDXID": "SPDXRef-DOCUMENT",
    "spdxVersion": "SPDX-2.2",
    ...