Introducción a las políticas de compilación
Las políticas de compilación te permiten validar las entradas de tus compilaciones de Docker antes de que se ejecuten. Este tutorial te guiará en la creación de tu primera política, enseñándote los conceptos básicos de Rego que necesitas a lo largo del proceso.
Qué aprenderás
Al finalizar este tutorial, comprenderás:
- Cómo crear y organizar archivos de políticas
- La sintaxis y patrones básicos de Rego
- Cómo escribir políticas que validen URLs, sumas de comprobación y imágenes
- Cómo se evalúan las políticas durante las compilaciones
Requisitos previos
- Buildx versión 0.31 o posterior
- Familiaridad básica con Dockerfiles y compilación de imágenes
Cómo funcionan las políticas
Cuando compilas una imagen, Buildx resuelve todas las entradas a las que hace
referencia tu Dockerfile: imágenes base de las instrucciones FROM, archivos de
las instrucciones ADD o COPY o contextos de compilación, y repositorios Git.
Antes de ejecutar la compilación, Buildx evalúa tus políticas frente a estas
entradas. Si alguna entrada viola una política, la compilación falla antes de que
se ejecute cualquier instrucción.
Las políticas se escriben en Rego, un lenguaje declarativo diseñado para expresar reglas y restricciones. No necesitas saber Rego para comenzar; este tutorial te enseña lo necesario.
Crea tu primera política
Crea un nuevo directorio para este tutorial y añade un Dockerfile:
$ mkdir tutorial-politicas
$ cd tutorial-politicas
Crea un Dockerfile que descargue un archivo con ADD:
FROM scratch
ADD https://example.com/index.html /index.htmlAhora crea un archivo de política. Las políticas usan la extensión .rego y se
ubican junto a tu Dockerfile. Crea Dockerfile.rego:
package docker
default allow := false
allow if input.local
allow if {
input.http.host == "example.com"
}
decision := {"allow": allow}Guarda este archivo como Dockerfile.rego en el mismo directorio que tu
Dockerfile.
Analicemos lo que hace esta política:
package docker- Todas las políticas de compilación deben comenzar con esta declaración de paquetedefault allow := false- Este ejemplo utiliza una regla de denegación por defecto: si las entradas no coinciden con una reglaallow, la verificación de la política fallaallow if input.local- La primera regla permite cualquier archivo local (tu contexto de compilación)allow if { input.http.host == "example.com" }- La segunda regla permite descargas HTTP desdeexample.comdecision := {"allow": allow}- El objeto de decisión final le indica a Buildx si debe permitir o denegar la entrada
Esta política dice: "Solo permitir archivos locales y descargas HTTP desde
example.com". Rego evalúa todas las reglas de la política para determinar el
valor de retorno de la variable decision para cada entrada de compilación. Las
evaluaciones ocurren en paralelo y bajo demanda; el orden de las reglas de la
política no tiene importancia.
Acerca de input.local
Verás allow if input.local en casi todas las políticas. Esta regla permite el
acceso a archivos locales, lo que incluye tu contexto de compilación
(normalmente, el directorio .) y, lo que es más importante, el propio
Dockerfile. Sin esta regla, Buildx no podría leer tu Dockerfile para iniciar la
compilación.
Incluso las compilaciones que no hacen referencia a ningún archivo del contexto de
compilación a menudo necesitan input.local porque el Dockerfile es un archivo
local. La política se evalúa antes de que comience la compilación, y denegar el
acceso local significa denegar el acceso al Dockerfile.
En casos poco comunes, es posible que desees políticas de archivos locales más estrictas; por ejemplo, en compilaciones de CI donde el contexto de compilación utiliza una URL de Git directamente. En estos casos, podrías querer denegar las fuentes locales para evitar que archivos sin seguimiento o cambios no registrados formen parte de tu compilación.
Carga automática de políticas
Buildx carga automáticamente las políticas que coinciden con el nombre de tu
Dockerfile. Cuando compilas con Dockerfile, Buildx busca Dockerfile.rego en el
mismo directorio. Para un archivo llamado app.Dockerfile, busca
app.Dockerfile.rego.
Esta carga automática significa que no necesitas ninguna bandera de línea de comandos en la mayoría de los casos: simplemente crea el archivo de política y compila.
El archivo de política debe estar en el mismo directorio que el Dockerfile. Si
Buildx no puede encontrar una política coincidente, la compilación continúa sin
la evaluación de la política (a menos que utilices --policy strict=true).
Para obtener más control sobre la carga de políticas, consulta la Guía de uso.
Ejecuta una compilación con tu política
Compila la imagen con la evaluación de políticas habilitada:
$ docker build .
La compilación se realiza con éxito porque la URL de tu Dockerfile coincide con la política. Ahora intenta cambiar la URL en tu Dockerfile por otra cosa:
FROM scratch
ADD https://api.github.com/users/octocat /user.jsonCompila de nuevo:
$ docker build .
Esta vez la compilación falla debido a una violación de la política. El nombre
de host api.github.com no coincide con la regla de tu política, por lo que
Buildx lo rechaza antes de ejecutar cualquier paso de compilación.
Depuración de fallas de políticas
Si tu compilación falla debido a una violación de la política, utiliza
--progress=plain para ver exactamente qué salió mal:
$ docker buildx build --progress=plain .
Esto muestra todas las verificaciones de políticas, los datos de entrada para cada fuente y las decisiones de permitir/denegar. Para obtener una guía de depuración completa, consulta Depuración.
Añadir mensajes de error útiles
Cuando una política deniega una entrada, los usuarios ven un mensaje de error genérico. Puedes proporcionar mensajes personalizados que expliquen por qué se denegó la compilación:
package docker
default allow := false
allow if input.local
allow if {
input.http.host == "example.com"
input.http.schema == "https"
}
deny_msg contains msg if {
not allow
input.http
msg := "solo se permiten descargas HTTPS desde example.com"
}
decision := {"allow": allow, "deny_msg": deny_msg}Now, cuando se deniegue una compilación, los usuarios verán tu mensaje personalizado explicando qué salió mal:
$ docker buildx build .
Policy: solo se permiten descargas HTTPS desde example.com
ERROR: failed to build: ... source not allowed by policy
La regla deny_msg utiliza contains para añadir mensajes a un conjunto. Puedes
añadir múltiples mensajes de denegación para diferentes condiciones de falla para
ayudar a los usuarios a comprender exactamente qué debe cambiar.
Entender las reglas de Rego
Las políticas de Rego se construyen a partir de reglas. Una regla define cuándo se permite algo. El patrón básico es:
allow if {
condition_one
condition_two
condition_three
}Todas las condiciones deben ser verdaderas para que la regla coincida. Piensa en ello como una operación AND: la URL debe coincidir AND la suma de comprobación debe coincidir AND cualquier otra condición que especifiques.
Puedes tener múltiples reglas allow en una sola política. Si alguna regla
coincide, la entrada se permite:
# Permitir descargas desde example.com
allow if {
input.http.host == "example.com"
}
# También permitir descargas desde api.github.com
allow if {
input.http.host == "api.github.com"
}Esto funciona como un OR: la entrada puede coincidir con la primera regla OR con la segunda regla.
Acceder a los campos de entrada
El objeto input te da acceso a la información sobre las entradas de
compilación. La estructura depende del tipo de entrada:
input.http- Archivos descargados conADD https://...input.image- Imágenes de contenedor deFROMoCOPY --frominput.git- Repositorios de Git deADD git://...o del contexto de compilacióninput.local- Contexto de archivos locales
Consulta la Referencia de inputs para conocer todos los campos de entrada disponibles.
Para las descargas HTTP, puedes acceder a:
| Clave | Descripción | Ejemplo |
|---|---|---|
input.http.url | La URL completa | https://example.com/index.html |
input.http.schema | El protocolo (HTTP/HTTPS) | https |
input.http.host | El nombre de host | example.com |
input.http.path | La ruta de la URL, incluyendo params | /index.html |
Actualiza tu política para requerir HTTPS:
package docker
default allow := false
allow if {
input.http.host == "example.com"
input.http.schema == "https"
}
decision := {"allow": allow}Ahora la política requiere tanto que el nombre de host sea example.com como que
el protocolo sea HTTPS. Las URLs HTTP (sin TLS) fallarían la verificación de la
política.
Coincidencia de patrones y cadenas
Rego proporciona funciones integradas para la coincidencia de patrones. Utiliza
startswith() para hacer coincidir prefijos de URL:
allow if {
startswith(input.http.url, "https://example.com/")
}Esto permite cualquier URL que comience con https://example.com/.
Utiliza regex.match() para patrones complejos:
allow if {
regex.match(`^https://example\.com/.+\.json$`, input.http.url)
}Esto coincide con URLs que:
- Comienzan con
https://example.com/ - Terminan con
.json - Tienen al menos un carácter entre el dominio y la extensión
Ubicación del archivo de política
Los archivos de políticas se ubican junto al Dockerfile que validan, utilizando
el patrón de nomenclatura <nombre-dockerfile>.rego:
project/
├── Dockerfile # Dockerfile principal
├── Dockerfile.rego # Política para Dockerfile
├── lint.Dockerfile # Dockerfile de análisis estático (linting)
└── lint.Dockerfile.rego # Política para lint.DockerfileCuando compilas, Buildx carga automáticamente el archivo de política correspondiente:
$ docker buildx build -f Dockerfile . # Carga Dockerfile.rego
$ docker buildx build -f lint.Dockerfile . # Carga lint.Dockerfile.rego
Siguientes pasos
Ahora comprendes cómo escribir políticas de compilación básicas para recursos HTTP. Para continuar aprendiendo:
- Aplicar y probar políticas: Uso de políticas de compilación
- Aprender Validación de imágenes para validar imágenes
de contenedor a partir de instrucciones
FROM - Aprender Validación de Git para validar repositorios de Git utilizados en compilaciones
- Consultar Ejemplos de políticas para políticas listas para copiar y pegar que cubren escenarios comunes
- Escribir pruebas unitarias para tus políticas: Probar políticas de compilación
- Depurar fallas de políticas: Depuración
- Leer la Referencia de inputs para conocer todos los campos de entrada disponibles
- Revisar las Funciones integradas para la verificación de firmas, atestaciones y otras comprobaciones de seguridad