Trivy permite revisar una copia local de un repositorio antes de desplegarla. Con un solo recorrido puede detectar vulnerabilidades conocidas en dependencias, secretos escritos en archivos de texto y errores de configuración en infraestructura como código (IaC).

En esta guía vas a instalar o comprobar Trivy, ejecutar una línea base sin bloquear el trabajo, activar explícitamente los tres scanners, definir exclusiones justificadas y aplicar la misma política en GitHub Actions. Al terminar, podrás verificar los hallazgos y el código de salida del comando.

Importante: un resultado sin hallazgos no demuestra que la aplicación sea segura. Trivy realiza análisis estático sobre los archivos compatibles que encuentra; no sustituye las pruebas dinámicas, la revisión del entorno desplegado ni la gestión de riesgos.

Qué analiza trivy fs

trivy fs examina un archivo o directorio disponible en el sistema de archivos. En un repositorio puede ejecutar estos scanners:

  • vuln: busca vulnerabilidades conocidas a partir de manifiestos y archivos de bloqueo de dependencias, como package-lock.json, Pipfile.lock, Gemfile.lock o equivalentes compatibles.
  • secret: busca patrones de credenciales y otros secretos en archivos de texto plano. No garantiza detectar todos los secretos; por ejemplo, un valor codificado puede no coincidir con las reglas disponibles.
  • misconfig: revisa configuraciones IaC compatibles, como Terraform, planes de Terraform, Kubernetes, Dockerfile, CloudFormation, Azure ARM y Helm.
  • license: identifica licencias; está fuera del alcance de esta guía.

En trivy fs, vuln y secret están activos de forma predeterminada. misconfig no lo está: para analizar IaC debes habilitarlo con --scanners vuln,misconfig,secret. Este comportamiento está documentado en la referencia oficial de filesystem.

  • Usa trivy fs para analizar una copia local, una carpeta de trabajo o un archivo concreto.
  • Usa trivy repo cuando quieras obtener y analizar un repositorio remoto compatible.
  • Usa trivy config si solo necesitas detectar misconfiguraciones de IaC.
  • Usa trivy image para una imagen de contenedor construida. Escanear el repositorio no reemplaza el análisis de la imagen final.

Requisitos previos

  • Una copia local del repositorio y permisos de lectura sobre sus archivos.
  • Trivy instalado. Los ejemplos fueron revisados contra la documentación de Trivy 0.74.0; comprueba los parámetros si utilizas otra versión.
  • Acceso de red en el primer uso para descargar las bases de vulnerabilidades y el paquete de comprobaciones.
  • Manifiestos o lockfiles si esperas resultados de vulnerabilidades.
  • Una política acordada sobre scanners, severidades y excepciones antes de convertir el análisis en una puerta de CI.

Los reportes pueden contener rutas, nombres de paquetes y fragmentos de contexto. Trátalos como información sensible y revísalos antes de publicarlos o conservarlos como artefactos.

1. Instalar y comprobar Trivy

En Debian o Ubuntu, el proyecto mantiene un repositorio oficial:

sudo apt-get update
sudo apt-get install -y wget gnupg

wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key \
  | gpg --dearmor \
  | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null

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

sudo apt-get update
sudo apt-get install -y trivy

Comprueba la instalación y registra la versión utilizada:

trivy --version
trivy fs --help | sed -n '1,80p'

La primera orden debe mostrar la versión. La segunda debe terminar con código 0 y listar las opciones de fs. En otros sistemas, elige un método marcado como oficial en la documentación de instalación.

2. Revisar el alcance antes de escanear

Sitúate en la raíz del repositorio:

cd /ruta/al/repositorio
git status --short

find . -maxdepth 3 -type f \
  \( -name 'Dockerfile' -o -name '*.tf' -o -name '*.tfvars' \
     -o -name 'package-lock.json' -o -name 'Pipfile.lock' \
     -o -name 'Gemfile.lock' -o -name 'go.sum' \) \
  -print

git status --short permite reconocer cambios locales antes del análisis. find solo ayuda a inventariar algunos archivos habituales; no determina todo lo que Trivy soporta.

No escanees una copia que contenga credenciales de producción innecesarias. Si Trivy detecta un secreto real, no basta con borrarlo del último commit: revócalo o rótalo y revisa si quedó expuesto en el historial, forks, logs o artefactos.

3. Ejecutar una línea base informativa

La primera ejecución debe mostrar todos los niveles de severidad sin bloquear el proceso:

status=0
trivy fs \
  --scanners vuln,misconfig,secret \
  --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL \
  --exit-code 0 \
  --format table \
  . || status=$?

printf 'Código de salida: %s\n' "$status"

