
sbomlyze v0.3.5
git diff para tu SBOM ,compara CycloneDX/SPDX/Syft listas de materiales, detecta manipulaciones, y controla el CI
sbomlyze
git diff para tu SBOM. Compara dos listas de materiales de software y observa qué cambió entre compilaciones, versiones y lanzamientos.
sbomlyze compara los hashes de los componentes, no solo las cadenas de versión. Cuando un atacante intercambia un paquete sin aumentar su versión, sbomlyze lo señala. Los generadores y los escáneres de vulnerabilidades no detectan esto.
[![CI][ci-img]][ci] [![GitHub Marketplace][marketplace-img]][marketplace] [![GitHub Release][release-img]][release] [![Go Report Card][go-report-img]][go-report] [![OpenSSF Scorecard][scorecard-img]][scorecard] [![Licencia: Apache-2.0][license-img]][license] [![Descargas][download-img]][download]
Consulta por qué esta señal es diferente de un diff de manifiesto o de componentes ordinario en Diff de manifiesto vs. diff de SBOM vs. deriva de integridad.
Los generadores crean SBOM y los escáneres encuentran CVEs. sbomlyze te dice qué cambió entre dos SBOM y si debes confiar en ello. Ejecútalo después de tu generador:
syft image:tag -o cyclonedx-json | sbomlyze - --complianceanaliza y puntúa el SBOM generado sin un archivo temporal. Compáralo con una línea base para clasificar la deriva y controlar tu pipeline.
Inicio rápido con GitHub Action
Añade [SBOMlyze Diff desde GitHub Marketplace][marketplace] para comparar un SBOM
verificado o generado por separado con su línea base de git. El SHA inmutable que aparece a continuación es
la Action v0.5.1 publicada:```yaml
steps:
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0
-
uses: rezmoss/sbomlyze@31503690611fda8ebba4ed2bd186eda000442594 # v0.5.1 with: sbom-path: build/sbom.cdx.json
La Action escribe un Job Summary por defecto y puede aplicar políticas, informar de desviaciones de integridad, subir SARIF o mantener un único comentario en la pull request. Consulta
[la referencia completa de la Action](https://github.com/rezmoss/sbomlyze/blob/HEAD/ACTION.md) para entradas, salidas, permisos
y guía de seguridad. Consulta el
[repositorio de demostración en vivo](https://github.com/rezmoss/sbomlyze-action-demo)
para ver una actualización de dependencias que pasa y un cambio de hash de la misma versión bloqueado, con
ejecuciones de workflows públicas y evidencia SARIF.
Para dogfooding específico de formato, usa los ejemplos públicos de
[Go + SPDX](https://github.com/rezmoss/sbomlyze-go-spdx-demo),
[Node + CycloneDX](https://github.com/rezmoss/sbomlyze-node-cyclonedx-demo) o
[contenedor](https://github.com/rezmoss/sbomlyze-container-demo). Cada uno
contiene cinco escenarios de revisión reproducibles. La
[guía beta de 10 minutos](https://github.com/rezmoss/sbomlyze/blob/HEAD/BETA.md) recopila cuatro preguntas centradas en la activación y la calidad de la señal.
Los SBOM generados no necesitan estar commiteados: `baseline: workflow-artifact`
recupera el artefacto coincidente más reciente de una ejecución exitosa de la rama
predeterminada. Un [workflow complementario de Syft fijado](https://github.com/rezmoss/sbomlyze/blob/HEAD/examples/workflows/syft-companion.yml)
muestra la generación y la publicación de la línea base mientras SBOMlyze sigue siendo responsable
de la revisión y las políticas.
## ¿Por qué sbomlyze?
Muchas herramientas generan SBOM. Pocas los comparan, y menos aún te dicen si un cambio es rutinario o una señal de alarma en la cadena de suministro. sbomlyze llena ese vacío.
| Capacidad | **sbomlyze** | cyclonedx-cli | sbomqs | syft / trivy |
|---|:---:|:---:|:---:|:---:|
| **Diff** SBOM a SBOM | ✅ | básico | ❌ | ❌ |
| Desviación de **integridad / manipulación** (hash cambiado sin cambio de versión) | ✅ | ❌ | ❌ | ❌ |
| Diff de grafo de dependencias + riesgo de profundidad transitiva | ✅ | ❌ | ❌ | ❌ |
| Puntuación de cumplimiento **NTIA / CISA / BSI** | ✅ | ❌ | ✅ | ❌ |
| Conversión de formatos (Syft / CycloneDX / SPDX) | ✅ | ✅ | ❌ | parcial |
| Exploradores **TUI + Web UI** | ✅ | ❌ | ❌ | ❌ |
| Puerta de políticas + SARIF / JUnit / Markdown / HTML / Patch | ✅ | parcial | parcial | parcial |
## Características
- **Diff de SBOM**: Compara dos SBOM y visualiza de un vistazo los componentes añadidos, eliminados y modificados
- **Clasificación de desviaciones**: Distingue entre desviación de versión y **desviación de integridad** (un hash cambiado sin cambio de versión, indicativo de manipulación) y desviación de metadatos
- **Puntuación de cumplimiento**: Puntúa cualquier SBOM según los elementos mínimos de **NTIA**, **CISA 2025** y **BSI TR-03183**
- **Diff de grafo de dependencias**: Realiza seguimiento de las dependencias transitivas y la profundidad de la cadena de suministro
- **Compatibilidad multi-formato**: Syft, CycloneDX, SPDX (JSON)
- **Conversión de formatos**: Convierte entre formatos CycloneDX, SPDX y Syft
- **Coincidencia sólida de identidades**: Precedencia PURL → CPE → BOM-ref → namespace/name
- **Modo estadísticas**: Analiza SBOM individuales para métricas de licencias, dependencias e integridad
- **Modo TUI interactivo**: Explora SBOM con navegación por teclado y búsqueda
- **Modo Web UI**: Explorador de SBOM basado en navegador con carga mediante arrastrar y soltar
- **Motor de políticas**: Aplica reglas de desviación, licencias y puntuación de cumplimiento en pipelines de CI
- **Action del GitHub Marketplace**: Filtra pull requests según la desviación del SBOM con Job Summary, SARIF y salida de comentarios opcional
- **Detección de duplicados y colisiones**: Encuentra múltiples versiones del mismo paquete y coincidencias de identidad ambiguas
- **Múltiples formatos de salida**: Texto, JSON, SARIF, JUnit XML, Markdown, HTML, JSON Patch
- **Análisis tolerante**: Continúa ante errores con advertencias estructuradas
## Instalación
### Homebrew (macOS/Linux)```bash
brew install rezmoss/sbomlyze/sbomlyze
Script de instalación
El script de instalación descarga el binario correcto para tu sistema operativo/arquitectura:```bash
Install to ./bin
curl -sSfL https://raw.githubusercontent.com/rezmoss/sbomlyze/main/install.sh | sh
Install to /usr/local/bin (requires sudo)
curl -sSfL https://raw.githubusercontent.com/rezmoss/sbomlyze/main/install.sh | sudo sh -s -- -b /usr/local/bin
Install specific version
curl -sSfL https://raw.githubusercontent.com/rezmoss/sbomlyze/main/install.sh | sh -s -- -v 0.4.0
**Opciones del instalador:**
| Opción | Descripción |
|--------|-------------|
| `-b <dir>` | Directorio de instalación (predeterminado: `./bin`) |
| `-d` | Habilitar salida de depuración |
| `-v <ver>` | Instalar versión específica (predeterminado: la última) |
El instalador siempre verifica el checksum de la versión. Cuando hay una CLI de GitHub compatible
instalada, también verifica la procedencia de compilación de la versión y falla de forma segura si
esa verificación no tiene éxito.
### Instalación con Go```bash
go install github.com/rezmoss/sbomlyze/cmd/sbomlyze@latest
Desde la versión binaria
Descarga el último binario desde GitHub Releases.
A partir de v0.3.7, los archivos de lanzamiento se publican con atestaciones de artefactos de GitHub. Verifica una descarga de forma independiente con:```bash
gh attestation verify ./sbomlyze_0.4.0_Linux_x86_64.tar.gz
--repo rezmoss/sbomlyze
--signer-workflow rezmoss/sbomlyze/.github/workflows/release.yml
Las instrucciones para repositorios apt, rpm y apk sin firmar se han eliminado hasta que los repositorios admitan la verificación de firmas nativa del administrador de paquetes.
**Usuarios de macOS:** Elimine el atributo de cuarentena después de descargar:```bash
xattr -d com.apple.quarantine ./sbomlyze
chmod +x ./sbomlyze
Compilar desde el código fuente```bash
git clone https://github.com/rezmoss/sbomlyze.git cd sbomlyze go build -o sbomlyze ./cmd/sbomlyze
## Inicio rápido```bash
# Compare two SBOMs (the headline use case)
sbomlyze before.json after.json
# Analyze a single SBOM
sbomlyze image.json
# Read an SBOM from standard input
syft image:tag -o cyclonedx-json | sbomlyze -
# Use standard input on either side of a diff
syft image:tag -o cyclonedx-json | sbomlyze baseline.json -
# Score an SBOM against NTIA / CISA / BSI minimum elements
sbomlyze image.json --compliance
# Interactive TUI explorer
sbomlyze image.json -i
# Web UI (opens browser)
sbomlyze -web
# Convert between SBOM formats
sbomlyze convert syft.json --to spdx
sbomlyze convert cdx.json --to syft -o output.json
# JSON output for CI integration
sbomlyze before.json after.json --json
# SARIF output for GitHub Code Scanning
sbomlyze before.json after.json --format sarif
# Markdown report for PR comments
sbomlyze before.json after.json --format markdown
# Apply policy checks
sbomlyze before.json after.json --policy policy.json
Uso```
sbomlyze <sbom1|-> [sbom2|-] [options] sbomlyze convert <sbom|-> --to [-o output]
Modes: Single file: sbomlyze [--json] Show statistics Interactive: sbomlyze -i Interactive explorer Convert: sbomlyze convert --to Convert SBOM format Web server: sbomlyze -web [--port 8080] Web UI explorer Two files: sbomlyze [...] Show diff
Use - in place of one SBOM path to read it from standard input.
Options: -i, --interactive Interactive TUI explorer -web, --web Start web UI server --port Web server port (default 8080) --json Output in JSON format (shortcut for --format json) --format Output format: text, json, sarif, junit, markdown, html, patch --compliance Show NTIA/CISA/BSI compliance scoring --policy Policy file for CI checks --strict Fail on parse warnings --tolerant Continue on parse warnings (default) --no-pager Disable automatic paging of output --to Target format for convert: cyclonedx (cdx), spdx, syft -o, --output Output file for convert (default: stdout) --version, -v Show version information --help, -h Show this help message
## Comandos
### Modo Estadísticas (Archivo Único)
Analiza un SBOM para obtener información sobre componentes, licencias y dependencias.```bash
sbomlyze image.json
La salida incluye el contexto del escaneo, hallazgos clave detectados automáticamente y estadísticas:``` Scan Context: Tool: syft 1.40.1 Schema: 16.0.18 Scan Scope: all-layers Source Type: image Source: alpine:latest
Key Findings: 💻 OS/Distro: Alpine Linux v3.21 📦 Dominated by apk: 71 of 71 packages (100.0%) 📂 8,542 files tracked on filesystem 🔗 Relationships: 71 containment + 64 dependency 📜 License profile: 72% permissive, 20% copyleft ⚠️ Low hash coverage: 0.0% (71 of 71 missing) 🔍 Top catalogers: apkdb-cataloger (71)
📦 SBOM Statistics
Total Components: 71
By Package Type: apk 71
Licenses: With license: 71 Without license: 0
Top Licenses: MIT 17 BSD-3-Clause 8 GPL-2.0-only 8
Integrity: With hashes: 0 Without hashes: 71
Dependencies: Components with deps: 65 Total dep relations: 176
#### Hallazgos clave
sbomlyze genera automáticamente información sobre tu SBOM. Para el análisis de un solo archivo, esto incluye:
| Hallazgo | Descripción |
|---------|-------------|
| **Detección de SO/distribución** | Identifica el sistema operativo o la distribución a partir de los metadatos del SBOM |
| **Ecosistema dominante** | Indica cuando un tipo de paquete domina (>60% de todos los paquetes) |
| **Huella del sistema de archivos** | Número de archivos rastreados en el sistema de archivos |
| **Densidad de relaciones** | Recuentos de relaciones de contención y dependencia |
| **Ubicaciones más frecuentes** | Directorios principales donde se encuentran los componentes |
| **Perfil de riesgo de licencias** | Desglose de porcentajes de licencias permisivas, copyleft y desconocidas |
| **Advertencias de calidad de datos** | Alertas cuando la cobertura de licencias (<50%), hashes (<50%) o PURL (<80%) es baja |
| **Advertencias de duplicados** | Señala grupos de componentes duplicados |
| **Desglose de catalogadores** | Principales escáneres/catalogadores que detectaron componentes (SBOM de Syft) |
#### Métricas de cobertura
El modo de estadísticas calcula porcentajes de cobertura para evaluar la calidad de los datos:
| Métrica | Descripción |
|--------|-------------|
| **Cobertura de PURL** | Porcentaje de componentes con URL de paquete |
| **Cobertura de CPE** | Porcentaje de componentes con CPE (preparación para el escaneo de vulnerabilidades) |
| **Cobertura de licencias** | Porcentaje de componentes con al menos una licencia |
| **Cobertura de hash** | Porcentaje de componentes con hashes de integridad |
#### Categorización de licencias
Las licencias se clasifican automáticamente en:
| Categoría | Ejemplos |
|----------|----------|
| **Copyleft** | GPL, LGPL, AGPL, MPL, EPL, CDDL |
| **Permisiva** | MIT, BSD, Apache, ISC, Zlib, Unlicense |
| **Dominio público** | Dedicatorias de dominio público |
| **Desconocida** | Licencias no reconocidas o faltantes |
### Modo Convert
Convierte SBOM entre formatos JSON de CycloneDX, SPDX y Syft. El formato de entrada se detecta automáticamente.```bash
# CycloneDX to SPDX
sbomlyze convert image.cdx.json --to spdx
# Syft to CycloneDX (cdx is an alias for cyclonedx)
sbomlyze convert syft-output.json --to cdx
# SPDX to Syft, writing to a file
sbomlyze convert spdx-output.json --to syft -o converted.json
Formatos de destino compatibles
| Formato | Valor de --to | Salida |
|---|---|---|
| CycloneDX 1.5 | cyclonedx o cdx | CycloneDX JSON con metadatos, dependencias y propiedades |
| SPDX 2.3 | spdx | SPDX JSON con paquetes, relaciones y referencias externas |
| Syft | syft | Syft JSON con artefactos, relaciones, fuente e información de distro |
Qué se conserva
La conversión conserva nombres de componentes, versiones, PURLs, CPEs, licencias, hashes, información del proveedor y relaciones de dependencia. Los campos específicos del formato (p. ej., lenguaje de Syft, foundBy, locations) se transmiten a través de las propiedades de CycloneDX al convertir a CDX.
Modo Diff (Dos Archivos)
Compara dos SBOMs para ver qué cambió entre versiones.```bash sbomlyze v1.0.json v2.0.json
#### Resumen del diff
El diff comienza con una comparación de metadatos lado a lado (nombres de archivos, tamaños, información del SO, información de herramientas, recuentos de componentes) seguido de los detalles del contexto del escaneo cuando estén disponibles.
#### Salida```
📊 Drift Summary:
📦 Version drift: 58 components
⚠️ Integrity drift: 1 component (hash changed without version change!)
📝 Metadata drift: 2 components
🔑 Key Findings:
📈 Attack surface: +5 packages (7.0%), +120 files (3.2%)
🚨 2 version downgrades detected: openssl 3.1.4→3.0.2, curl 8.5.0→8.4.0
🔄 56 version upgrades (2 major, 12 minor, 42 patch) among 65 shared packages
⚠️ Integrity drift (1 total): 1 npm (review recommended)
❌ python ecosystem entirely removed (15 → 0 packages)
➕ New ecosystem: golang (8 packages)
✅ Core system packages stable: apk (71) unchanged
+ Added (2):
+ libgcrypt 1.10.3-r0
+ libgpg-error 1.49-r0
- Removed (3):
- libapk 3.0.3-r1
- libgcc 15.2.0-r2
- nghttp3 1.13.1-r0
~ Changed (58):
~ nginx
version: 1.29.4-r1 -> 1.27.3-r1
~ suspicious-pkg ⚠️ [INTEGRITY]
hash[SHA256]: abc123 -> def456
>> Added dependencies:
pkg:apk/alpine/libxslt: +[so:libgcrypt.so.20]
<< Removed dependencies:
pkg:apk/alpine/libcurl: -[so:libnghttp3.so.9]
🔗 New transitive dependencies (3):
+ pkg:npm/lodash (depth 2)
via: [pkg:npm/my-app pkg:npm/express pkg:npm/lodash]
+ pkg:npm/underscore (depth 3)
via: [pkg:npm/my-app pkg:npm/express pkg:npm/lodash pkg:npm/underscore]
📊 New deps by depth:
Depth 2: 1
Depth 3+ (risky): 2 ⚠️
Hallazgos clave del diff
En modo diff, sbomlyze genera automáticamente información más detallada comparando ambos SBOM:
| Hallazgo | Descripción |
|---|---|
| Desajuste de contexto de escaneo | Advierte si la versión del esquema o el alcance del escaneo cambiaron entre SBOM |
| Delta de superficie de ataque | Cambios en el recuento de paquetes, archivos y relaciones con porcentajes |
| Ecosistemas desaparecidos/nuevos | Tipos de paquetes que aparecieron o desaparecieron por completo |
| Migración de SO/distro | Detecta cambios en el sistema operativo entre escaneos |
| Análisis de cambios de versión | Cuenta actualizaciones frente a degradaciones, clasifica los cambios como mayores/menores/patch |
| Degradaciones de versión | Señala las degradaciones como señal de seguridad con detalles de los componentes |
| Contexto de deriva de integridad | Desglosa la deriva de integridad por tipo de paquete con orientación de riesgo |
| Patrones de ruta dominantes | Cambios concentrados por tipo y ruta de sistema de archivos |
| Puntos críticos de eliminación/adición | Principales directorios afectados por los cambios |
| Tipos estables | Tipos de paquetes con recuentos idénticos (núcleo sin cambios) |
| Cambios en la categoría de licencia | Cambios en el equilibrio copyleft/permisiva |
| Lagunas del catalogador | Exploradores que encontraron paquetes en Before pero ninguno en After |
Muestras de paquetes por tipo
Los componentes añadidos y eliminados se agrupan por tipo de paquete con listados de muestra, lo que facilita ver qué cambió en cada ecosistema.
Puntuación de cumplimiento
Puntúe cualquier SBOM comparándolo con los tres marcos principales de elementos mínimos para responder a la pregunta que auditores y equipos de adquisiciones siguen haciendo: "¿Es este SBOM lo suficientemente completo?"```bash
Score a single SBOM
sbomlyze image.json --compliance
Score alongside a diff
sbomlyze before.json after.json --compliance
As JSON for CI
sbomlyze image.json --compliance --json
### Frameworks evaluados
| Framework | Checks | Requisitos notables |
|-----------|--------|----------------------|
| **NTIA Minimum Elements** (2021) | 7 | nombre, versión, proveedor, IDs únicos (PURL/CPE), relaciones de dependencia, autor del SBOM, marca de tiempo |
| **CISA 2025 Minimum Elements** (borrador de agosto de 2025) | 10 | añade productor de software, información de licencia, **hash del componente** y nombre de la herramienta además de los de NTIA |
| **BSI TR-03183-2** (v2.1.0, 2025) | 9 | requiere contacto del creador del componente, **hash SHA-512**, licencias en formato SPDX y contacto del creador del SBOM |
### Presentación de la puntuación
Cada framework reporta un porcentaje (comprobaciones aprobadas / comprobaciones totales) más una puntuación general (promedio entre frameworks), con indicadores de estado:
| Indicador | Puntuación |
|-----------|-------|
| 🟢 | ≥ 90% |
| 🟡 | 70–89% |
| 🟠 | 50–69% |
| 🔴 | < 50% |
La salida JSON (`--compliance --json`) incluye el informe completo con el detalle de aprobado/fallido por comprobación; el formato HTML incrusta el informe de cumplimiento en la página del informe.
### Puerta de cumplimiento en CI
Aplica umbrales de cumplimiento a través del [motor de políticas](#policy-engine). Establecer cualquier umbral activa la evaluación de cumplimiento sin la bandera `--compliance`:```json
{
"min_ntia_score": 85,
"min_cisa_score": 70,
"min_bsi_score": 80,
"min_overall_compliance": 75
}
sudo apt-get install chromium-browser```bash sbomlyze image.json --policy compliance-policy.json
## Diff del Grafo de Dependencias
sbomlyze va más allá de los diffs simples de listas de componentes para analizar el grafo de dependencias completo, detectando riesgos en la cadena de suministro introducidos a través de dependencias transitivas.
### Características
| Característica | Descripción |
|---------|-------------|
| **Diff de aristas** | Dependencias directas añadidas/eliminadas (A depende de B) |
| **Alcance transitivo** | Nuevas dependencias indirectas que aparecen a través del grafo |
| **Seguimiento de pérdidas transitivas** | Dependencias transitivas que fueron eliminadas |
| **Seguimiento de rutas** | Muestra exactamente cómo se alcanza cada nueva dependencia transitiva |
| **Seguimiento de profundidad** | A cuántos saltos está cada nueva dependencia de tu código |
| **Resumen de riesgo** | Dependencias de profundidad 3+ marcadas como de mayor riesgo |
### Por Qué Importa la Profundidad
Las dependencias introducidas más profundamente en el grafo son:
- Más difíciles de auditar y revisar
- A menudo incorporadas sin aprobación explícita
- Vectores comunes para ataques a la cadena de suministro (p. ej., el incidente de event-stream)
El resumen de profundidad ayuda a priorizar la revisión:
| Profundidad | Nivel de Riesgo | Descripción |
|-------|------------|-------------|
| **1** | Bajo | Dependencias directas (tú elegiste estas) |
| **2** | Medio | Dependencias de tus dependencias |
| **3+** | Alto ⚠️ | Dependencias transitivas profundas: revisa con cuidado |
### Ejemplo: Detección de Dependencias Transitivas Profundas```bash
# Before: app -> express (simple, 1 dep)
# After: app -> express -> lodash -> underscore -> deep-lib (chain of 4)
sbomlyze before.json after.json
No content was provided to translate.``` 🔗 New transitive dependencies (3):
- lodash (depth 2) via: [app express lodash]
- underscore (depth 3) via: [app express lodash underscore]
- deep-lib (depth 4) via: [app express lodash underscore deep-lib]
📊 New deps by depth: Depth 2: 1 Depth 3+ (risky): 2 ⚠️
### Salida JSON para el Grafo de Dependencias```json
{
"dependencies": {
"added_deps": {
"pkg:npm/express": ["pkg:npm/lodash", "pkg:npm/body-parser"]
},
"removed_deps": {},
"transitive_new": [
{
"target": "pkg:npm/underscore",
"via": ["pkg:npm/my-app", "pkg:npm/express", "pkg:npm/lodash", "pkg:npm/underscore"],
"depth": 3
}
],
"transitive_lost": [],
"depth_summary": {
"depth_1": 0,
"depth_2": 2,
"depth_3_plus": 2
}
}
}
Detección de deriva
sbomlyze clasifica los cambios de componentes en tres tipos de deriva, ayudándote a distinguir actualizaciones normales de cambios potencialmente sospechosos.
Tipos de deriva
| Tipo | Indicador | Descripción | Gravedad |
|---|---|---|---|
| Versión | 📦 | Número de versión cambiado | Normal |
| Integridad | ⚠️ | Hash cambiado SIN cambio de versión | Alta: ¡investigar! |
| Metadatos | 📝 | Solo metadatos (licencias, etc.) cambiados | Baja |
Deriva de integridad (señal de seguridad)
La deriva de integridad ocurre cuando el hash de un componente cambia pero su versión permanece igual. Esto podría indicar:
- Ataque a la cadena de suministro: El paquete fue reemplazado por una versión maliciosa
- Reconstrucción sin incremento de versión: Legítimo pero mala práctica
- Entorno de compilación diferente: Problemas de reproducibilidad```bash
Example output with integrity drift
~ suspicious-pkg ⚠️ [INTEGRITY] hash[SHA256]: abc123 -> def456
**Recomendación**: Investiga siempre la deriva de integridad. Puede ser benigna, pero es una señal clave para la seguridad de la cadena de suministro.
### Salida JSON para la deriva
El resumen de la deriva está dentro del objeto `diff`:```json
{
"diff": {
"changed": [
{
"id": "pkg:npm/suspicious-pkg",
"name": "suspicious-pkg",
"changes": ["hash[SHA-256]: abc123 -> def456"],
"drift": {
"type": "integrity",
"hash_changes": {
"changed": {
"SHA-256": {"before": "abc123", "after": "def456"}
}
}
}
}
],
"drift_summary": {
"version_drift": 55,
"integrity_drift": 1,
"metadata_drift": 2
}
}
}
Extrayendo resumen de deriva:```bash
Get drift summary
sbomlyze before.json after.json --json | jq '.diff.drift_summary'
Check for integrity drift in CI
sbomlyze before.json after.json --json | jq -e '.diff.drift_summary.integrity_drift > 0'
## Detección de Duplicados y Colisiones
### Detección de Duplicados
sbomlyze identifica componentes con la misma identidad pero diferentes versiones dentro de un SBOM:```
⚠️ Duplicates Found: 2
lodash: [4.17.20, 4.17.21]
express: [4.18.0, 4.19.2]
En el modo diff, el seguimiento de diferencias de versiones duplicadas rastrea:
- Duplicados nuevos: Componentes que se duplicaron en el nuevo SBOM
- Duplicados resueltos: Grupos de duplicados que se consolidaron
- Adiciones/eliminaciones de versiones: Cambios de versión dentro de grupos de duplicados existentes
Detección de colisiones
Las colisiones son coincidencias de identidad ambiguas en las que los componentes comparten el mismo ID pero tienen características conflictivas:
| Tipo | Descripción |
|---|---|
| Discrepancia de nombre | Nombres de componentes diferentes asignados al mismo ID de identidad |
| Discrepancia de hash | La misma versión de un componente tiene hashes diferentes (posible manipulación) |
Explorador de SBOM de SBOMlyze (TUI)```bash
sbomlyze sbom.json -i

### Atajos de teclado de la TUI
#### Navegación
| Tecla | Acción |
|-------|--------|
| `↑` / `k` | Moverse hacia arriba |
| `↓` / `j` | Moverse hacia abajo |
| `PgUp` / `Ctrl+u` | Media página hacia arriba |
| `PgDn` / `Ctrl+d` | Media página hacia abajo |
| `Inicio` / `g` | Ir al principio |
| `Fin` / `G` | Ir al final |
| `Enter` | Ver detalles del componente |
| `Esc` / `Retroceso` | Volver atrás |
| `q` / `Ctrl+c` | Salir |
#### Búsqueda y filtros
| Tecla | Acción |
|-------|--------|
| `/` | Búsqueda profunda en todos los campos (nombre, PURL, licencias, JSON sin procesar) |
| `t` | Filtrar por tipo de paquete (npm, apk, golang, pypi, etc.) |
| `c` | Borrar todos los filtros activos |
#### Vistas
| Tecla | Contexto | Acción |
|-------|----------|--------|
| `j` | Vista de detalles | Ver el JSON sin procesar del componente con resaltado de sintaxis |
| `d` | Vista JSON | Volver a la vista de detalles |
| `Enter` | Vista JSON | Exportar el JSON del componente a un archivo |
| `?` | Cualquier vista | Mostrar ayuda con todos los atajos de teclado |
### Vista de detalles del componente
La vista de detalles muestra información completa del componente:
- Información del paquete (nombre, versión, PURL, espacio de nombres, proveedor)
- Licencias con indicadores visuales
- Hashes de integridad
- CPE (Common Platform Enumeration)
- Lista de dependencias
- Identificadores (ID, BOM-ref, SPDX-ID)
## Modo interfaz web
Inicie un explorador de SBOM basado en navegador con carga de archivos mediante arrastrar y soltar:```bash
# Start web server on default port 8080
sbomlyze -web
# Start on custom port
sbomlyze -web --port 3000
Luego abre http://localhost:8080 en tu navegador.
Funciones de la interfaz web
| Característica | Descripción |
|---|---|
| Carga por arrastrar y soltar | Suelta cualquier archivo SBOM (Syft, CycloneDX, SPDX) en la página (hasta 500MB) |
| Árbol de dependencias | Vista de árbol interactiva con navegación expandir/contraer (paginada para >5000 componentes) |
| Detalles del componente | Consulta licencias, hashes, dependencias, información del proveedor y recuento de archivos |
| Vista JSON sin procesar | JSON con resaltado de sintaxis para cada componente |
| Búsqueda profunda | Busca en todos los campos, incluidos los datos JSON sin procesar |
| Panel de estadísticas | Métricas de cobertura, categorías de licencias, distribución de lenguajes |
| Explorador del sistema de archivos | Explora archivos dentro del SBOM con navegación por directorios, búsqueda y filtrado por capas |
Estadísticas mostradas
La interfaz web muestra estadísticas completas, incluyendo:
- Recuentos de componentes por tipo de paquete (npm, apk, pypi, etc.)
- Distribución de licencias con desglose por categoría (copyleft, permisiva, dominio público)
- Métricas de cobertura con barras de progreso visuales:
- Cobertura PURL (presencia de URL del paquete)
- Cobertura CPE (preparación para el escaneo de vulnerabilidades)
- Cobertura de licencias
- Cobertura de hash/integridad
- Desglose por lenguaje (para SBOM generados por Syft)
- Estadísticas de relaciones (contains, dependency-of, evident-by)
- Advertencias de detección de duplicados
Casos de uso
Revisión de seguridad
- Sube un SBOM y explora el árbol de dependencias completo
- Verifica la cobertura CPE para asegurar que el escaneo de vulnerabilidades funcione
- Revisa componentes sin licencias ni hashes
Auditoría de cumplimiento
- Busca licencias específicas en todos los componentes
- Consulta la distribución por categorías de licencia (copyleft vs permisiva)
- Exporta JSON sin procesar para documentación
Depuración de desarrollo
- Explora qué paquetes están incluidos en tu imagen
- Verifica las dependencias transitivas
- Verifica que los metadatos del paquete sean correctos
Explorador del sistema de archivos
La interfaz web incluye un explorador de sistema de archivos completo para explorar archivos dentro de SBOM (especialmente útil para SBOM generados por Syft con metadatos de archivos):
- Navegación por árbol de directorios con ruta de migas de pan
- Búsqueda de archivos compatible con patrones de subcadena y glob (p. ej.,
*.so,/usr/lib/**/*.conf) - Filtrado por capas para SBOM de imágenes de contenedor (explora archivos por capa de imagen)
- Relaciones componente-archivo (qué componente es propietario de qué archivos)
- Estadísticas de archivos por tipo, tipo MIME, extensión y capa
- Detección de archivos sin propietario (archivos no asociados con ningún componente)
Opciones
-i (Modo interactivo)
Lanza el explorador TUI basado en terminal para navegar por los SBOM con controles de teclado.```bash sbomlyze image.json -i
Características: navegación por árbol, detalles de componentes, búsqueda, inspección de licencias/hashes.
### `-web` (Modo Servidor Web)
Inicia un servidor web para la exploración de SBOM basada en navegador.```bash
# Default port 8080
sbomlyze -web
# Custom port
sbomlyze -web --port 3000
La interfaz web ofrece carga mediante arrastrar y soltar, vista de árbol interactiva, búsqueda profunda y panel de estadísticas.
--compliance
Evalúa el SBOM según los marcos de elementos mínimos de NTIA, CISA 2025 y BSI TR-03183. Consulta Puntuación de Cumplimiento.```bash sbomlyze image.json --compliance sbomlyze image.json --compliance --json
### `--format` / `-f`
Selecciona el formato de salida. Hay siete formatos disponibles:
| Formato | Flag | Descripción | Mejor para |
|--------|------|-------------|----------|
| **text** | `--format text` (por defecto) | Salida de terminal legible por humanos | Inspección local |
| **json** | `--json` o `--format json` | JSON estructurado | Pipelines de CI, scripting |
| **sarif** | `--format sarif` | SARIF 2.1.0 para GitHub Code Scanning | Integración con GitHub |
| **junit** | `--format junit` | Resultados de pruebas JUnit en XML | Paneles de pruebas CI |
| **markdown** | `--format markdown` | Informe Markdown listo para comentarios de PR | Comentarios de pull requests |
| **html** | `--format html` | Informe HTML autocontenido (CSS/JS en línea) | Auditores, informes compartibles |
| **patch** | `--format patch` | Operaciones JSON Patch RFC 6902 | Aplicación de parches programática |```bash
# SARIF output for GitHub Code Scanning
sbomlyze before.json after.json --format sarif > results.sarif
# JUnit output for CI test dashboards
sbomlyze before.json after.json --format junit > results.xml
# Markdown report for PR comments
sbomlyze before.json after.json --format markdown > report.md
# Self-contained HTML report
sbomlyze before.json after.json --format html > report.html
# JSON Patch operations
sbomlyze before.json after.json --format patch > changes.json
Formato SARIF
Genera un informe SARIF 2.1.0 adecuado para GitHub Code Scanning. Las reglas detectadas incluyen:
integrity-drift(error): hash cambiado sin cambio de versióndeep-dependency(warning): nueva dependencia en profundidad 3+new-component/removed-component(note): adiciones/eliminaciones de componentesversion-change(note): actualizaciones de versión de componentespolicy-violation(error/warning): violaciones de reglas de políticas
Formato JUnit
Genera XML JUnit con casos de prueba para:
- Sin desviación de integridad
- Sin dependencias transitivas profundas (profundidad 3+)
- Cumplimiento de políticas (un caso de prueba por violación)
- Resumen de diff de SBOM
Formato Markdown
Genera un informe Markdown con:
- Tabla comparativa de SBOM lado a lado (archivo, tamaño, SO, métricas de cobertura)
- Detalles del contexto de escaneo
- Hallazgos clave
- Paquetes añadidos/eliminados agrupados por tipo (en secciones plegables)
- Resumen de desviación, profundidad de dependencias y violaciones de políticas
Formato HTML
Genera un único archivo HTML autocontenido (CSS y JavaScript en línea, sin recursos externos) adecuado para enviar por correo a auditores o adjuntar a un lanzamiento. Incluye el panel de estadísticas, el árbol de dependencias, el resumen de desviación y el informe de cumplimiento integrado cuando se especifica --compliance.
Formato Patch
Genera un array de operaciones JSON Patch RFC 6902 (add, remove, replace) que representan el diff.
--json
Abreviatura de --format json. Muestra los resultados en formato JSON para consumo programático.```bash
Stats as JSON
sbomlyze image.json --json
Diff as JSON
sbomlyze before.json after.json --json
**Estructura JSON de estadísticas:**```json
{
"stats": {
"total_components": 71,
"by_type": {"apk": 71},
"by_license": {"MIT": 17, "BSD-3-Clause": 8},
"without_license": 0,
"with_hashes": 0,
"without_hashes": 71,
"total_dependencies": 176,
"with_dependencies": 65,
"duplicate_count": 0,
"by_language": {"go": 45, "python": 12},
"by_found_by": {"apk-db-cataloger": 71},
"license_categories": {
"copyleft": 8,
"permissive": 55,
"public_domain": 0,
"unknown": 8
},
"with_cpes": 71,
"without_cpes": 0,
"with_purl": 71,
"without_purl": 0
},
"warnings": []
}
--policy <file>
Aplicar reglas de políticas y hacer fallar la CI si se violan.```bash sbomlyze before.json after.json --policy policy.json
Consulta [Policy Engine](#policy-engine) para obtener más detalles.
### `--strict`
Falla inmediatamente ante cualquier error de análisis.```bash
sbomlyze broken.json --strict
# Error parsing broken.json: unknown SBOM format
# exit status 1
--tolerant (por defecto)
Continuar el procesamiento ante errores, recopilar advertencias.```bash sbomlyze broken.json --tolerant
📦 SBOM Statistics
==================
Total Components: 0
...
⚠️ Parse Warnings (1):
[broken.json] unknown SBOM format
Parse warnings include structured information: the source file, a human-readable message, and optionally the field that caused the issue.
### `--no-pager`
Disable automatic output paging. Useful when piping output to another command or when running in non-interactive environments.```bash
sbomlyze image.json --no-pager
sbomlyze before.json after.json --no-pager | head -20
Motor de políticas
Crea políticas para aplicar reglas en los pipelines de CI/CD. sbomlyze sale con el código 1 cuando se producen violaciones.
Formato de archivo de políticas```json
{ "max_added": 10, "max_removed": 5, "max_changed": 100, "deny_licenses": ["GPL-3.0", "AGPL-3.0"], "require_licenses": true, "deny_duplicates": true, "deny_integrity_drift": true, "max_depth": 3, "warn_supplier_change": true, "warn_new_transitive": true, "min_ntia_score": 85, "min_cisa_score": 70, "min_bsi_score": 80, "min_overall_compliance": 75 }
### Reglas de Política
| Regla | Tipo | Descripción |
|------|------|-------------|
| `max_added` | int | Máximo de nuevos componentes permitidos (0 = ilimitado) |
| `max_removed` | int | Máximo de componentes eliminados permitidos (0 = ilimitado) |
| `max_changed` | int | Máximo de componentes modificados permitidos (0 = ilimitado) |
| `deny_licenses` | []string | Lista de identificadores de licencia prohibidos |
| `require_licenses` | bool | Exigir que todos los componentes *agregados* tengan licencias (solo verifica los componentes recién agregados en modo diff) |
| `deny_duplicates` | bool | Fallar si existen paquetes duplicados en el resultado |
| `deny_integrity_drift` | bool | Fallar si el hash del componente cambió sin cambio de versión (riesgo de cadena de suministro) |
| `max_depth` | int | Fallar si hay nuevas dependencias transitivas a profundidad >= N (0 = ilimitado) |
| `warn_supplier_change` | bool | Advertir (no fallar) si el proveedor/autor del componente cambió |
| `warn_new_transitive` | bool | Advertir (no fallar) sobre cualquier nueva dependencia transitiva |
| `min_ntia_score` | int | Fallar si la puntuación de cumplimiento NTIA está por debajo de esto (0-100, 0 = deshabilitado) |
| `min_cisa_score` | int | Fallar si la puntuación de cumplimiento CISA está por debajo de esto (0-100, 0 = deshabilitado) |
| `min_bsi_score` | int | Fallar si la puntuación de cumplimiento BSI está por debajo de esto (0-100, 0 = deshabilitado) |
| `min_overall_compliance` | int | Fallar si la puntuación de cumplimiento general está por debajo de esto (0-100, 0 = deshabilitado) |
> Establecer cualquier umbral `min_*_score` activa automáticamente la evaluación de cumplimiento, incluso sin la bandera `--compliance`.
### Ejemplo: Política Estricta```json
{
"max_added": 5,
"max_removed": 3,
"max_changed": 20,
"deny_licenses": ["GPL-3.0", "AGPL-3.0", "SSPL-1.0"],
"require_licenses": true,
"deny_duplicates": true,
"deny_integrity_drift": true,
"max_depth": 3,
"warn_supplier_change": true,
"warn_new_transitive": true,
"min_overall_compliance": 80
}
Salida de Violaciones de Políticas```
!! Policy Violations (3): [max_added] too many components added: 10 > 5 [max_removed] too many components removed: 7 > 3 [deny_licenses] component foo has denied license: GPL-3.0
## Formatos SBOM compatibles
| Formato | Detección de archivo | Identificadores extraídos |
|--------|----------------|----------------------|
| Syft (nativo) | Clave JSON `"artifacts"` + una de `"source"`, `"distro"`, `"descriptor"` | PURL, CPE, name |
| CycloneDX | Clave JSON `"bomFormat"` = `"CycloneDX"`, o `"$schema"` que contenga `cyclonedx` | PURL, CPE, BOM-ref, group (namespace) |
| SPDX | Clave JSON `"spdxVersion"` que comience con `"SPDX-"` | PURL, CPE, SPDXID |
Todos los formatos deben ser JSON. Actualmente no hay soporte para XML.
### Conversión de formatos
sbomlyze puede convertir entre cualquiera de los tres formatos compatibles:```bash
sbomlyze convert input.json --to spdx # any format → SPDX 2.3
sbomlyze convert input.json --to cyclonedx # any format → CycloneDX 1.5
sbomlyze convert input.json --to syft # any format → Syft JSON
Ver Modo Convertir para más detalles.
Comparación entre formatos
sbomlyze puede comparar SBOMs en diferentes formatos:```bash
Compare Syft output with CycloneDX
sbomlyze syft-output.json cyclonedx-output.json
Compare SPDX with Syft
sbomlyze spdx-output.json syft-output.json
**Nota:** Los diferentes formatos SBOM extraen distintos niveles de detalle. Una diferencia entre formatos puede mostrar cambios que reflejan diferencias de formato (p. ej., disponibilidad de campos) en lugar de cambios reales en el sistema. El sistema de hallazgos clave advertirá sobre discrepancias de contexto de escaneo cuando se detecten.
## Coincidencia de identidad de componentes
Los componentes se emparejan mediante un sistema de identidad basado en prioridad:
| Prioridad | Identificador | Ejemplo | Descripción |
|----------|------------|---------|-------------|
| 1 | PURL | `pkg:npm/lodash` | URL del paquete (versión eliminada) |
| 2 | CPE | `cpe:vendor:product` | CPE proveedor:producto (versión eliminada) |
| 3 | BOM-ref / SPDXID | `ref:component-123` | CycloneDX bom-ref o identificador SPDX |
| 4 | Namespace + Nombre | `com.example/mypackage` | Grupo/espacio de nombres con nombre |
| 5 | Nombre | `simple-package` | Respaldo al nombre únicamente |
## Integración CI/CD
### GitHub Actions
SBOMlyze se distribuye como una Action de JavaScript sin dependencias. Compara un SBOM head incluido en el repositorio o generado por separado con el archivo en la base git del pull request, publica un Job Summary y, opcionalmente, produce SARIF o actualiza un comentario del PR.```yaml
name: SBOM Check
on:
pull_request:
permissions:
contents: read
jobs:
sbom-diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- id: sbomlyze
uses: rezmoss/sbomlyze@31503690611fda8ebba4ed2bd186eda000442594 # v0.5.1
with:
sbom-path: build/sbom.cdx.json
policy: .github/sbom-policy.json
fail-on: policy
GitLab CI
La Action nunca ejecuta comandos de generador. Genere el SBOM principal en un paso separado,
revisado, o haga commit de él en el repositorio. comment y sarif tienen como valor
predeterminado false; los PR bifurcados aún reciben el Job Summary completo cuando el
permiso de comentario no está disponible. Consulte la referencia de la Action para conocer
cada entrada/salida, fijación de SHA, carga de SARIF, permisos y comportamiento de seguridad.```yaml
sbom-diff:
stage: test
script:
- syft . -o json > current.json
- sbomlyze baseline.json current.json --policy policy.json --json > sbom-report.json
- sbomlyze baseline.json current.json --format junit > sbom-junit.xml
artifacts:
paths:
- sbom-report.json
reports:
junit: sbom-junit.xml
when: always
### Alerta de deriva de integridad```bash
# Alert on any integrity drift (CI example)
if sbomlyze baseline.json current.json --json | jq -e '.diff.drift_summary.integrity_drift > 0' > /dev/null; then
echo "⚠️ INTEGRITY DRIFT DETECTED - Investigate immediately!"
exit 1
fi
Alerta de dependencia profunda```bash
Alert on new deep transitive dependencies
if sbomlyze baseline.json current.json --json | jq -e '.diff.dependencies.depth_summary.depth_3_plus > 0' > /dev/null; then echo "⚠️ New deep transitive dependencies detected - Review required!" fi
### Puerta de Cumplimiento```bash
# Fail the build if the SBOM doesn't meet minimum-element requirements
sbomlyze current.json --policy compliance-policy.json
# where compliance-policy.json sets min_overall_compliance / min_ntia_score / etc.
Códigos de Salida
| Código | Significado |
|---|---|
| 0 | Éxito, sin diferencias ni violaciones |
| 1 | Diferencias encontradas (cualquier componente añadido/eliminado/modificado), violaciones de políticas o errores |
Nota: En modo diff, se devuelve el código de salida 1 siempre que se detecte cualquier cambio en los componentes, incluso sin un archivo de políticas. Esto lo hace utilizable como una simple compuerta de "¿cambió algo?" en CI.
Ejemplos
Comparar Imágenes de Docker```bash
Generate SBOMs
syft nginx:1.25-alpine -o json > nginx-125.json syft nginx:1.26-alpine -o json > nginx-126.json
Compare
sbomlyze nginx-125.json nginx-126.json
### Auditoría de licencias```bash
# Check for GPL licenses in new dependencies
cat > audit-policy.json << EOF
{
"deny_licenses": ["GPL-2.0", "GPL-3.0", "LGPL-2.1", "LGPL-3.0"],
"require_licenses": true
}
EOF
sbomlyze old.json new.json --policy audit-policy.json
Detección de deriva de dependencias```bash
Detect any changes (strict mode for no drift)
cat > no-drift.json << EOF { "max_added": 0, "max_removed": 0, "max_changed": 0 } EOF
sbomlyze baseline.json current.json --policy no-drift.json
### Comprobación de Cumplimiento```bash
# Score an SBOM and enforce a minimum
sbomlyze image.json --compliance
cat > compliance-policy.json << EOF
{
"min_ntia_score": 90,
"min_overall_compliance": 80
}
EOF
sbomlyze image.json --policy compliance-policy.json
Convertir Formatos de SBOM```bash
Convert a Syft SBOM to CycloneDX for tools that require it
syft alpine:latest -o json > alpine-syft.json sbomlyze convert alpine-syft.json --to cyclonedx -o alpine-cdx.json
Convert CycloneDX to SPDX for compliance workflows
sbomlyze convert vendor-sbom.cdx.json --to spdx > vendor-sbom.spdx.json
Pipe conversion output directly
sbomlyze convert input.json --to spdx | jq '.packages | length'
### Explorar SBOM en el navegador```bash
# Generate SBOM and explore in web UI
syft alpine:latest -o json > alpine.json
# Start web server
sbomlyze -web
# Then open http://localhost:8080 and drag-drop alpine.json
Exploración interactiva del terminal```bash
Explore with keyboard navigation
sbomlyze alpine.json -i
Navigate with arrow keys, search with '/', view details with Enter
## Desarrollo
### Ejecutar pruebas```bash
make test
# or
go test -v ./...
Lint```bash
make lint # runs go vet + golangci-lint + staticcheck make vulncheck # runs govulncheck for known CVEs
### Compilación```bash
make build-quick
# or
go build -o sbomlyze ./cmd/sbomlyze
Comandos Make```bash
make all # Run test, lint, and build make test # Run all tests with race detector make lint # Run go vet, golangci-lint, and staticcheck make vulncheck # Run govulncheck for known vulnerabilities make build # Build with goreleaser (snapshot) make build-quick # Quick build for development make snapshot-test # Run snapshot tests only make update-snapshot # Update snapshot golden files make clean # Remove build artifacts
## Contribuyendo
¡Las contribuciones son bienvenidas! Los issues de buena entrada están etiquetados con [`good first issue`](https://github.com/rezmoss/sbomlyze/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). Consulta [CONTRIBUTING.md](https://github.com/rezmoss/sbomlyze/blob/HEAD/CONTRIBUTING.md) si existe, y no dudes en abrir un issue o una discusión para proponer cambios.
[ci]: https://github.com/rezmoss/sbomlyze/actions/workflows/ci.yml
[ci-img]: https://github.com/rezmoss/sbomlyze/actions/workflows/ci.yml/badge.svg
[marketplace]: https://github.com/marketplace/actions/sbomlyze-diff
[marketplace-img]: https://img.shields.io/badge/Marketplace-SBOMlyze%20Diff-blue?logo=github
[release]: https://github.com/rezmoss/sbomlyze/releases
[release-img]: https://img.shields.io/github/v/release/rezmoss/sbomlyze
[go-report]: https://goreportcard.com/report/github.com/rezmoss/sbomlyze
[go-report-img]: https://goreportcard.com/badge/github.com/rezmoss/sbomlyze
[license]: https://raw.githubusercontent.com/rezmoss/sbomlyze/main/LICENSE
[license-img]: https://img.shields.io/badge/License-Apache%202.0-blue.svg
[download]: https://github.com/rezmoss/sbomlyze/releases
[download-img]: https://img.shields.io/github/downloads/rezmoss/sbomlyze/total
[scorecard]: https://scorecard.dev/viewer/?uri=github.com/rezmoss/sbomlyze
[scorecard-img]: https://api.scorecard.dev/projects/github.com/rezmoss/sbomlyze/badge
