Seguridad de imágenes en Kubernetes: cómo proteger la cadena de suministro de containers
Guía práctica de seguridad de imágenes en Kubernetes: escanea, firma y verifica imágenes, endurece bases y protege tu cadena de containers.
Toda carga de trabajo en un clúster de Kubernetes comienza su vida como una imagen de container. Ese solo hecho convierte a la seguridad de imágenes en Kubernetes en la base de la seguridad de la cadena de suministro de containers: si una imagen comprometida o vulnerable llega al scheduler, Kubernetes la descargará fielmente, la ejecutará y le entregará el acceso a la red, los secrets y los privilegios que le otorgaste a la carga de trabajo. El orquestador no juzga lo que hay dentro de la imagen; confía en ella. Proteger esa imagen, y demostrar de dónde vino, es una de las acciones de mayor impacto que un equipo de plataforma o de seguridad puede realizar.
Este artículo es un análisis a fondo de la seguridad de imágenes dentro del panorama más amplio de la seguridad de Kubernetes. Si eres responsable del pipeline que construye e implementa containers, esta es la capa donde el escaneo de imágenes de container, el image signing y la política de admission se unen para proteger tu cadena de suministro de containers.
Por qué la imagen es una superficie de ataque privilegiada en Kubernetes
Una imagen de container es una instantánea congelada de un sistema de archivos: una capa de sistema operativo, runtimes de lenguaje, dependencias de la aplicación, tu código y cualquier configuración que haya quedado incrustada por el camino. Se ensambla a partir de muchas fuentes — imágenes base públicas, registries de paquetes, bibliotecas de terceros, artefactos de build internos — y cada una de ellas es un lugar donde un atacante puede intentar inyectar o explotar algo.
Kubernetes amplifica las consecuencias. Una imagen vulnerable no se implementa una sola vez; se descarga en cada node que programa la carga de trabajo y puede replicarse en decenas o cientos de pods en segundos. Las fallas en la cadena de suministro de software son lo bastante prominentes como para que el OWASP Top 10 (2025) las registre como la categoría A03, lo que refleja con qué frecuencia los atacantes apuntan a las dependencias y los sistemas de build en lugar de a la aplicación en ejecución directamente. En un clúster, la imagen es la forma concentrada de ese riesgo.
Anatomía del riesgo de imagen
Para proteger imágenes de forma deliberada, ayuda ponerle nombre a los distintos tipos de riesgo que conllevan.
Paquetes del sistema operativo
La imagen base incluye el equivalente a toda una distribución de Linux de bibliotecas y utilidades del sistema. Estas acumulan CVEs con el tiempo, y una imagen base que estaba limpia hace seis meses casi con seguridad no lo está hoy. Los paquetes del sistema operativo viejos y sin parchear son la fuente más común de vulnerabilidades de imagen.
Dependencias de la aplicación
Tu app incorpora bibliotecas open-source — npm, PyPI, Maven, módulos Go — y sus dependencias transitivas. Una versión con vulnerabilidades conocidas de una biblioteca en lo profundo del árbol es tan explotable dentro de un container como en cualquier otro lugar, y a menudo más difícil de detectar.
Configuración incorrecta
La forma en que se construye la imagen importa. Ejecutar como root, exponer puertos innecesarios, dejar gestores de paquetes y shells en la imagen final o establecer permisos de archivo demasiado permisivos: todo eso amplía la superficie de ataque incluso cuando no hay ninguna CVE puntual presente.
Secrets incrustados
Los secrets quedan incrustados en las imágenes con más frecuencia de la que a nadie le gustaría: una clave de API en una línea ENV, un token de .npmrc, una clave privada copiada durante un paso de build y nunca eliminada. Como las capas de imagen son inmutables y se guardan en caché, un secret que se commiteó una vez puede persistir en el historial de capas incluso después de que una capa posterior lo "borre".
Provenance
Por último, está la pregunta que pocas imágenes pueden responder por sí solas: ¿de dónde vino esto en realidad? Sin provenance, no puedes distinguir una imagen que tu sistema de CI construyó y aprobó de una que un atacante subió a tu registry con el mismo nombre.
Empieza por la base: imágenes mínimas y non-root
Las victorias de seguridad más baratas ocurren antes de que se ejecute cualquier scanner, al elegir qué entra en la imagen.
Prefiere imágenes base mínimas o distroless. Una imagen distroless contiene tu aplicación y sus dependencias de runtime y poco más — sin shell, sin gestor de paquetes, sin utilidades de propósito general. Eso reduce drásticamente la superficie de ataque (menos paquetes significa menos CVEs) y le complica la vida a un atacante que sí logre ejecución de código, porque no hay shell con el cual pivotear.
Ejecuta como un usuario non-root. Si el proceso dentro del container no necesita root, no le des root.
# Multi-stage build: compile in a full image, ship a minimal one
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./cmd/server
FROM gcr.io/distroless/static:nonroot
COPY --from=build /app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]
Un multi-stage build como este mantiene los compiladores y las herramientas de build completamente fuera del artefacto final, de modo que nunca puedan formar parte de tu superficie de ataque en runtime. Combina imágenes non-root con controles restrictivos a nivel de pod — consulta seguridad de pods en Kubernetes para ver cómo los security contexts y los admission standards imponen non-root y eliminan capabilities en el momento del deploy.
Escaneo de vulnerabilidades: SCA en toda la imagen
No puedes arreglar lo que no puedes ver, y el escaneo de imágenes de container es cómo lo ves. Un escaneo eficaz usa software composition analysis (SCA) para inventariar todo lo que hay en la imagen — tanto paquetes del sistema operativo como dependencias de la aplicación — y cruzar ese inventario con datos de vulnerabilidades.
Dos principios hacen que el escaneo sea realmente útil en lugar de ruido:
Escanea en más de un lugar. Escanea en la CI para que los desarrolladores reciban retroalimentación en el pull request que introdujo una mala dependencia, y escanea en el registry para que las imágenes se reevalúen a medida que se divulgan nuevas CVEs contra artefactos que ya entregaste. Una imagen que pasó la semana pasada puede fallar esta semana cuando se publica una nueva vulnerabilidad crítica; solo el reescaneo continuo detecta eso.
Haz que los builds fallen ante hallazgos críticos. Un escaneo que solo produce un informe se ignora. Conecta el scanner al pipeline de modo que los nuevos hallazgos de severidad crítica (y, cuando corresponda, alta) rompan el build.
# CI step: scan and fail on new critical/high findings
- name: Scan image
run: |
rainforest image scan registry.example.com/app:${GIT_SHA} \
--severity CRITICAL,HIGH \
--fail-on CRITICAL,HIGH \
--ignore-unfixed
Acotar a problemas de alta severidad que tengan corrección mantiene la puerta significativa en lugar de ahogar a los equipos en hallazgos sobre los que no pueden actuar.
Provenance y firma de imágenes
El escaneo te dice qué hay dentro de una imagen. El image signing y la provenance te dicen de dónde vino y si conviene confiar en ella.
La idea es sencilla. Cuando tu pipeline construye una imagen, firma criptográficamente el digest resultante y registra attestations — declaraciones legibles por máquina sobre cómo se produjo la imagen: qué commit de origen, qué sistema de build, qué pasos se ejecutaron. Este es el núcleo del framework SLSA (Supply-chain Levels for Software Artifacts), que describe niveles crecientes de integridad de provenance para un build.
Más adelante, antes de que algo se ejecute, verificas la firma. Si una imagen no está firmada con una clave que tu organización controla, o si su provenance no coincide con tus expectativas, se rechaza. Eso cierra la brecha que un registry por sí solo no puede: incluso si un atacante sube una imagen maliciosa con un nombre legítimo, no llevará una firma válida, y la verificación la detectará.
La firma y la verificación pertenecen al pipeline (firmar en el build, verificar en el deploy) en lugar de ser un ritual manual, de modo que la provenance se imponga automáticamente para cada carga de trabajo.
Seguridad del registry
El registry es donde viven las imágenes entre el build y el deploy, así que merece el mismo cuidado que cualquier otro sistema de producción.
- Usa registries privados para imágenes internas, y sé deliberado sobre desde qué registries externos permites descargar imágenes.
- Impón control de acceso. El acceso de push debe limitarse a los sistemas de CI y a un pequeño conjunto de identidades confiables; unos derechos amplios de push convierten al registry en un punto de inyección fácil.
- Usa tags inmutables. Una vez que una tag apunta a un digest, no debería reapuntarse. Las tags mutables permiten que una imagen cambie por debajo después de haber sido escaneada y aprobada.
- Prohíbe `:latest` en los deployments. Hacer deploy de
:latestsignifica que no puedes decir con certeza qué se está ejecutando, no puedes reproducir un deploy y no puedes vincular una carga de trabajo en ejecución con un escaneo específico. Fija a una tag inmutable o, mejor aún, a un digest (app@sha256:...).
Fijar por digest es la opción más fuerte: el digest es la identidad direccionada por contenido de la imagen, así que no puede cambiar en silencio.
Admission control: aplica la política en la puerta
Todo lo anterior es meramente consultivo hasta que algo se niega a ejecutar imágenes que lo violen. Ese algo es el admission control. Un admission controller de Kubernetes (típicamente un motor de políticas que se ejecuta como un validating admission webhook) inspecciona cada especificación de pod antes de que se programe y puede rechazarla.
Una postura madura de seguridad de imágenes usa el admission control para bloquear:
- Imágenes sin firmar — sin firma válida de una clave confiable, sin admisión.
- Imágenes sin escanear — sin un resultado de escaneo reciente y aprobado, sin admisión.
- Imágenes de alta severidad — imágenes que llevan vulnerabilidades por encima de tu umbral.
- Fuentes no permitidas — imágenes de registries que no están en tu allowlist, o referenciadas por tags mutables como
:latest.
# Illustrative admission policy: require a valid signature and a passing scan
apiVersion: policy.example.com/v1
kind: ImagePolicy
metadata:
name: require-signed-and-scanned
spec:
match:
registries: ["registry.example.com/*"]
rules:
- requireSignature: true # provenance must verify
- requireScanPassed: true # no unresolved CRITICAL/HIGH
- disallowTags: ["latest"] # digest or immutable tag only
onViolation: deny
Este es el punto en que la política se convierte en una garantía: una imagen que se saltó el escaneo o que carece de provenance sencillamente no puede iniciarse.
Drift en runtime
Incluso una imagen perfectamente construida, firmada y admitida puede sufrir drift una vez que está en ejecución. Alguien hace exec en un container e instala un paquete; un proceso escribe nuevos binarios en una capa grabable; una carga de trabajo empieza a comportarse de forma distinta a la imagen a partir de la cual se construyó. Esa divergencia entre la imagen confiable y el container en vivo es el drift en runtime, y socava cada garantía que estableciste en el momento del build y de la admisión.
Las defensas son mayormente preventivas y refuerzan decisiones anteriores: ejecuta los containers con sistemas de archivos raíz de solo lectura siempre que sea posible, elimina capabilities innecesarias, prohíbe la escalada de privilegios y mantén imágenes distroless que no ofrezcan un shell con el cual manipular. Cuanto menos pueda alterarse un container en ejecución, más seguirá siendo la imagen que verificaste la imagen que se está ejecutando.
Shift left en todo el pipeline
Fíjate en el patrón a lo largo de cada sección: cuanto antes se detecta un problema, más barato es corregirlo. Una dependencia vulnerable señalada en el pull request de un desarrollador es un cambio de cinco minutos; la misma dependencia descubierta en una imagen de producción es un incidente. Eso es lo que significa "shift left" en la práctica para las imágenes — empujar las decisiones de imagen base, el SCA, la detección de secrets y la firma lo más temprano posible en el pipeline, sin dejar de imponer la política en las puertas del registry y del admission como respaldo.
Por lo tanto, la seguridad de imágenes no es una sola herramienta, sino una cadena de puntos de control: imagen base, build, escaneo, firma, almacenamiento, admisión y ejecución. Una debilidad en cualquier eslabón socava al resto, que es exactamente por lo que la cadena de suministro de containers debe tratarse como un sistema conectado.
Cómo ayuda Rainforest
Proteger toda esa cadena es más fácil cuando los puntos de control comparten una misma visión de tu software. Rainforest reúne container security y software composition analysis para que puedas escanear imágenes en busca de vulnerabilidades en paquetes del sistema operativo y dependencias de la aplicación, sacar a la luz secrets incrustados y configuraciones incorrectas, y hacer seguimiento de los hallazgos desde el pull request hasta el registry. Como Rainforest también cubre tu infraestructura como código y las dependencias que incorporan tus aplicaciones, los manifests que implementan tus imágenes y las bibliotecas dentro de ellas se evalúan como parte de la misma cadena de suministro en lugar de forma aislada — que es cómo los riesgos de cadena de suministro registrados por OWASP llegan realmente a un clúster.
Si estás desarrollando la seguridad de imágenes en Kubernetes, agenda una demo y recorreremos juntos cómo proteger tu cadena de suministro de containers de extremo a extremo, desde la imagen base hasta la admisión.
Preguntas frecuentes
¿Qué es la seguridad de imágenes en Kubernetes?
La seguridad de imágenes en Kubernetes es la práctica de garantizar que solo se ejecuten en tu clúster imágenes de container confiables y verificadas frente a vulnerabilidades. Como todo pod parte de una imagen, abarca endurecer el contenido de la imagen (imágenes base mínimas, usuarios non-root, sin secrets incrustados), escanear en busca de vulnerabilidades en paquetes del sistema operativo y dependencias de la aplicación, firmar imágenes para demostrar su provenance, proteger el registry que las almacena y usar admission control para bloquear imágenes que no cumplan la política.
¿Cómo escaneo imágenes de container en busca de vulnerabilidades?
Usa un scanner de imágenes de container basado en software composition analysis (SCA) que inventaríe tanto paquetes del sistema operativo como dependencias de la aplicación y los cruce con CVEs conocidas. Ejecuta el escaneo en la CI para que los desarrolladores reciban retroalimentación sobre el cambio que introdujo el problema, y de nuevo en el registry para que las imágenes ya publicadas se reevalúen a medida que se divulgan nuevas vulnerabilidades. Configura el pipeline para que falle el build ante nuevos hallazgos de severidad crítica (y típicamente alta), acotando a problemas con corrección para que la puerta siga siendo accionable.
¿Por qué debería firmar imágenes de container?
La firma demuestra de dónde vino una imagen. Cuando tu pipeline firma el digest de una imagen y registra attestations de provenance (el modelo SLSA), un admission controller puede después verificar esa firma y admitir solo imágenes que tu sistema de build realmente produjo y aprobó. Sin la firma, un atacante que pueda hacer push a tu registry podría sustituir una imagen maliciosa con un nombre legítimo; la verificación de firma detecta exactamente eso, cerrando una brecha que el escaneo y el control de acceso al registry por sí solos no pueden.
¿Debería usar imágenes base distroless o mínimas?
Sí, siempre que tu runtime lo permita. Las imágenes base mínimas y distroless contienen solo tu aplicación y sus dependencias de runtime — sin shell, gestor de paquetes ni utilidades extra — lo que reduce la superficie de ataque, disminuye la cantidad de CVEs que un scanner llegará a encontrar y dificulta la post-explotación porque no hay shell con el cual pivotear. Combínalas con un usuario non-root e, idealmente, un multi-stage build que mantenga los compiladores y las herramientas de build fuera de la imagen final.
¿Cómo evito que se implementen imágenes vulnerables?
Impón la política con un admission controller de Kubernetes. Un validating admission webhook inspecciona cada pod antes de la programación y puede denegar imágenes que estén sin firmar, carezcan de un escaneo reciente aprobado, lleven vulnerabilidades por encima de tu umbral de severidad, provengan de registries que no estén en tu allowlist o usen tags mutables como :latest. Combinar el admission control con el escaneo en la CI y en el registry convierte tu política de imágenes de una recomendación en una garantía impuesta.

Escrito por
Bruno Baldo
CMO
Um pouco de marketing e um pouco de curiosidade e temos a receita pra criar um apaixonado por cyber!

Seguridad en Kubernetes: la guía completa
Guía completa de seguridad en Kubernetes: el modelo de las 4C, superficie de ataque, RBAC, pods, network policies, secrets, cadena de suministro y shift-left.

Kubernetes Pod Security: Standards, Admission y securityContext
Una guía práctica de Kubernetes Pod Security: los Pod Security Standards, el Pod Security Admission y los ajustes de securityContext que mantienen protegidos los pods.

Buenas prácticas de seguridad en Kubernetes: una checklist práctica
Checklist práctica de seguridad en Kubernetes que cubre control plane, RBAC, pods, red, secrets, imágenes y CI para fortalecer tu clúster.