Las opciones cumplen estas funciones:

  • --scanners declara el alcance y evita depender de valores predeterminados.
  • --severity controla qué hallazgos se muestran.
  • --exit-code 0 mantiene esta ejecución como diagnóstico aunque existan hallazgos.
  • . establece como objetivo el directorio actual.

En la salida deberías reconocer los archivos o destinos analizados y los resúmenes de los scanners aplicables. Si no aparece IaC, comprueba que incluiste misconfig, que los archivos están dentro de la ruta y que su formato es compatible.

El código debe ser 0, salvo que Trivy haya sufrido un error operativo, por ejemplo al leer archivos o descargar datos.

4. Guardar una configuración reproducible

Crea un archivo trivy.yaml en la raíz del repositorio:

timeout: 10m

format: table
exit-code: 0
severity:
  - UNKNOWN
  - LOW
  - MEDIUM
  - HIGH
  - CRITICAL

scan:
  scanners:
    - vuln
    - misconfig
    - secret

Valida que Trivy pueda leerlo:

status=0
trivy fs --config trivy.yaml . || status=$?

printf 'Código de salida: %s\n' "$status"

Al versionar esta configuración, los análisis local y de CI pueden partir de la misma política. Las opciones de la línea de comandos tienen prioridad sobre el archivo, por lo que deben reservarse para cambios deliberados.

5. Generar evidencia sin bloquear

Crea un directorio restringido y genera un reporte JSON:

install -d -m 0700 artifacts/trivy

status=0
trivy fs \
  --config trivy.yaml \
  --format json \
  --output artifacts/trivy/trivy-results.json \
  . || status=$?

printf 'Código de salida: %s\n' "$status"

Comprueba que el reporte exista y no esté vacío:

test -s artifacts/trivy/trivy-results.json
printf 'Validación del reporte: %s\n' "$?"

Añade artifacts/trivy/ a .gitignore si los reportes no deben versionarse. Antes de subirlos a un sistema de artefactos, define quién podrá leerlos y cuánto tiempo se conservarán.

6. Aplicar una puerta por severidad

Después de revisar la línea base, ejecuta una segunda pasada que falle ante hallazgos HIGH o CRITICAL:

status=0
trivy fs \
  --config trivy.yaml \
  --severity HIGH,CRITICAL \
  --ignore-unfixed \
  --exit-code 1 \
  . || status=$?

printf 'Código de salida de la puerta: %s\n' "$status"
  • Código 0: no se encontraron hallazgos que coincidan con los filtros.
  • Código 1: pueden existir hallazgos seleccionados o un error operativo. Revisa la salida antes de diagnosticar la causa.

--ignore-unfixed oculta vulnerabilidades sin corrección disponible; no elimina misconfiguraciones ni secretos. No lo actives automáticamente si tu política exige visibilidad sobre riesgos todavía sin parche.

La severidad es un filtro inicial, no una decisión de riesgo completa. También importan la exposición, la explotabilidad, el uso real de la dependencia y los controles compensatorios.

Imagen técnica 2. Flujo desde la línea base hasta la puerta de CI y la corrección.

7. Excluir archivos o aceptar hallazgos

Omitir una ruta y aceptar un hallazgo son decisiones distintas.

Omitir rutas del recorrido

Usa --skip-dirs o --skip-files únicamente para contenido que no deba analizarse, como salidas generadas duplicadas:

trivy fs \
  --config trivy.yaml \
  --skip-dirs ./dist \
  --skip-dirs ./coverage \
  .

Omitir una carpeta impide que todos los scanners vean su contenido. No excluyas vendor, node_modules, módulos descargados de Terraform u otras rutas de forma mecánica: primero determina si contienen evidencia necesaria.

Suprimir un hallazgo concreto

Una excepción debe utilizar el identificador real mostrado por Trivy y tener alcance, motivo, responsable y vencimiento.

El formato .trivyignore.yaml permite separar tipos de hallazgo, aunque la documentación actual lo considera experimental:

misconfigurations:
  - id: ID_REAL_DEL_HALLAZGO
    paths:
      - infra/ejemplo.tf
    expired_at: AAAA-MM-DD
    statement: "Responsable: equipo-plataforma; ticket: SEC-000; motivo temporal"

statement documenta la decisión, pero no participa en el filtrado. La supresión se determina mediante id, paths y expired_at.

Especifica el archivo al ejecutar el análisis:

trivy fs \
  --config trivy.yaml \
  --ignorefile .trivyignore.yaml \
  .

Después, repite la línea base y la puerta con el mismo --ignorefile. Comprueba que desaparezca únicamente el hallazgo previsto. Consulta la documentación oficial sobre filtrado antes de actualizar la herramienta.

8. Integrar Trivy en GitHub Actions

El siguiente workflow ejecuta la puerta en cada pull request y en los cambios a main:

