Trivy es un escáner de seguridad de código abierto de Aqua Security que analiza imágenes de contenedor, directorios de código y archivos de infraestructura en busca de vulnerabilidades conocidas (CVE), secretos expuestos y configuraciones inseguras. Es un único binario, no necesita servidor y descarga su base de datos de vulnerabilidades automáticamente. En este tutorial instalarás Trivy en Ubuntu 24.04 desde su repositorio oficial, escanearás imágenes y un proyecto, filtrarás resultados, generarás un SBOM y lo integrarás en GitHub Actions para bloquear imágenes con vulnerabilidades graves.

Requisitos previos

Para seguir esta guía necesitas:

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con un usuario no root con privilegios sudo.
  • Unos 2 GB libres en disco para la caché de Trivy y las imágenes.
  • Acceso a Internet para descargar la base de datos de vulnerabilidades.
  • Opcional: Docker Engine instalado, si quieres escanear imágenes que construyes localmente. Tu usuario debe estar en el grupo docker para que Trivy pueda leerlas sin sudo.

Paso 1: Instalar Trivy desde el repositorio oficial

Instala las herramientas necesarias para añadir la clave del repositorio:

sudo apt update
sudo apt install -y wget gnupg

Descarga la clave de firma de Aqua Security en /etc/apt/keyrings:

sudo install -m 0755 -d /etc/apt/keyrings
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /etc/apt/keyrings/trivy.gpg > /dev/null

Añade el repositorio. Trivy publica un único repositorio generic válido para cualquier versión de Debian y Ubuntu:

echo "deb [signed-by=/etc/apt/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list

Instala el paquete:

sudo apt update
sudo apt install -y trivy

Comprueba la versión:

trivy --version
Version: 0.xx.x

Instalarlo desde el repositorio permite que apt upgrade mantenga Trivy actualizado, lo cual importa: las versiones nuevas añaden detectores y corrigen falsos positivos.

Paso 2: Escanear una imagen de contenedor

Escanea una imagen pública. Trivy la descarga directamente del registro, sin necesidad de Docker:

trivy image nginx:1.27

La primera ejecución descarga la base de datos de vulnerabilidades en ~/.cache/trivy, lo que tarda algo más. Las siguientes solo la actualizan si tiene más de unas horas. El resultado empieza con el total de vulnerabilidades por severidad:

nginx:1.27 (debian 12.x)
========================
Total: 142 (UNKNOWN: 0, LOW: 98, MEDIUM: 30, HIGH: 12, CRITICAL: 2)

Debajo de ese total aparece una tabla con una fila por vulnerabilidad y las columnas Library, Vulnerability, Severity, Status, Installed Version, Fixed Version y Title.

Las cifras dependen de la fecha en que escanees. Las columnas más útiles de la tabla son Severity, Status (fixed significa que ya existe una versión corregida) y Fixed Version, que indica a qué versión actualizar.

Paso 3: Filtrar por severidad y por disponibilidad de parche

Una imagen base típica tiene decenas de vulnerabilidades de severidad baja o sin corrección publicada, sobre las que no puedes actuar. Limita el informe a lo relevante:

trivy image --severity HIGH,CRITICAL --ignore-unfixed nginx:1.27
  • --severity HIGH,CRITICAL muestra solo esas severidades.
  • --ignore-unfixed oculta vulnerabilidades que todavía no tienen versión corregida.

Para aceptar conscientemente una vulnerabilidad concreta (porque no te afecta o está mitigada), crea un archivo .trivyignore en el directorio desde el que ejecutas Trivy, con un identificador por línea y un comentario que explique el motivo:

nano .trivyignore
# No usamos el módulo afectado; revisado el 2026-09-25
CVE-XXXX-XXXXX

Trivy lee .trivyignore del directorio actual automáticamente. Para usar otro archivo, pasa --ignorefile /ruta/al/archivo.

Paso 4: Usar el código de salida para bloquear builds

Por defecto Trivy termina con código 0 aunque encuentre vulnerabilidades. Con --exit-code 1 devuelve 1 si hay hallazgos que cumplen los filtros, lo que hace fallar cualquier pipeline:

trivy image --severity CRITICAL --ignore-unfixed --exit-code 1 nginx:1.27
echo "Código de salida: $?"
Código de salida: 1

