Un SBOM (Software Bill of Materials) es un inventario de todos los componentes de software en un producto, y se está convirtiendo en un requisito legal para dispositivos embebidos. El CRA de la UE exige la entrega de SBOM para 2027, la FDA ya lo requiere para dispositivos médicos, y Yocto Scarthgap genera SBOMs de forma nativa.
Esta guía te lleva paso a paso por la generación de SBOMs y el escaneo de vulnerabilidades CVE usando las herramientas integradas de Yocto Scarthgap 5.0 LTS (BitBake 2.8). Desde el contexto regulatorio hasta la configuración práctica y flujos de trabajo de producción — todo en un artículo.
Por qué SBOM se está volviendo obligatorio para embebidos
Un SBOM (Software Bill of Materials) es un inventario de todos los componentes de software en un producto. Qué bibliotecas están incluidas, qué versiones son y qué licencias usan — registrado en un formato legible por máquina.
Podrías pensar "somos demasiado pequeños para que esto importe." Pero si distribuyes productos en la UE, EE.UU. o mercados automotrices, tu equipo ya está afectado.
Ley de Ciberresiliencia de la UE (CRA)
El CRA (Reglamento UE 2024/2847) entró en vigor el 10 de diciembre de 2024. Los requisitos completos aplican desde el 11 de diciembre de 2027 (las obligaciones de reporte de vulnerabilidades comienzan el 11 de septiembre de 2026). Cubre a toda empresa que fabrique, venda o importe productos con elementos digitales al mercado de la UE. Las empresas japonesas que exportan a la UE están incluidas.
Requisitos específicos de SBOM:
- Crear y mantener SBOMs en formato legible por máquina (SPDX / CycloneDX)
- Deben estar disponibles para las autoridades de vigilancia del mercado bajo solicitud
- Multas de hasta 15 millones de euros o el 2.5% de los ingresos anuales globales
Dispositivos médicos (FDA)
La FDA de EE.UU. ha requerido la entrega de SBOM desde marzo de 2023 bajo la Sección 524B de la Ley FD&C (PATCH Act). Los SBOMs son obligatorios para las solicitudes previas al mercado. La FDA puede rechazar solicitudes sin uno.
Automotriz (UN-R155 / R156)
UN-R155 no exige explícitamente SBOMs. Sin embargo, operar un Sistema de Gestión de Ciberseguridad (CSMS) requiere conocer la composición del software, y la gestión de vulnerabilidades no funciona sin él. En Japón, la homologación UN-R155 es obligatoria para nuevos tipos de vehículos desde julio de 2022, y desde julio de 2024 se aplica a todos los vehículos de nueva producción, incluyendo tipos existentes.
Japón
Todavía no hay mandato legal. Sin embargo, METI (Ministerio de Economía, Comercio e Industria) ha publicado la "Guía para la Introducción de SBOMs" (versión 2.0, agosto 2024), ampliamente vista como preparación para futura legislación. En septiembre de 2025, Japón cofirmó un documento de orientación internacional de SBOM de 15 naciones liderado por CISA/NSA.
Generación de SBOMs con create-spdx
La documentación de SBOM de Yocto cubre la clase create-spdx completa. En Scarthgap, la configuración predeterminada de la distribución Poky (poky.conf) incluye INHERIT += "create-spdx", así que está habilitado por defecto. Una compilación normal genera SBOMs automáticamente en formato SPDX 2.2.
Verificar si está habilitado
bitbake-getvar -r core-image-minimal INHERIT
Si la salida incluye create-spdx, estás listo. Si no, añade lo siguiente a conf/local.conf.
# conf/local.conf — habilitar create-spdx manualmente (normalmente innecesario)
INHERIT += "create-spdx"
Configuración recomendada
# conf/local.conf — configuración recomendada de SBOM
SPDX_PRETTY = "1"
SPDX_PRETTY añade indentación a la salida JSON, haciéndola legible por humanos. El tamaño del archivo aumenta, pero vale la pena para depuración y revisión.
Si necesitas trazabilidad del código fuente, añade también esto.
# conf/local.conf — incluir información de fuentes en el SBOM (opcional)
SPDX_INCLUDE_SOURCES = "1"
SPDX_ARCHIVE_SOURCES = "1"
Compilar y verificar la salida
Ejecuta una compilación normal.
bitbake core-image-minimal
Después de que la compilación termine, el SBOM está en:
tmp/deploy/images/<MACHINE>/core-image-minimal-<MACHINE>.spdx.tar.zst
Extrae e inspecciona el contenido.
cd tmp/deploy/images/qemux86-64/
mkdir spdx-output && cd spdx-output
tar -I zstd -xf ../core-image-minimal-qemux86-64.spdx.tar.zst
ls *.spdx.json | head -10
Entendiendo la salida del SBOM
Después de la extracción, encontrarás un archivo SPDX por receta. Cada archivo está en formato SPDX 2.2 JSON.
Estructura de archivos
spdx-output/
├── recipe-core-image-minimal.spdx.json ← imagen completa
├── recipe-busybox.spdx.json ← receta individual
├── recipe-glibc.spdx.json
├── recipe-openssl.spdx.json
└── ...
Campos JSON clave
Al abrir un archivo SPDX individual se muestra una estructura como esta (simplificada).
{
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"name": "recipe-openssl",
"packages": [
{
"name": "openssl",
"versionInfo": "3.2.1",
"supplier": "Organization: OpenSSL",
"downloadLocation": "https://www.openssl.org/source/openssl-3.2.1.tar.gz",
"licenseConcluded": "Apache-2.0",
"licenseDeclared": "Apache-2.0"
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-Recipe",
"relationshipType": "GENERATES",
"relatedSpdxElement": "SPDXRef-Package-openssl"
}
]
}
Los campos clave para cumplimiento:
- packages: Nombre del paquete, versión, licencia y ubicación de descarga
- relationships: Cadena de dependencias entre recetas y paquetes
- licenseConcluded / licenseDeclared: Información de licencia (siempre revisada en auditorías)
Escaneo de vulnerabilidades con cve-check
La clase cve-check cruza las referencias de los paquetes compilados contra la NVD del NIST (National Vulnerability Database) para detectar vulnerabilidades conocidas. La documentación de verificación de vulnerabilidades de Yocto cubre la configuración completa. A diferencia de create-spdx, debe habilitarse manualmente.
Habilitarlo
# conf/local.conf — habilitar verificación de CVE
INHERIT += "cve-check"
Verificar una receta específica
bitbake -c cve_check openssl
Verificar la imagen completa
Con INHERIT += "cve-check" configurado, una compilación normal genera reportes de CVE automáticamente.
bitbake core-image-minimal
Ubicación de los reportes
tmp/deploy/cve/
├── openssl ← texto por receta
├── openssl_cve.json ← JSON por receta
└── ...
tmp/deploy/images/<MACHINE>/
├── core-image-minimal-<MACHINE>.cve ← texto de toda la imagen
└── core-image-minimal-<MACHINE>.cve.json ← JSON de toda la imagen
Se generan tanto formatos de texto como JSON por defecto.
Lectura del reporte
El reporte de texto lista cada CVE con su estado.
PACKAGE NAME: openssl
PACKAGE VERSION: 3.2.1
CVE: CVE-2024-XXXXX
CVE STATUS: Patched
CVE SUMMARY: ...
CVE: CVE-2024-YYYYY
CVE STATUS: Unpatched
CVE SUMMARY: ...
Hay tres valores de estado:
- Patched: Corregido por un parche de Yocto
- Unpatched: No corregido. Necesita atención
- Ignored: Ignorado intencionalmente (configurado vía
CVE_STATUS)
Filtrado del ruido en reportes CVE
Habilitar las verificaciones de CVE puede inundarte de resultados. Solo el kernel Linux tiene miles de CVEs registrados, y la gran mayoría no aplica a tu arquitectura o configuración de kernel específica.
Marcar CVEs individuales con CVE_STATUS
Cuando un CVE específico no aplica a tu plataforma, exclúyelo con CVE_STATUS.
# En una receta o bbappend
CVE_STATUS[CVE-2024-12345] = "not-applicable-platform: Only affects Windows"
CVE_STATUS[CVE-2024-67890] = "not-applicable-config: Feature disabled in our config"
Los valores de estado están predefinidos en cve-check-map.conf. Los comunes incluyen not-applicable-platform, not-applicable-config, cpe-incorrect y upstream-wontfix. El texto después de los dos puntos documenta la razón específica, haciendo las exclusiones auditables. Puedes gestionar estas configuraciones en un bbappend sin modificar la receta original. Si migras desde Kirkstone, necesitarás reescribir CVE_CHECK_IGNORE a CVE_STATUS — consulta la lista de verificación de migración.
Gestión por lotes con CVE_STATUS_GROUPS
Cuando muchos CVEs comparten la misma razón de exclusión, agrúpalos para una gestión más fácil.
# conf/local.conf o un archivo inc personalizado
CVE_STATUS_GROUPS = "CVE_STATUS_WIN CVE_STATUS_ARM32"
CVE_STATUS_WIN = "CVE-2024-11111 CVE-2024-22222 CVE-2024-33333"
CVE_STATUS_WIN[status] = "not-applicable-platform: Windows-only vulnerability"
CVE_STATUS_ARM32 = "CVE-2024-44444 CVE-2024-55555"
CVE_STATUS_ARM32[status] = "not-applicable-platform: ARM32-only, we target ARM64"
Limitar el alcance del escaneo por capa
Útil cuando solo quieres verificar tu propia capa.
# conf/local.conf — verificar solo tu capa
CVE_CHECK_LAYER_INCLUDELIST = "meta-mylayer"
# o excluir capas específicas
CVE_CHECK_LAYER_EXCLUDELIST = "meta-poky"
Usar la lista de exclusiones oficial
Poky viene con una lista de exclusiones de CVE predefinida.
# conf/local.conf
include conf/distro/include/cve-extra-exclusions.inc
Flujo de trabajo de producción
Así es como integrar SBOM y verificación de CVE en tu flujo de compilación diario.
conf/local.conf recomendado
# conf/local.conf — configuración recomendada de SBOM + CVE
# Generación de SBOM (habilitado por defecto, pero hacerlo explícito)
INHERIT += "create-spdx"
SPDX_PRETTY = "1"
# Verificación de CVE
INHERIT += "cve-check"
# Lista oficial de exclusiones de CVE
include conf/distro/include/cve-extra-exclusions.inc
Flujo por compilación
1. bitbake <image>
↓ automático
2. SBOM generado → tmp/deploy/images/MACHINE/IMAGE.spdx.tar.zst
↓ automático
3. Reporte CVE generado → tmp/deploy/images/MACHINE/IMAGE.cve
↓
4. Revisar CVEs sin parche
↓
5. Aplicar parches o excluir con CVE_STATUS (con razones documentadas)
↓
6. Archivar SBOM + reporte CVE en control de versiones
Extraer CVEs sin parche
# Extraer entradas Unpatched del reporte de texto
grep -B 3 "CVE STATUS: Unpatched" \
tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.cve
Para depurar problemas de compilación que surjan al parchear CVEs, la guía de depuración de errores de compilación cubre técnicas de devshell y análisis de logs.
Lista de verificación de cumplimiento del CRA de la UE
| # | Requisito | Cómo lo maneja Yocto |
|---|---|---|
| 1 | SBOM legible por máquina | create-spdx (habilitado por defecto) |
| 2 | Escaneo de vulnerabilidades conocidas | cve-check |
| 3 | Documentación de respuesta a vulnerabilidades | CVE_STATUS con razones |
| 4 | Actualizaciones regulares del SBOM | Regenerar SBOM con cada compilación de release |
| 5 | Preparación para envío a autoridades | Archivar .spdx.tar.zst como artefactos de compilación |
FAQ
¿Cuál es la diferencia entre SPDX y CycloneDX?
Ambos son formatos SBOM legibles por máquina. SPDX (ISO/IEC 5962:2021) fue creado por la Linux Foundation con enfoque en cumplimiento de licencias. CycloneDX fue creado por OWASP con enfoque en seguridad y seguimiento de vulnerabilidades. El create-spdx de Yocto genera formato SPDX. Tanto el CRA de la UE como la FDA aceptan ambos formatos. Si tus herramientas o clientes no tienen preferencia, SPDX es la opción natural para proyectos Yocto ya que se genera nativamente.
¿Necesita cve-check conexión a internet?
Sí, para la descarga inicial de la base de datos NVD y las actualizaciones posteriores. La API de NIST NVD tiene límites de velocidad, así que la primera descarga puede tomar de 10 a 30 minutos. Después, solo se descargan actualizaciones incrementales. Para entornos aislados (air-gapped), puedes pre-descargar los datos NVD y apuntar cve-check a un mirror local.
¿Con qué frecuencia debo regenerar los SBOMs?
Como mínimo, regenera con cada compilación de release. Para productos bajo el alcance del CRA de la UE, necesitas mantener SBOMs "actualizados", lo que significa regenerar siempre que actualices un componente. Un enfoque práctico: genera como parte de tu pipeline CI/CD en cada compilación de rama de release, y archiva junto con los artefactos de imagen.
¿Puedo usar cve-check en CI sin compilaciones completas?
Sí. Usa bitbake -c cve_check <receta> para escanear recetas individuales sin compilar la imagen completa. Esto es útil para verificaciones rápidas en pipelines de merge requests. Sin embargo, para reportes completos, el escaneo a nivel de imagen (bitbake <image> con cve-check heredado) da el panorama completo.
¿Qué significa CVE_STATUS "cpe-incorrect"?
CPE (Common Platform Enumeration) es cómo la NVD identifica el software afectado. A veces el CPE de una entrada NVD coincide con el nombre de tu paquete pero se refiere a un software completamente diferente. Por ejemplo, un CVE para "python-json" podría coincidir con tu receta personalizada json pero en realidad apunta a otro proyecto. cpe-incorrect marca estos falsos positivos.
¿Cómo manejo los CVEs del kernel Linux?
El kernel es la fuente más ruidosa de reportes CVE — miles de entradas, la mayoría irrelevantes para tu configuración. Empieza con el cve-extra-exclusions.inc de Poky para entradas conocidas como no aplicables. Luego usa CVE_STATUS_GROUPS para excluir por lotes CVEs que solo afectan subsistemas que has deshabilitado. Documenta cada exclusión con la justificación de tu configuración del kernel. La documentación de vulnerabilidades de Yocto tiene orientación específica para el kernel.
¿La generación de SBOM añade tiempo significativo de compilación?
Mínimo. La clase create-spdx se ejecuta como paso de post-procesamiento y añade solo segundos a la compilación. No recompila nada — recopila metadatos que BitBake ya rastrea. cve-check tiene un costo inicial mayor (descarga de NVD), pero las compilaciones posteriores añaden solo unos minutos para la diferencia de la base de datos y el escaneo.
Conclusión
La gestión de SBOM y CVE ya no es un "sería bueno tenerlo." El plazo del CRA de la UE en 2027, el mandato existente de la FDA, los requisitos prácticos de UN-R155 — la regulación se está cerrando.
La buena noticia: el cumplimiento con Yocto Scarthgap es más simple de lo que podrías pensar.
| Tarea | Método | Esfuerzo |
|---|---|---|
| Generación de SBOM | create-spdx (habilitado por defecto) | Casi cero |
| Escaneo de CVE | INHERIT += "cve-check" | Una línea en conf/local.conf |
| Filtrado de ruido | CVE_STATUS + razones documentadas | Esfuerzo de configuración inicial |
| Operaciones | Archivar SBOM + reporte CVE por compilación | Automatizar vía CI/CD |
Los SBOMs ya se generan por defecto. La verificación de CVE toma una línea para habilitar. El primer paso hacia el cumplimiento regulatorio es más fácil de lo que piensas.
Artículos relacionados:
- SWUpdate vs Mender vs RAUC: Comparativa OTA para Yocto
- Migración de Kirkstone a Scarthgap: La lista de verificación completa
- Errores de compilación en Yocto: Guía de depuración por tarea
- Primeros pasos con Yocto: Compila tu primera imagen Linux
- Cómo escribir recetas Yocto: Guía de archivos .bb
- Yocto bbappend: Guía práctica con 5 patrones
- Compilaciones Yocto 10x más rápidas