Introducción

Los equipos de DevOps y seguridad enfrentan un problema concreto: el 80% de las organizaciones que saben que deberían firmar sus imágenes de contenedor aún no lo hacen, según datos de Aqua Security. No es por desinterés, sino porque los flujos de trabajo actuales hacen que implementarlo de manera consistente sea operativamente costoso. Mientras tanto, los ataques a la cadena de suministro de IA ya son realidad: en febrero de 2024, investigadores de JFrog descubrieron más de 100 modelos maliciosos en Hugging Face que ejecutaban shells inversas al cargarse, explotando vulnerabilidades en la deserialización de PyTorch.

Qué ocurrió

El problema central es que las imágenes de contenedor no firmadas permiten a atacantes suplantar paquetes legítimos en cualquier etapa del pipeline de delivery. En febrero de 2025, ReversingLabs documentó el caso nullifAI: dos modelos que evadieron los escáneres de Hugging Face (incluyendo picklescan) al comprimir los payloads maliciosos con 7z en lugar de ZIP y corromper el stream de pickle después de ejecutar el código. Los modelos fueron eliminados en 24 horas, pero el incidentemostró que los escáneres basados en patrones son una barrera temporal: el atacante siempre puede encontrar una variante que los evada.

El riesgo se amplifica con los artifacts de IA: pesos de modelos, datasets de entrenamiento y runtimes de inferencia se distribuyen cada vez más como imágenes OCI. Estos artifacts no tienen CVEs asociados (el payload malicioso en los modelos PyTorch no generó ningún CVE), y los escáneres tradicionales de vulnerabilidades no tienen bases de datos para compararlos. Peor aún: un modelo comprometido puede corromper predicciones a escala, envenenar recomendaciones para millones de usuarios o, en el caso de agentes autónomos, realizar acciones no autorizadas (llamadas a APIs, invocación de herramientas, gasto en cloud).

Impacto para DevOps / Infraestructura / Cloud / Seguridad

Para los equipos de infraestructura, el impacto es multiplícado. Un estudio de Sonatype revealed que el 65% de los ataques a la cadena de suministro en 2023 explotaron vulnerabilidades en dependencias indirectas. En el contexto de IA, esto se extiende a los base images: una imagen base comprometida (como la de XZ Utils en marzo de 2024, CVE-2024-30377) puede propagarse a docenas de servicios downstream antes de ser detectada. En Kubernetes, el riesgo se materializa en el ImagePullPolicy: si se usa Always, los pods pueden pullsear una imagen modificada incluso después de una verificación inicial.

Para los equipos de seguridad, el desafío es la atribución. Sin firmado, un imagen maliciosa en el registry no puede rastrearse a un autor específico. En el incident de XZ Utils, el backdoor estaba presente en los binarios durante meses, pero sin firmado, las organizaciones no podían verificar si sus imágenes eran legítimas o habían sido tamperizadas. Con firmado, el compromise se reduce a un evento auditable: un signing key comprometido.

Detalles técnicos

