SBOM está en todas partes en las discusiones de Linux embebido. La nueva regulación de la UE exige la entrega de SBOM para 2027. La FDA ya lo requiere para dispositivos médicos.
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)
Entró en vigor en diciembre de 2024. Los requisitos completos aplican desde el 11 de diciembre de 2027. 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, el cumplimiento de UN-R155 es obligatorio para todos los nuevos tipos de vehículos desde julio de 2024.
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.
Generación de SBOMs con create-spdx
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.
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 (National Vulnerability Database) del NIST para detectar vulnerabilidades conocidas. 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 |
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.