Atestaciones de procedencia
Las atestaciones de procedencia incluyen datos sobre el proceso de compilación, que abarcan detalles como:
- Marcas de tiempo de la compilación
- Parámetros y entorno de la compilación
- Metadatos del sistema de control de versiones
- Detalles del código fuente
- Materiales (archivos, scripts) consumidos durante la compilación
Por defecto, las atestaciones de procedencia siguen el esquema de procedencia de SLSA, versión 0.2. Opcionalmente, puedes habilitar SLSA Provenance v1 utilizando el parámetro version.
Para obtener más información sobre cómo BuildKit completa estas propiedades de procedencia, consulta las definiciones de SLSA.
Crear atestaciones de procedencia
Para crear una atestación de procedencia, pasa la opción --attest type=provenance al comando docker buildx build:
$ docker buildx build --tag <namespace>/<image>:<version> \
--attest type=provenance,mode=[min,max],version=[v0.2,v1] .
Alternativamente, puedes utilizar la opción abreviada --provenance=true en lugar de --attest type=provenance.
Para especificar los parámetros mode o version utilizando la opción abreviada, usa:
--provenance=mode=max,version=v1.
Para ver un ejemplo sobre cómo añadir atestaciones de procedencia con GitHub Actions, consulta Añadir atestaciones con GitHub Actions.
Modo
Puedes utilizar el parámetro mode para definir el nivel de detalle que se incluirá en la atestación de procedencia. Los valores admitidos son mode=min (predeterminado) y mode=max.
Min
En el modo min, las atestaciones de procedencia incluyen un conjunto mínimo de información, como:
- Marcas de tiempo de la compilación
- El frontend utilizado
- Materiales de la compilación
- Repositorio de origen y revisión
- Plataforma de compilación
- Reproducibilidad
Los valores de los argumentos de compilación, las identidades de los secretos y los metadatos detallados de las capas no se incluyen en mode=min. La procedencia a nivel min es segura de utilizar para todas las compilaciones, ya que no filtra información de ninguna parte del entorno de compilación.
El siguiente ejemplo JSON muestra la información incluida en una atestación de procedencia creada utilizando el modo 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/docker/dockerfile@1",
"digest": {
"sha256": "9ba7531bd80fb0a858632727cf7a112fbfd19b17e94c4e84ced81e24ef1a0dbc"
}
},
{
"uri": "pkg:docker/[email protected]?platform=linux%2Farm64",
"digest": {
"sha256": "a9b24b67dc83b3383d22a14941c2b2b2ca6a103d805cac6820fd1355943beaf1"
}
}
],
"invocation": {
"configSource": { "entryPoint": "Dockerfile" },
"parameters": {
"frontend": "gateway.v0",
"args": {
"cmdline": "docker/dockerfile:1",
"source": "docker/dockerfile:1",
"target": "binaries"
},
"locals": [{ "name": "context" }, { "name": "dockerfile" }]
},
"environment": { "platform": "linux/arm64" }
},
"metadata": {
"buildInvocationID": "c4a87v0sxhliuewig10gnsb6v",
"buildStartedOn": "2022-12-16T08:26:28.651359794Z",
"buildFinishedOn": "2022-12-16T08:26:29.625483253Z",
"reproducible": false,
"completeness": {
"parameters": true,
"environment": true,
"materials": false
},
"https://mobyproject.org/buildkit@v1#metadata": {
"vcs": {
"revision": "a9ba846486420e07d30db1107411ac3697ecab68",
"source": "[email protected]:<org>/<repo>.git"
}
}
}
}
}Max
El modo max incluye toda la información que contiene el modo min, además de:
- La definición LLB de la compilación. Esta muestra los pasos exactos realizados para producir la imagen.
- Información sobre el Dockerfile, incluida una versión completa codificada en base64 del archivo.
- Mapas de origen (source maps) que describen la relación entre los pasos de compilación y las capas de la imagen.
Siempre que sea posible, deberías preferir mode=max, ya que contiene información significativamente más detallada para su análisis.
WarningTen en cuenta que
mode=maxexpone los valores de los argumentos de compilación.Si estás utilizando incorrectamente los argumentos de compilación para pasar credenciales, tokens de autenticación u otros secretos, deberías refactorizar tu compilación para pasar los secretos utilizando montajes de secretos en su lugar. Los montajes de secretos no se filtran fuera de la compilación y nunca se incluyen en las atestaciones de procedencia.
Versión
El parámetro version te permite especificar qué versión del esquema de procedencia de SLSA utilizar. Los valores admitidos son version=v0.2 (predeterminado) y version=v1.
Para utilizar SLSA Provenance v1:
$ docker buildx build --tag <namespace>/<image>:<version> \
--attest type=provenance,mode=max,version=v1 .
Para obtener más información sobre SLSA Provenance v1, consulta la especificación de SLSA. Para ver la diferencia entre las atestaciones de procedencia SLSA v0.2 y v1, consulta las definiciones de SLSA.
Inspección de procedencia
Para explorar la procedencia creada y exportada mediante el exportador image, puedes utilizar
imagetools inspect.
Mediante la opción --format, puedes especificar una plantilla para la salida. Todos los datos relacionados con la procedencia están disponibles bajo el atributo .Provenance. Por ejemplo, para obtener el contenido sin procesar de la procedencia en el formato de SLSA:
$ docker buildx imagetools inspect <namespace>/<image>:<version> \
--format "{{ json .Provenance.SLSA }}"
{
"buildType": "https://mobyproject.org/buildkit@v1",
...
}
También puedes construir expresiones más complejas utilizando la funcionalidad completa de las plantillas de Go. Por ejemplo, para la procedencia generada con mode=max, puedes extraer el código fuente completo del Dockerfile utilizado para compilar la imagen:
$ docker buildx imagetools inspect <namespace>/<image>:<version> \
--format '{{ range (index .Provenance.SLSA.metadata "https://mobyproject.org/buildkit@v1#metadata").source.infos }}{{ if eq .filename "Dockerfile" }}{{ .data }}{{ end }}{{ end }}' | base64 -d
FROM ubuntu:24.04
RUN apt-get update
...
Ejemplo de atestación de procedencia
El siguiente ejemplo muestra cómo se ve una representación JSON de una atestación de procedencia con 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/docker/dockerfile@1",
"digest": {
"sha256": "9ba7531bd80fb0a858632727cf7a112fbfd19b17e94c4e84ced81e24ef1a0dbc"
}
},
{
"uri": "pkg:docker/[email protected]?platform=linux%2Farm64",
"digest": {
"sha256": "a9b24b67dc83b3383d22a14941c2b2b2ca6a103d805cac6820fd1355943beaf1"
}
}
],
"buildConfig": {
"llbDefinition": [
{
"id": "step4",
"op": {
"Op": {
"exec": {
"meta": {
"args": ["/bin/sh", "-c", "go mod download -x"],
"env": [
"PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOLANG_VERSION=1.19.4",
"GOPATH=/go",
"CGO_ENABLED=0"
],
"cwd": "/src"
},
"mounts": [
{ "input": 0, "dest": "/", "output": 0 },
{
"input": -1,
"dest": "/go/pkg/mod",
"output": -1,
"mountType": 3,
"cacheOpt": { "ID": "//go/pkg/mod" }
},
{
"input": 1,
"selector": "/go.mod",
"dest": "/src/go.mod",
"output": -1,
"readonly": true
},
{
"input": 1,
"selector": "/go.sum",
"dest": "/src/go.sum",
"output": -1,
"readonly": true
}
]
}
},
"platform": { "Architecture": "arm64", "OS": "linux" },
"constraints": {}
},
"inputs": ["step3:0", "step1:0"]
}
]
},
"metadata": {
"buildInvocationID": "edf52vxjyf9b6o5qd7vgx0gru",
"buildStartedOn": "2022-12-15T15:38:13.391980297Z",
"buildFinishedOn": "2022-12-15T15:38:14.274565297Z",
"reproducible": false,
"completeness": {
"parameters": true,
"environment": true,
"materials": false
},
"https://mobyproject.org/buildkit@v1#metadata": {
"vcs": {
"revision": "a9ba846486420e07d30db1107411ac3697ecab68-dirty",
"source": "[email protected]:<org>/<repo>.git"
},
"source": {
"locations": {
"step4": {
"locations": [
{
"ranges": [
{ "start": { "line": 5 }, "end": { "line": 5 } },
{ "start": { "line": 6 }, "end": { "line": 6 } },
{ "start": { "line": 7 }, "end": { "line": 7 } },
{ "start": { "line": 8 }, "end": { "line": 8 } }
]
}
]
}
},
"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": "s4j58ngehdal1b5hn7msiqaqe",
"local.sharedkeyhint": "dockerfile"
}
}
},
"constraints": {}
}
},
{ "id": "step1", "op": { "Op": null }, "inputs": ["step0:0"] }
]
}
]
},
"layers": {
"step2:0": [
[
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"digest": "sha256:261da4162673b93e5c0e7700a3718d40bcc086dbf24b1ec9b54bca0b82300626",
"size": 3259190
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"digest": "sha256:bc729abf26b5aade3c4426d388b5ea6907fe357dec915ac323bb2fa592d6288f",
"size": 286218
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"digest": "sha256:7f1d6579712341e8062db43195deb2d84f63b0f2d1ed7c3d2074891085ea1b56",
"size": 116878653
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"digest": "sha256:652874aefa1343799c619d092ab9280b25f96d97939d5d796437e7288f5599c9",
"size": 156
}
]
]
}
}
}
}
}