name: Trivy filesystem

on:
  pull_request:
  push:
    branches:
      - main

permissions:
  contents: read

jobs:
  scan:
    runs-on: ubuntu-24.04
    steps:
      - name: Obtener el repositorio
        uses: actions/checkout@v4

      - name: Escanear repositorio e IaC
        uses: aquasecurity/[email protected]
        with:
          version: v0.74.0
          scan-type: fs
          scan-ref: .
          trivy-config: trivy.yaml
          scanners: vuln,misconfig,secret
          format: table
          severity: HIGH,CRITICAL
          ignore-unfixed: true
          exit-code: '1'

v0.36.0 era la versión publicada más reciente de la acción oficial al revisar esta guía. Antes de utilizar el workflow en producción, reemplaza las etiquetas de las acciones por el SHA completo de un commit auditado. Dependabot o Renovate pueden proponer actualizaciones revisables.

Si utilizas excepciones estructuradas, añade lo siguiente al bloque with:

trivyignores: .trivyignore.yaml

No incluyas esa opción si el archivo no existe.

El job solo necesita contents: read. No entregues secretos al job de pull requests externos. Para publicar SARIF en GitHub Code Scanning también necesitarás security-events: write y un paso de carga independiente. La acción oficial de Trivy documenta ambas modalidades.

Cómo comprobar la integración

  1. Ejecuta localmente la línea base y confirma que termina con 0.
  2. Ejecuta la puerta con el filtro acordado y registra su salida.
  3. Abre un pull request de prueba con un hallazgo controlado. No utilices una credencial válida para probar el scanner de secretos.
  4. Comprueba que el job falle y que la salida identifique el archivo y el hallazgo esperados.
  5. Corrige el ejemplo, vuelve a ejecutar y confirma que el job quede aprobado.

Esta prueba valida el funcionamiento de la puerta, pero no demuestra cobertura completa ni ausencia de falsos negativos.

Problemas frecuentes

No aparecen misconfiguraciones de IaC

Confirma que ejecutaste --scanners vuln,misconfig,secret o utiliza trivy config . para una prueba exclusiva de IaC. Revisa también la extensión y la ruta. La cobertura oficial de IaC enumera los formatos compatibles.

No aparecen vulnerabilidades

Comprueba que el repositorio contenga manifiestos o lockfiles compatibles y actualizados. Revisa además si --skip-dirs, el archivo de excepciones o --ignore-unfixed están ocultando resultados.

El primer escaneo falla o tarda demasiado

Verifica la conectividad, los permisos de escritura en la caché, el espacio disponible y timeout. No uses --skip-db-update en la primera ejecución: requiere una base ya disponible.

Terraform no coincide con el plan real

El análisis estático no puede resolver todos los valores dependientes de proveedores o del estado remoto. Cuando la decisión dependa del plan, genera un tfplan en un entorno controlado y analízalo:

terraform plan -out tfplan
trivy config tfplan

Escanea desde una raíz que incluya los archivos referenciados. Trivy trata la raíz del análisis como límite de confianza.

Hay un supuesto falso positivo

Verifica el archivo, el identificador, la versión de Trivy y el contexto. Si aceptas el riesgo, crea una excepción acotada y temporal. No omitas un directorio completo para silenciar un único hallazgo.

Buenas prácticas

  • Fija la versión de Trivy y los SHA de las acciones en CI.
  • Mantén los mismos scanners y filtros en local y CI.
  • Ejecuta una línea base antes de activar la puerta.
  • Conserva lockfiles y actualízalos de manera controlada.
  • Rota cualquier secreto real detectado.
  • Separa las omisiones de recorrido de las excepciones de hallazgos.
  • Registra responsable, motivo, ticket y vencimiento de cada excepción.
  • Escanea también la imagen de contenedor final si el proyecto la produce.

Resultado

El repositorio queda cubierto por un flujo repetible: Trivy analiza dependencias, secretos y archivos IaC; la línea base permite revisar el estado sin bloquear; la puerta devuelve un código distinto de cero cuando la política encuentra hallazgos seleccionados; y las excepciones quedan acotadas y documentadas.

El siguiente paso es corregir los hallazgos por orden de riesgo, repetir el escaneo y añadir el análisis de la imagen construida o del entorno desplegado cuando forme parte de la arquitectura real.


Cloud Serversby Donweb

Todo el poder de la nube a tus proyectos y aplicaciones.
Alojamiento ultra rápido, escalable y con alta disponibilidad.

  • Performance que te sorprenderá
  • Rápida escalabilidad y sin limitaciones
  • Arquitectura de alta disponibilidad
  • Soporte experto y ejecutivos de cuenta
  • Pagos en tu moneda y facturación local

Descubre la mejor solución de Cloud Hosting