Si no hay vulnerabilidades críticas con parche, el código es 0 y el pipeline continúa.

Paso 5: Escanear imágenes locales

Para una imagen que has construido con Docker, Trivy la lee del daemon local si no la encuentra en un registro:

docker build -t mi-app:1.0 .
trivy image --severity HIGH,CRITICAL mi-app:1.0

Si la imagen está en un archivo tar (por ejemplo, exportada en otra máquina), escanéala con --input:

docker save -o mi-app.tar mi-app:1.0
trivy image --input mi-app.tar

Paso 6: Escanear el código y la configuración del proyecto

Trivy también analiza un directorio: dependencias declaradas (package-lock.json, requirements.txt, go.sum, pom.xml...), secretos en el código y errores de configuración en Dockerfile, manifiestos de Kubernetes o Terraform. Desde la raíz de tu repositorio:

trivy fs --scanners vuln,secret,misconfig .

Si solo quieres revisar la configuración de infraestructura como código, usa trivy config:

trivy config .

Un hallazgo típico en un Dockerfile es que la imagen se ejecuta como root:

Dockerfile (dockerfile)
=======================
Tests: 27 (SUCCESSES: 26, FAILURES: 1)
Failures: 1 (HIGH: 1)

HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument

Para corregir este tipo de problemas, consulta la guía de hardening de imágenes de contenedor.

Paso 7: Generar un SBOM

Un SBOM (Software Bill of Materials) es el inventario de todos los paquetes de una imagen. Sirve para auditorías y para volver a comprobar vulnerabilidades más adelante sin tener la imagen. Genera uno en formato CycloneDX:

trivy image --format cyclonedx --output sbom.cdx.json nginx:1.27

Para el formato SPDX usa --format spdx-json. Cuando se publiquen nuevos CVE, puedes volver a escanear el SBOM guardado:

trivy sbom --severity HIGH,CRITICAL sbom.cdx.json

Para integrar los resultados con otras herramientas, usa --format json --output resultado.json.

Paso 8: Integrar Trivy en GitHub Actions

Aqua Security mantiene una acción oficial. Este workflow construye la imagen en cada push y pull request, falla si hay vulnerabilidades altas o críticas con parche y sube el informe a la pestaña Security del repositorio.

Crea el archivo .github/workflows/trivy.yml en tu repositorio:

name: Trivy

on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read
  security-events: write

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Construir la imagen
        run: docker build -t mi-app:${{ github.sha }} .

      - name: Escanear con Trivy
        uses: aquasecurity/[email protected]
        with:
          image-ref: mi-app:${{ github.sha }}
          format: sarif
          output: trivy-results.sarif
          severity: HIGH,CRITICAL
          ignore-unfixed: true
          exit-code: "1"

      - name: Subir resultados a GitHub Security
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: trivy-results.sarif

En otros sistemas de CI basta con instalar Trivy y ejecutar el mismo comando del paso 4; el código de salida hace fallar el job.

Solución de problemas

TOOMANYREQUESTS al descargar la base de datos: el registro de la base de datos limita las descargas. Usa un mirror alternativo con --db-repository public.ecr.aws/aquasecurity/trivy-db o, en CI, conserva la caché ~/.cache/trivy entre ejecuciones.

unable to find the specified image con una imagen local: tu usuario no tiene acceso al socket de Docker. Añádelo al grupo con sudo usermod -aG docker $USER y abre una sesión nueva, o exporta la imagen con docker save y usa --input.

Resultados inconsistentes o base de datos corrupta: borra la caché y deja que Trivy la descargue de nuevo:

trivy clean --all

Escaneos lentos en imágenes grandes: si solo te interesan vulnerabilidades, desactiva el resto de detectores con --scanners vuln.

Conclusión

Tienes Trivy instalado desde su repositorio oficial y sabes escanear imágenes remotas y locales, filtrar lo accionable, analizar el código y la configuración de un proyecto, generar un SBOM y bloquear builds en CI. Como siguientes pasos, puedes reducir las vulnerabilidades de partida endureciendo tus imágenes (bases mínimas, builds multi-etapa, usuario no root), escanear con regularidad las imágenes ya desplegadas, o añadir detección en tiempo de ejecución con Falco.