SLSA 定義 (供應鏈層級安全保證定義)

BuildKit 支援為其執行的建置建立 SLSA 出處證明

BuildKit 產生的出處證明格式由 SLSA 出處證明格式builder.id

對應於 SLSA `builder.id` ....

包含在 `mode=min` 和 `mode=max` 中。

如果有的話,`builder.id` 欄位會設定為建置的 URL。

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

可以使用 `builder-id` 證明參數設定此值。

buildType

對應於 SLSA `buildType` ....

包含在 `mode=min` 和 `mode=max` 中。

`buildType` 欄位設定為 `https://mobyproject.org/buildkit@v1`,可用於判斷出處證明內容的結構。

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

invocation.configSource

對應於 SLSA `invocation.configSource` ....

包含在 `mode=min` 和 `mode=max` 中。

描述初始化建置的設定。

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

對於從遠端上下文(例如 Git 或 HTTP URL)初始化的建置,此物件會在 `uri` 和 `digest` 欄位中定義上下文 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=min` 和 `mode=max` 中

  • locals 列出建置過程中使用的任何本地來源,包括建置上下文和前端檔案。

  • frontend 定義建置所使用的 BuildKit 前端類型。目前,可以是 dockerfile.v0gateway.v0

  • args 定義傳遞給 BuildKit 前端的建置參數。

    args 物件中的鍵反映了 BuildKit 接收到的選項。例如,build-arglabel 前綴分別用於建置參數和標籤,而 target 鍵定義了已建置的目標階段。source 鍵定義了 Gateway 前端的來源映像檔(如果有的話)。

以下欄位僅在 mode=max 時包含

  • secrets 定義建置期間使用的密鑰。請注意,實際的密鑰值不包含在內。
  • ssh 定義建置期間使用的 ssh 轉發。

invocation.environment

對應於 SLSA invocation.environment

包含在 `mode=min` 和 `mode=max` 中。

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

BuildKit 目前設定的唯一值是目前建置機器的 platform(平台)。請注意,這不一定是建置結果的平台,建置結果的平台可以從 in-toto 主題欄位中確定。

materials

對應於 SLSA materials

包含在 `mode=min` 和 `mode=max` 中。

定義所有構成建置一部分的外部構件。值取決於構件的類型

  • 包含映像檔程式碼的 Git 儲存庫的 URL
  • 如果您從遠端壓縮檔建置,或是使用 Dockerfile 中的 ADD 命令包含的 HTTP URL
  • 建置期間使用的任何 Docker 映像檔

Docker 映像檔的 URL 將採用 套件 URL

buildConfig

對應於 SLSA buildConfigLLB 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

metadata.buildStartedOn

對應於 SLSA metadata.buildStartedOn

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

metadata.buildFinishedOn

對應於 SLSA metadata.buildFinishedOn

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

metadata.completeness

對應於 SLSA metadata.completeness

包含在 `mode=min` 和 `mode=max` 中。

定義來源資訊是否完整。

如果所有建置參數都包含在 invocation.parameters 欄位中,則 completeness.parameters 為 true。使用 min 模式建置時,建置參數不會包含在來源資訊中,且參數不完整。在沒有使用前端的直接 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=min` 和 `mode=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 陣列包含程式碼本身。如果 BuildKit 前端在建立 LLB 定義時提供了此映射,則此映射會存在。

layers

僅在 mode=max 時包含。

定義在 buildConfig.llbDefinition 中定義的 LLB 建置步驟掛載的層映射到等效層的 OCI 描述元。如果層資料可用,則此映射會存在,通常在證明是針對映像檔或建置步驟將映像檔資料提取為建置一部分時。

vcs

包含在 `mode=min` 和 `mode=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
              }
            ]
          ]
        }
      }
    }
  }
}