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, comopackage-lock.json,Pipfile.lock,Gemfile.locko 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 fspara analizar una copia local, una carpeta de trabajo o un archivo concreto. - Usa
trivy repocuando quieras obtener y analizar un repositorio remoto compatible. - Usa
trivy configsi solo necesitas detectar misconfiguraciones de IaC. - Usa
trivy imagepara 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 trivyComprueba 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' \) \
-printgit 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:
--scannersdeclara el alcance y evita depender de valores predeterminados.--severitycontrola qué hallazgos se muestran.--exit-code 0mantiene 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
- secretValida 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.yamlNo 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
- Ejecuta localmente la línea base y confirma que termina con
0. - Ejecuta la puerta con el filtro acordado y registra su salida.
- Abre un pull request de prueba con un hallazgo controlado. No utilices una credencial válida para probar el scanner de secretos.
- Comprueba que el job falle y que la salida identifique el archivo y el hallazgo esperados.
- 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 tfplanEscanea 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.