El firmado de imágenes de contenedor se basa en el estándar OCI Image Signing (part of the Open Container Initiative specifications) y usa frameworks como Cosign (Sigstore) o Notation (CNCF). El proceso tiene tres etapas:

  • Firma: En el momento de build o push, se genera una firma digital que vincula el digest de la imagen (SHA256) con una identidad verificable. Por ejemplo, con Cosign:
  • cosign sign –key cosign.key «docker.io/mi-org/mi-imagen@sha256:12345678…»

    La custodia de la clave privada es crítica. Soluciones como Sigstore’s Keyless Signing eliminan la necesidad de gestionar claves locales, usando identidades de short-lived certificates basadas en OIDC (por ejemplo, autenticación con GitHub Actions).

  • Verificación: Antes de ejecutar la imagen, se valida la firma contra una trust policy. Con Cosign:
  • cosign verify –key cosign.pub «docker.io/mi-org/mi-imagen@sha256:12345678…»

    Las políticas de confianza pueden especificar qué identidades se confía (ej: ci/github.com/mi-org), y requerir que la imagen esté firmada por al menos una de ellas.

  • Aplicación: En Kubernetes, se usa un admission controller como Kyverno para bloquear imágenes no firmadas. Un ClusterPolicy ejemplo:
  • apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
    name: check-image-signature
    spec:
    validationRules:
    – rule: «verify-cosign-signature»
    message: «La imagen debe estar firmada con Cosign»
    check:
    verifyCosignSignature: {}

    Los registries modernos (Amazon ECR, Google Artifact Registry, GitHub Container Registry) pueden gestionar el firmado de forma transparente. Por ejemplo, ECR supports image signing with AWS Signer y puede rechazar pushes de imágenes no firmadas a nivel de repository. Esto resuelve el problema de consistencia: el registry firma automáticamente al push, y verifica automáticamente al pull, sin requerir cambios en los flujos de CI/CD.

    Qué deberían hacer los administradores y equipos técnicos

  • Habilitar firmado gestionado por el registry:
  • – En Amazon ECR: Activar ECR image scanning and signing con AWS Signer. Configurar una signing profile y asociarla al repository:

    aws signer put-signing-profile –profile-name mi-perfil –platform-id «Platform/EC2»
    aws ecr put-image-scanning-configuration –repository-name mi-repo –scan-on-push true

    Luego, configurar el registry para rechazar images no firmadas:

    aws ecr put-repository-policy –repository-name mi-repo –policy-name reject-unsigned {
    «Version»: «2012-10-17»,
    «Statement»: [{
    «Effect»: «Deny»,
    «Principal»: «*»,
    «Action»: «ecr:PutImage»,
    «Condition»: {«StringNotEquals»: {«ecr:SignerVersion»: «1»}}
    }]
    }

    – En Google Artifact Registry: Usar Binary Authorization con Cosign. Crear una policy que requiera firmas de Cosign:

    gcloud beta container binauthz policy create –project=mi-proyecto \
    –image-patterns=»docker.io/mi-org/*» \
    –attestation-authorities=»projects/mi-proyecto/attestation-authorities/cosign»

  • Implementar verificación en Kubernetes:
  • – Desplegar Kyverno o OPA Gatekeeper con políticas de verificación de firmas. Para Kyverno, instalar el Cosign plugin:

    kubectl kyverno plugin install cosign-yaml

    – Configurar image pull secrets para que el cluster pueda acceder a las claves públicas de verificación (si no se usan claves públicas globales).

  • Integrar firmado en CI/CD:
  • – En GitHub Actions: Usar el action cosign/cosign-action para firmar imágenes:

    – name: Sign image
    uses: cosign/cosign-action@v2
    with:
    arg: –key env://COSIGN_PRIVATE_KEY
    digest: ${{ steps.build.outputs.digest }}

    Almacenar la clave privada en un GitHub Secret (o usar Keyless Signing con OIDC).

    – En GitLab CI: Usar el template Sign container image (disponible en la versión 16.6+).

  • Establecer una política de confianza:
  • – Definir qué identidades se confía para firmar imágenes (ej: el pipeline de CI/CD de la organización, registry internos).

    – Documentar el procedimiento para rotar claves y revocar identidades comprometidas.

  • Monitorear y audit:
  • – Usar herramientas como Sigstore’s Rekor (servidor de transparencia) para audit el historial de firmas.

    – Configurar alertas para intentos de pull de imágenes no firmadas o firmadas por identidades no autorizadas.

    Conclusión

    El firmado de imágenes de contenedor no es una solución mágica, pero reduce el superficie de ataque de un problema invisible y ilimitado a uno scoped y auditable. En la era de la IA, donde los artifacts pueden contener código oculto en pesos de modelos o datasets, el escaneado de vulnerabilidades ya no es suficiente. El firmado gestionado por el registry elimina las barreras operativas, haciendo que la procedencia y verificación sean transparentes para los equipos de desarrollo. La combinación de firmado en el registry, verificación en Kubernetes y políticas de confianza claras cierra un vector de ataque crítico en la cadena de suministro de software moderno.

    Fuentes

    • https://thenewstack.io/unsigned-container-images-ai/
    • https://www.envoyproxy.io/blog/
    • https://msrc.microsoft.com/blog/

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *