OpsCanopy 5 min de lectura
Una CVE, cuatro archivos de exclusión: unificando Trivy, Grype, Snyk y osv-scanner
Una única supresión de CVE triada tiene que recodificarse en .trivyignore, .grype.yaml, .snyk y osv-scanner.toml, cada una con una forma distinta. Aquí está la misma supresión en los cuatro formatos, qué se traslada limpiamente y qué se pierde.
- security
- vulnerability-management
- devops
En esta página
Triaste la CVE. Un escáner marcó CVE-2023-45853 en zlib, leíste el aviso, confirmaste que la ruta de código vulnerable no es alcanzable desde tu imagen y tomaste la decisión: suprimirla, con un motivo y una fecha de revisión. Una decisión.
Ahora codifica esa única decisión cuatro veces.
Si tu pipeline ejecuta más de un escáner —y muchos lo hacen, porque Trivy, Grype, Snyk y osv-scanner detectan cada uno cosas que los demás pasan por alto— cada supresión de riesgo aceptado tiene que escribirse en el archivo de exclusión de cada herramienta. La misma CVE, la misma justificación, cuatro archivos distintos con cuatro esquemas distintos, cuatro capacidades distintas. Si te equivocas en uno, ese escáner sigue haciendo fallar el build (o peor, deja de fallar silenciosamente en algo que nunca quisiste ignorar).
La misma supresión, de cuatro maneras
Aquí está la versión más sencilla de esa decisión —«ignorar CVE-2023-45853»— en cada formato.
.trivyignore es una lista plana delimitada por saltos de línea. Un ID por línea, # para comentarios:
# zlib MiniZip — not reachable from our build, re-review 2026-09-01
CVE-2023-45853
.grype.yaml usa un array ignore estructurado de reglas de coincidencia. Puedes delimitar por ID de vulnerabilidad y, opcionalmente, por paquete:
ignore:
- vulnerability: CVE-2023-45853
# zlib MiniZip — not reachable, re-review 2026-09-01
package:
name: zlib
version: 1.2.13
.snyk es el archivo de política de Snyk: un mapa YAML indexado por ID de incidencia, donde cada entrada es una lista de objetos delimitados por ruta que llevan reason y expires como campos de primera clase:
version: v1.25.0
ignore:
CVE-2023-45853:
- "*":
reason: zlib MiniZip not reachable from our build
expires: 2026-09-01T00:00:00.000Z
osv-scanner.toml usa un array de tablas TOML [[IgnoredVulns]], con id, reason y un ignoreUntil en RFC 3339:
[[IgnoredVulns]]
id = "CVE-2023-45853"
ignoreUntil = 2026-09-01T00:00:00Z
reason = "zlib MiniZip not reachable from our build"
Cuatro archivos. El ID de la CVE es lo único que sobrevive textualmente en todos ellos.
Qué se traslada limpiamente
Un puñado de conceptos son genuinamente portables, y un conversor puede moverlos sin pérdida:
- El identificador. Un ID
CVE-…es un IDCVE-…en todas partes. La única peculiaridad: osv-scanner está más cómodo con IDs de OSV (GHSA-…,PYSEC-…) pero acepta CVEs y resuelve alias, mientras que los demás priorizan las CVE. La mayoría de las veces el ID es una copia limpia. - Una cadena de motivo. Grype, Snyk y osv-scanner tienen todos algún sitio donde poner el «por qué». Trivy históricamente no lo tenía: en un
.trivyignoresimple, el único hogar para una justificación es un comentario#en la línea de arriba, que ninguna herramienta analiza pero todo revisor lee. - La caducidad, en espíritu. El
expiresde Snyk y elignoreUntilde osv-scanner son ambos marcas de tiempo reales y aplicadas: una vez que pasa la fecha, la supresión expira y el hallazgo vuelve. Esa es la misma idea, y se convierte directamente entre las dos.
Qué se pierde
La parte interesante es todo lo que no hace el viaje de ida y vuelta. Un conversor tiene que ser honesto sobre esto en lugar de descartarlo silenciosamente.
La caducidad es asimétrica. Snyk y osv-scanner aplican una fecha. El .trivyignore simple no tiene campo de caducidad en absoluto: una supresión allí es para siempre hasta que alguien borre la línea. (El archivo de exclusión YAML más reciente de Trivy admite un statement y una coincidencia más rica, pero el .trivyignore clásico que la mayoría de los repos todavía usan no.) Convierte una exclusión de Snyk con caducidad a .trivyignore y esa caducidad solo puede sobrevivir como comentario: una nota para un humano, no una regla que el escáner aplique. Eso es una pérdida real de seguridad, y debería señalarse, no ocultarse.
El alcance del paquete varía. Grype te permite fijar package.name y package.version, de modo que la supresión solo se aplica a esa dependencia exacta. .trivyignore (clásico) se indexa puramente por el ID de la vulnerabilidad: ignora esa CVE en todas partes donde aparezca en el escaneo, lo cual es más amplio de lo que quizás pretendías. Reducir una regla de Grype a .trivyignore amplía el radio de impacto; no puedes expresar «solo este paquete» en una lista plana de IDs.
El alcance de ruta es sobre todo una idea de Snyk. Las entradas ignore de Snyk son listas indexadas por ruta: el "*" de arriba significa «en todas partes», pero Snyk también puede delimitar una supresión a una ruta de dependencia concreta para que se aplique en un sitio y no en otro. Ni Trivy, ni Grype, ni osv-scanner modelan el alcance a nivel de ruta de esta forma, así que una exclusión de Snyk delimitada por ruta se aplana a «esta CVE, a nivel de proyecto» en los demás. La intención («solo en esta ruta transitiva») desaparece.
El motivo no tiene dónde aterrizar de forma nativa en el Trivy clásico. Como antes: convertir hacia .trivyignore degrada un motivo de primera clase a un comentario. Al convertir desde él, normalmente no hay ningún motivo legible por máquina que recuperar, solo lo que un humano dejara en una línea #.
El patrón en todos estos casos: convertir hacia un formato más expresivo es seguro, y convertir hacia uno más plano amplía silenciosamente el alcance y descarta metadatos. La única forma responsable de hacer la conversión plana es exponer exactamente qué se perdió para que un humano pueda decidir si la supresión más amplia es aceptable.
Hazlo una vez, emite cuatro
Mantener cuatro archivos de exclusión escritos a mano sincronizados es exactamente el tipo de tarea administrativa repetitiva y propensa a errores que debería ser mecánica. Describe una supresión una sola vez —ID, motivo, caducidad, alcance de paquete y de ruta— y deja que una herramienta emita la forma correcta para cada escáner, con advertencias explícitas allá donde un formato de destino no pueda contener un campo.
Eso es lo que hace el CVE-Ignore Converter: pega cualquiera de .trivyignore, .grype.yaml, .snyk o osv-scanner.toml, recibe los otros tres de vuelta y observa con precisión qué partes se perdieron en el viaje de ida y vuelta. Se ejecuta enteramente en tu navegador: tu política de supresión nunca abandona la página.
Publicaciones relacionadas
-
8 min de lectura
Aprende DevOps en 90 días: la ruta gratuita y centrada en incidentes de desarrollador a ingeniero DevOps
Por qué creamos Mission: 90 Days DevOps — una ruta gratuita día a día de Linux a Kubernetes con misiones de incidentes jugables. El plan completo, las decisiones de diseño y los compromisos honestos.
-
7 min de lectura
Leer expresiones cron: una guía campo por campo
Una guía práctica, campo por campo, para leer expresiones cron — los cinco campos de tiempo, rangos, pasos, listas y @macros — además de las trampas que hacen que las programaciones se disparen cuando menos lo esperas.
-
7 min de lectura
Los errores de seguridad en GitHub Actions que los linters pasan por alto
Los validadores de YAML detectan la sintaxis, no la exposición. Aquí están las cinco configuraciones incorrectas de GitHub Actions de mayor impacto — pull_request_target, inyección de scripts, actions sin fijar, ámbitos demasiado amplios de GITHUB_TOKEN y curl|bash — con el patrón incorrecto y su corrección para cada una.