View a markdown version of this page

Guía para desarrolladores de complementos - Amazon Inspector

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Guía para desarrolladores de complementos

Esta guía explica cómo ampliar Amazon Inspector SBOM Generator (inspector-sbomgen) con complementos de Lua personalizados. Los complementos le permiten añadir soporte para nuevos ecosistemas de paquetes sin modificar el código fuente de sbomgen ni tener que volver a compilarlo.

Para ver el catálogo completo de funciones, consulte la. Referencia de la API de complementos Para obtener orientación sobre la redacción de las pruebas, consulte laGuía de pruebas de complementos.

Descripción general de

Los complementos de Sbomgen están escritos en Lua y siguen un proceso de dos pasos:

  • Descubrimiento: escanea la lista de archivos del artefacto e informa qué archivos son relevantes para tu ecosistema.

  • Recopilación: analiza cada archivo descubierto e introduce los resultados del paquete en la SBOM.

Modelo de eventos del complemento

Los complementos de descubrimiento necesitan una forma de indicar a los complementos de la colección que los archivos que contienen metadatos del paquete se han descubierto en el artefacto que se encuentra en el inventario. Para facilitar este intercambio de datos, los complementos de detección definen un nombre de evento y devuelven una lista de las rutas de los archivos. Los complementos de recopilación se suscriben a ese evento y reciben todas las rutas de archivo coincidentes. Esto desvincula la detección de archivos del análisis: puede hacer que un complemento de descubrimiento alimente varios recopiladores (patrón de distribución en abanico). Sin embargo, cada complemento de descubrimiento debe tener un nombre de evento único y cada complemento de colección debe tener un nombre de recopilador único. Para obtener más información, consulte Reglas de colisión de complementos.

Los desarrolladores pueden reconocer esto como el patrón de diseño del observador.

Este diseño permite que un único complemento de descubrimiento desencadene múltiples análisis independientes de forma eficaz. Por ejemplo, un complemento de descubrimiento puede localizar todos los requirements.txt elementos de un artefacto y, a continuación, alimentar:

  • Un recopilador de paquetes que analiza cada línea para obtener los resultados de la SBOM (). name==version

  • Un recopilador de secretos que marca las líneas que contienen claves de API o tokens anclados accidentalmente como versiones.

  • Un recopilador de políticas que informa sobre los especificadores de versiones no anclados o con caracteres comodín.

Cada recopilador utiliza de forma independiente la misma lista de archivos sin tener que revisar el sistema de archivos del artefacto. Esto también permite a los autores de complementos añadir nuevos complementos de colección que se suscriban a los eventos existentes sin tener que cambiar el complemento de descubrimiento correspondiente.

Inicio rápido: creación de nuevos complementos

La forma más rápida de crear un nuevo complemento es mediante el comando scaffolding incorporado:

inspector-sbomgen plugin new

El comando solicita el nombre del plugin y el directorio del proyecto. Al pulsar Entrar, se acepta el valor predeterminado que se muestra entre paréntesis:

Plugin name (identifies the software ecosystem your plugin will inventory, e.g. debian-dpkg, rhel-rpm, python-pip, cmake) [my-custom-ecosystem]: cmake Project directory [my-sbomgen-plugins]:

También puede pasar los argumentos directamente:

inspector-sbomgen plugin new --name cmake --path /tmp/custom-plugins

Empezando con un ejemplo práctico

Si quieres experimentar con los complementos antes de escribir tu propia lógica, crea un nuevo complemento con la siguiente --with-example bandera:

inspector-sbomgen plugin new --with-example

Esto genera un proyecto de plugin completamente funcional con un ejemplo de analizador de archivos bloqueados, datos de prueba y pruebas de superación. El plugin de ejemplo descubre example.lock archivos, analiza name==version entradas y envía paquetes a la SBOM. Puedes ejecutar las pruebas inmediatamente para ver el sistema de complementos en acción y, a continuación, modificar el código para adaptarlo a tu ecosistema real.

Para un andamiaje avanzado que incluya todas las funciones de anulación opcionales (get_scanner_name,, get_event_nameget_scanner_groups, detección de eventos múltiples, etc.), usa la --with-overrides marca (hablaremos de esto más adelante):

inspector-sbomgen plugin new --with-overrides

Completando tu complemento

Tras el andamiaje, los archivos de complementos generados contienen TODO marcadores que indican dónde añadir la lógica específica del ecosistema. Revisa estos marcadores para convertir el andamio en un complemento funcional:

  • Sustituya todos los TODO marcadores por sus valores reales

  • Actualice el patrón del archivo discover() para que coincida con los archivos de destino

  • Implemente la lógica de análisis collect() y sbomgen.push_package() solicite cada paquete

Pruebe su complemento

Hay dos formas de probar tus complementos:

1. Arnés de pruebas integrado: se utiliza inspector-sbomgen plugin test para validar la lógica del plugin durante el desarrollo. Esto ejecuta tus archivos init_test.lua de prueba sin necesidad de escanear un artefacto real:

inspector-sbomgen plugin test --path ./my-plugins

Consulte Guía de pruebas de complementos para obtener más información sobre la escritura de archivos de prueba y el uso de la testing.* API.

2. End-to-endescanear: invoca tu complemento con los comandos estándar de sbomgen para comprobar que funciona con artefactos reales. Para este enfoque, debes proporcionar un artefacto que contenga los archivos a los que apunta tu complemento (por ejemplo, un directorio requirements.txt o equivalente) y la ruta al directorio de tu complemento:

inspector-sbomgen directory \ --path /path/to/test/dir \ --plugin-dir ./my-plugins \ --disable-native-scanners \ -o sbom.json

El --disable-native-scanners indicador garantiza que solo se ejecuten tus complementos de Lua, lo que facilita las pruebas sin la salida de los escáneres integrados (nativos).

Configuración del IDE

Sbomgen proporciona la finalización del código, la verificación de tipos y la documentación en línea para toda la sbomgen.* API de VS Code.

VS Code con Lua Language Server

Y ya está! El plugin new comando genera .vscode/settings.json y library/sbomgen.lua detecta automáticamente el servidor de idiomas de Lua. Obtendrá inmediatamente:

  • Completar el código para todas sbomgen.* las funciones

  • Consejos de parámetros con tipos

  • Pase el ratón sobre la documentación

  • Comprobación de tipos

Estructura del directorio de complementos

Los complementos de detección y recopilación de Sbomgen deben seguir la siguiente estructura de directorios:

{plugin-dir}/ ├── discovery/ │ └── {platform}/ │ └── {category}/ │ └── {ecosystem}/ │ └── init.lua # REQUIRED entrypoint └── collection/ └── {platform}/ └── {category}/ └── {ecosystem}/ └── init.lua # REQUIRED entrypoint

Estos nombres de directorio tienen un significado semántico: sbomgen los usa para obtener los metadatos predeterminados para su complemento, incluidos el nombre del escáner, el nombre del evento, los grupos de escáneres y el filtrado de la plataforma. Esto reduce la cantidad de texto repetitivo que, de otro modo, tendrían que escribir los desarrolladores. La elección de los valores correctos garantiza que su complemento se integre correctamente con el modelo de selección y ejecución de escáneres de sbomgen.

Las siguientes secciones exploran la estructura de directorios con mayor detalle y proporcionan orientación sobre el significado semántico y las convenciones.

Plataforma

El directorio de la plataforma controla los sistemas operativos en los que se ejecuta tu complemento.

Valor Cuándo se debe usar
cross-platform El complemento funciona en cualquier sistema operativo (la mayoría de los complementos)
linux Lógica de detección específica para Linux
windows Lógica de detección específica para Windows
macos Lógica de detección específica para macOS

Categoría

El directorio de categorías determina los grupos de escáneres predeterminados asignados al complemento, lo que controla si se ejecuta de forma predeterminada o si requiere una suscripción explícita. Vea cómo Selección de escáner los grupos afectan a la ejecución.

Valor Grupos predeterminados Cuándo se debe usar
proglang programming-language-packages, pkg-scanner Paquetes de lenguajes de programación (pip, npm, maven, etc.)
os os, pkg-scanner Administradores de paquetes de sistema operativo (dpkg, rpm, apk, etc.)
extra-ecosystems extra-ecosystems, pkg-scanner Aplicaciones y tiempos de ejecución (nginx, curl, wordpress, etc.)

Si utilizas un nombre de categoría que no coincide con ninguno de los anteriores, el nombre de la categoría en sí se utiliza como grupo.

Ecosistema

Un nombre para el ecosistema de paquetes específico (por ejemplopython-pip,,python-poetry,debian-dpkg,curl). Los nombres separados por guiones son una convención común, pero no un requisito estricto.

El nombre del escáner y el nombre del recopilador se derivan directamente del nombre del directorio del ecosistema.

Emparejo de nombres de eventos

Los complementos de detección y recopilación situados en la misma ruta de directorio se emparejan automáticamente. Por ejemplo, un complemento de descubrimiento discovery/cross-platform/proglang/python-pip/ se empareja automáticamente concollection/cross-platform/proglang/python-pip/.

Puedes anular esto definiendo get_event_name() y subscribe_to_event() en tus complementos.

Plugins de Discovery

Un complemento de descubrimiento solo requiere la discover() función. Todas las demás funciones son opcionales; los valores predeterminados se derivan de la ruta del directorio.

La mayoría de los complementos de descubrimiento funcionan localizando archivos cuyos nombres o rutas identifican un ecosistema específico, requirements.txt por ejemplo, para Python pip, package.json npm o Rust Cargo.lock cargo. Las sbomgen.find_files_by_* funciones realizan esta coincidencia fuera de la máquina virtual de Lua, lo que las hace mucho más rápidas que iterar la lista completa de archivos en Lua:

-- REQUIRED: Scans the artifact and returns a table of file paths. function discover() return sbomgen.find_files_by_name({"requirements.txt"}) end

discover()debe devolver una tabla (matriz) de cadenas de Lua. Si no se encuentra ningún archivo, devuelva una tabla vacía. {}

Patrones de descubrimiento comunes

Objetivo Función recomendada
Haga coincidir uno o más nombres de archivo exactos sbomgen.find_files_by_name({names})
Haga coincidir los nombres de los archivos sin distinguir entre mayúsculas y minúsculas sbomgen.find_files_by_name_icase({names})
Haga coincidir por sufijo de ruta (por ejemplo,) /pom.properties sbomgen.find_files_by_suffix({suffixes})
Haga coincidir por expresión regular de ruta completa sbomgen.find_files_by_path_regex({patterns})
Coincidencia de nombre base al estilo de Glob (por ejemplo,) *.lock sbomgen.glob_find_files(pattern)

Cuando tu lógica requiera un filtrado posterior (por ejemplo, conservar los archivos que coincidan con un sufijo pero excluyendo los directorios de compilación y salida), combina una llamada con un bucle de Lua: find_files_by_*

function discover() local found = {} for _, f in ipairs(sbomgen.find_files_by_suffix({".conda-meta.json"})) do if not f:match("[/\\]%.cache[/\\]") then table.insert(found, f) end end return found end

Evite sbomgen.get_file_list() el descubrimiento a menos que no haya otro método de comparación adecuado: copia todas las rutas a la máquina virtual de Lua y, si se trata de artefactos de gran tamaño, puede tardar varios segundos. Consulte el Referencia de la API de complementos para obtener más información.

Descubrimiento de eventos múltiples

De forma predeterminada, todos los archivos devueltos por discover() se publican en un único evento (desdeget_event_name()). Si el escáner necesita enrutar diferentes archivos a diferentes recopiladores, devuelva una tabla con claves:

function discover() return { EventNameFoundCurl = sbomgen.find_files_by_name({"curl", "curl.exe"}), EventNameFoundLibcurl = sbomgen.find_files_by_name({"curlver.h"}), } end

Cuando discover() devuelve una tabla con claves de cadena, cada clave se trata como un nombre de evento independiente y su valor (una tabla de rutas de archivos) se publica en ese evento. Los complementos de colección se suscriben a eventos específicos subscribe_to_event() como de costumbre.

Esto es compatible con versiones anteriores: la devolución de una tabla secuencial {"file1", "file2"} sigue funcionando como modo de evento único. La detección es automática: las tablas con cualquier clave de cadena son de eventos múltiples, las tablas con claves de números enteros (o vacías) son de eventos únicos.

Cuando se utilizan eventos múltiples, no get_event_name() se usa para publicar (los nombres de los eventos provienen de las claves de las tablas devueltas). Sin embargo, se sigue llamando durante la carga del complemento para detectar colisiones, por lo que debería devolver un valor único o omitirse para usar el valor predeterminado.

Funciones de detección opcionales

Todas ellas tienen valores predeterminados idénticos derivados de la ruta del directorio. Defínalos solo si necesita anular:

Función Predeterminado Anular cuando...
get_scanner_name() {ecosystem}(por ejemplo,python-pip) ¿Desea un nombre de escáner personalizado
get_scanner_description() "Lua discovery plugin: {ecosystem}" ¿Desea una descripción personalizada
get_scanner_groups() Derivado del directorio de categorías Necesita grupos no estándar
get_event_name() Derivado de la ruta del directorio Necesita un enrutamiento de eventos personalizado
get_localhost_scan_paths() Ninguno Tu complemento necesita que se escaneen rutas específicas durante los localhost escaneos

Rutas de escaneo de Localhost

Cuando sbomgen ejecuta un localhost escaneo, recorre los directorios especificados por el usuario además de las rutas predeterminadas declaradas por los escáneres. De forma predeterminada, los complementos de detección de Lua no aportan ninguna ruta, por lo que los archivos que no estén en los directorios especificados por el usuario no aparecerán en la lista de archivos.

Defina get_localhost_scan_paths() los directorios o rutas de archivos que el rastreador de localhost debe incluir:

function get_localhost_scan_paths() return { "/usr/bin", "/usr/local/bin", } end

Las rutas devueltas se añaden a la lista de escaneos del caminante solo durante los localhost escaneos; no tienen ningún efecto sobre container los escaneos. directory archive

Rutas de escaneo específicas de la plataforma

Cuando los archivos que le interesan se encuentren en diferentes ubicaciones en Windows, macOS y Linux, ramifique sbomgen.get_platform() y devuelva las rutas correspondientes al host:

function get_localhost_scan_paths() local platform = sbomgen.get_platform() if platform == sbomgen.platform.WINDOWS then local drive = sbomgen.get_system_drive() return { drive .. "/Program Files/MyApp/myapp.exe", drive .. "/Program Files (x86)/MyApp/myapp.exe", } end if platform == sbomgen.platform.DARWIN then return {"/Applications/MyApp.app/Contents/MacOS/myapp"} end -- Linux return { "/usr/bin/myapp", "/usr/local/bin/myapp", } end

En Windows, utilícelo sbomgen.get_system_drive() para resolver la letra de la unidad del sistema (por ejemplo,"C:") en lugar de codificarla de forma rígida. Para las rutas derivadas de variables de entorno como LOCALAPPDATA oPROGRAMFILES, repita sbomgen.get_env_vars() y busque el valor por clave. Consulte la Referencia de la API de complementos para obtener más información.

Plugins de colección

Un complemento de colección solo requiere la collect() función. Todas las demás funciones son opcionales.

collect(file_path)se invoca una vez por cada archivo descubierto por el complemento de detección emparejada. El patrón típico es:

  • Lea el contenido del archivo utilizando sbomgen.read_file() (para archivos pequeños cargados en la memoria) o sbomgen.open_file() (para archivos grandes, lea line-by-line).

  • Analice el contenido: haga coincidir cadenas para manifiestos simples, sbomgen.xml_decode() JSON, XML o sbomgen.search_binary() binarios compilados. sbomgen.json_decode()

  • Publica cada paquete descubierto llamando sbomgen.push_package() con los metadatos del paquete.

-- REQUIRED: Called once per discovered file. -- Parse the file and call sbomgen.push_package() for each package found. function collect(file_path) local content, err = sbomgen.read_file(file_path) if err or not content then return end for line in content:gmatch("[^\r\n]+") do local name, version = line:match("^([%w%-%_%.]+)==(.+)$") if name and version then sbomgen.push_package({ name = name, version = version, purl_type = "pypi", component_type = sbomgen.component_types.LIBRARY, }) end end end

collect()no devuelve ningún valor. Cada push_package() llamada requiere namepurl_type, ycomponent_type. Consulte todos Referencia de la API de complementos los campos admitidos.

Adjuntar metadatos a los componentes

Sbomgen admite dos formas de adjuntar metadatos a un componente del paquete: los calificadores de PURL y las propiedades de CyclonedX. Tienen diferentes propósitos, y la elección entre ellos tiene implicaciones en la forma en que Amazon Inspector identifica las vulnerabilidades en la SBOM resultante.

Mecanismo Dónde aparece Úselo para
qualifiers Dentro de la URL del paquete (por ejemplo,pkg:deb/debian/curl@7.88.1?arch=amd64) Datos que forman parte de la identidad del paquete
properties En la matriz de la SBOM components[].properties Metadatos descriptivos que no cambian la forma en que se identifica el paquete

Recomendación: prefiera las propiedades de CyclonedX (en su propio espacio de nombres) para los metadatos personalizados. Las propiedades no alteran la identidad de un componente, por lo que no pueden afectar a la identificación de vulnerabilidades de Amazon Inspector. Reserve los calificadores de PURL para los casos en que el tipo de PURL de su ecosistema los requiera.

Calificadores de PURL

Algunos calificadores de PURL tienen un significado semántico para Amazon Inspector e influyen en la identificación de vulnerabilidades. Por ejemplo, en deb los componentes, el Inspector utiliza calificadores, como arch y distro para seleccionar la fuente de vulnerabilidades correcta; en generic los componentes de los binarios compilados, calificadores, como go_toolchain o rust_toolchain identifica la cadena de herramientas utilizada. Establecer un calificador que el Inspector no reconoce u omitir uno que espera puede provocar que las vulnerabilidades se pasen por alto o se atribuyan erróneamente.

Consulte ¿Qué es la URL de un paquete? en la guía del usuario de Amazon Inspector para conocer las convenciones de calificación que el Inspector reconoce por tipo de PURL.

Establezca los calificadores mediante la tabla que aparece enqualifiers: sbomgen.push_package()

sbomgen.push_package({ name = "curl", version = "7.88.1", purl_type = "deb", namespace = "debian", component_type = sbomgen.component_types.LIBRARY, qualifiers = { arch = "amd64", distro = "debian-12", }, })

Establece los clasificatorios únicamente cuando se ajusten a las expectativas del Inspector para el tipo PURL. Si necesita registrar metadatos que no forman parte de la identidad del paquete, utilice en su lugar las propiedades de CyclonedX.

Propiedades de CyclonedX

Las propiedades CyclonedX son anotaciones clave-valor que aparecen en la matriz de la SBOM. components[].properties Describen un componente sin afectar a la forma en que se identifica, por lo que son la opción más segura para los metadatos definidos por un complemento.

Los amazon:inspector:* espacios de nombres están reservados para Amazon Inspector. En concreto:

  • amazon:inspector:sbom_generator:*— reservado para sbomgen y sus escáneres integrados.

  • amazon:inspector:sbom_scanner:*— reservado para la API de escaneo de Amazon Inspector.

Los autores de los complementos no deben emitir claves dentro de estos espacios de nombres reservados. Escribir en ellos puede interferir con el comportamiento del Inspector y puede sobrescribirse. Para ver la lista completa de claves reservadas, consulte Uso de espacios de nombres CyclonedX con Amazon Inspector.

Utilice su propio espacio de nombres (normalmente el identificador de su organización o complemento) al definir las propiedades:

sbomgen.push_package({ name = "requests", version = "2.28.1", purl_type = "pypi", component_type = sbomgen.component_types.LIBRARY, properties = { ["acme:python:manifest_path"] = file_path, ["acme:python:pinned"] = "true", ["acme:python:source"] = "requirements.txt", }, })

Reglas de nomenclatura clave

sbomgen procesa las claves de propiedad de la siguiente manera:

  • Una clave que contiene dos puntos se usa textualmente en la SBOM. Incluye siempre al menos dos puntos en las claves para controlar el espacio de nombres.

  • A una clave que no contenga dos puntos se le añade automáticamente el prefijo, colocándola dentro del espacio de nombres reservado del Inspector. amazon:inspector:sbom_generator: Evite esta forma para las propiedades personalizadas.

properties = { ["acme:my_plugin:detected_via"] = "lockfile", -- used as-is (recommended) detected_via = "lockfile", -- becomes "amazon:inspector:sbom_generator:detected_via" (avoid) }

Las sbomgen.properties.* constantes existen para que los escáneres oficiales emitan claves consistentes dentro del espacio de nombres reservado. No son puntos de extensión para complementos personalizados; en su lugar, usa tu propio espacio de nombres.

Propiedades y calificadores de los componentes secundarios

Los componentes independientes children están anidados. Cada elemento secundario tiene sus propias qualifiers tablas properties y los metadatos establecidos en el elemento principal no se propagan a los elementos secundarios. Establezca valores de forma explícita para cada niño que los necesite.

Funciones de recopilación opcionales

Función Predeterminado Anular cuando...
get_collector_name() {ecosystem}(por ejemplo,python-pip) ¿Quieres un nombre de coleccionista personalizado
get_collector_description() empty string ¿Quieres una descripción
subscribe_to_event() Derivado de la ruta del directorio Necesita un enrutamiento de eventos personalizado

Ejecutando tus complementos

Para que los complementos generen metadatos de paquetes, sbomgen debe tener un artefacto para escanearlo que contenga los archivos a los que apunta su complemento (por ejemplo, un directorio con requirements.txt archivos de manifiesto de paquetes o archivos de manifiesto equivalentes). package.json

Uso básico

inspector-sbomgen <artifact type> <arguments> --plugin-dir /path/to/plugins

Ejemplo:

inspector-sbomgen directory --path /target -o /tmp/sbom.json --plugin-dir /path/to/plugins

Con los escáneres nativos desactivados (modo solo para LUA)

inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --disable-native-scanners -o sbom.json

Con registro detallado

inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --verbose -o sbom.json

Listado de escáneres disponibles

Úselo list-scanners para ver todos los escáneres disponibles para sbomgen. Esto incluye los escáneres nativos integrados, cualquier complemento oficial de Lua incluido en sbomgen y cualquier complemento de Lua personalizado que hayas suministrado a través de: --plugin-dir

inspector-sbomgen list-scanners --plugin-dir /path/to/plugins
┌─────────────────────┬────────┬───────────────────────────────┬─────────────────────────────┐ │ SCANNER NAME │ SOURCE │ GROUPS │ DESCRIPTION │ ├─────────────────────┼────────┼───────────────────────────────┼─────────────────────────────┤ │ curl │ custom │ extra-ecosystems │ Discovers curl version │ │ │ │ pkg-scanner │ header files (curlver.h) │ ├─────────────────────┼────────┼───────────────────────────────┼─────────────────────────────┤ │ python-requirements │ custom │ pkg-scanner │ Discovers requirements*.txt │ │ │ │ programming-language-packages │ files for Python pip │ │ │ │ │ packages │ └─────────────────────┴────────┴───────────────────────────────┴─────────────────────────────┘

La columna SOURCE muestra de dónde proviene cada escáner:

Origen Significado
native Escáner incorporado incluido con sbomgen
official Plugins Lua incluidos con sbomgen
custom El complemento de Lua proporcionado por el usuario se carga mediante --plugin-dir

Si se ejecuta list-scanners sin --plugin-dir él, se incluyen ambos native y official escáneres, que están siempre disponibles. La --plugin-dir marca añade sus custom escáneres a la lista.

Para mostrar solo los escáneres Lua sin escáneres nativos:

inspector-sbomgen list-scanners --plugin-dir /path/to/plugins --disable-native-scanners

Selección de escáner

Los complementos de Lua Discovery participan en el mismo modelo de selección de escáneres que los escáneres nativos integrados. De forma predeterminada, sbomgen ejecuta todos los escáneres cuyos grupos coinciden con los grupos de escáneres predeterminados para el tipo de artefacto. Puede anular esto con tres indicadores:

Ejecute solo escáneres específicos

Úselo --scanners para ejecutar solo los escáneres nombrados. Se excluyen todos los demás escáneres:

inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --scanners python-requirements \ -o sbom.json

Esto solo ejecuta el python-requirements escáner. Puede pasar varios nombres de escáneres separados por comas o pasar el nombre de un grupo de escáneres (por ejemploprogramming-language-packages) para activar todos los escáneres que pertenezcan a ese grupo.

Excluya escáneres específicos

Se utiliza --skip-scanners para excluir los escáneres con nombre asignado mientras se ejecuta todo lo demás:

inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --skip-scanners python-poetry \ -o sbom.json

Esto ejecuta todos los escáneres predeterminados exceptopython-poetry. Por ejemplo--scanners, este indicador también acepta nombres de grupos, por lo que al pasarlos --skip-scanners programming-language-packages se deshabilitan todos los escáneres de ese grupo.

nota

--scannersy --skip-scanners se excluyen mutuamente. Pasar ambos produce un error.

Agregue escáneres de grupos no predeterminados

El conjunto de escáneres predeterminado depende del tipo de artefacto que se esté escaneando (consulte la matriz que aparece a continuación). Cómo afectan los grupos a la selección Un escáner cuyos grupos no formen parte del conjunto predeterminado para el tipo de artefacto no se ejecutará a menos que lo active. --additional-scannersUtilícelo para añadir escáneres al conjunto predeterminado sin reemplazarlo:

inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --additional-scanners my-extra-scanner \ -o sbom.json

Esto ejecuta todos los escáneres predeterminados para el tipo de artefacto, además. my-extra-scanner El indicador acepta una lista separada por comas de nombres de escáneres o grupos, y se apila con el conjunto predeterminado en lugar de reemplazarlo. Se utiliza list-scanners para comprobar a qué grupos pertenece un escáner.

Cómo afectan los grupos a la selección

La get_scanner_groups() función del complemento de detección determina a qué grupos pertenece el escáner. El funcionamiento predeterminado de un escáner depende tanto de sus grupos como del tipo de artefacto que se esté escaneando. La siguiente matriz muestra los grupos que se incluyen en el conjunto de escáneres predeterminado para cada tipo de artefacto:

Group (Grupo) directory / archive container localhost volume binary
os
programming-language-packages
binary
extra-ecosystems
dockerfile
custom
certificate
machine-learning
pkg-scanner

A ✓ significa que todos los escáneres de ese grupo se ejecutan de forma predeterminada para ese tipo de artefacto. A significa que el grupo no está en el conjunto predeterminado, por lo que sus escáneres solo se ejecutan si se seleccionan explícitamente mediante --scanners o. --additional-scanners

Detalles destacables:

  • customsiempre está en el conjunto predeterminado: los complementos personalizados que se cargan reciben --plugin-dir automáticamente el custom grupo, por lo que se ejecutan de forma predeterminada independientemente del tipo de artefacto.

  • extra-ecosystemsestá predeterminado para containerlocalhost, y volume escanea, pero no para directoryarchive, o binary escanea. En el caso de esos tipos, hay que pasar por alto --additional-scanners (por nombre o por extra-ecosystems grupo) para incluirlos.

  • pkg-scanneres informativo: marca un escáner como recopilador de paquetes para mostrarlos en éllist-scanners, pero no hace que el escáner funcione por sí solo. Combínelo con un grupo de ejecución (por ejemplo,programming-language-packages) enget_scanner_groups().

Por ejemplo, un complemento que {sbomgen.groups.EXTRA_ECOSYSTEMS, sbomgen.groups.PACKAGE_COLLECTOR} se devuelva se ejecutará de forma predeterminada en los escaneos de contenedores, hosts locales y volúmenes, pero será necesario --additional-scanners (o--scanners) en los escaneos de directorios, archivos y binarios.

Reglas de colisión de complementos

Sbomgen aplica metadatos únicos en todos los complementos cargados para evitar la sobrescritura silenciosa y garantizar la integridad del SBOM. Cuando se detecta una colisión, se omite el último complemento y se registra una advertencia.

¿Qué está marcado

Metadatos Alcance En caso de colisión
Nombre del evento de descubrimiento (get_event_name) Todos los complementos de descubrimiento Se omitió el segundo complemento
Nombre del escáner () get_scanner_name Todos los complementos de descubrimiento Se omitió el segundo complemento
Nombre del recopilador () get_collector_name Todos los complementos de la colección Se omitió el segundo complemento

¿Qué está permitido

Se pueden suscribir varios complementos de colección al mismo evento a través desubscribe_to_event(). Este es el patrón de distribución previsto: un plugin de descubrimiento puede alimentar a varios recopiladores, cada uno de los cuales realiza tareas diferentes (por ejemplo, uno extrae paquetes y otro detecta secretos).

Evitar colisiones

Si dos complementos utilizan el mismo nombre de escáner, nombre de evento o nombre de recopilador, se omite el segundo que se haya cargado. Para resolver las colisiones, cambie el nombre de los metadatos en conflicto definiendo la función de anulación adecuada en su complemento (get_scanner_name(),, o). get_event_name() get_collector_name()

Ejemplo de advertencia de colisión

[custom:python-pip] SKIPPED: discovery event name "EventNameFoundPythonRequirements" is already registered by [official:python-pip]. Each discovery plugin must have a unique event name. Rename get_event_name() in your plugin to use a unique name.

La advertencia indica qué complemento se omitió, qué colisionó, qué complemento ya tiene ese nombre y qué función cambiar.

Debugging

Registro de la consola

Los complementos pueden emitir mensajes a la salida de la consola de sbomgen mediante las siguientes funciones:

Función Nivel ¿Visible por defecto?
sbomgen.log_debug(message) DEBUG No, requiere --verbose
sbomgen.log_info(message) INFO
sbomgen.log_warn(message) WARN
sbomgen.log_error(message) ERROR

Todas las salidas de registro de un complemento llevan automáticamente el prefijo de la fuente y la ruta del complemento (por ejemplo,[custom:python-pip]), por lo que los mensajes de los distintos complementos son fáciles de distinguir. log_infolog_warn, y log_error siempre se imprime; log_debug solo se imprime cuando se invoca sbomgen con. --verbose

function discover() sbomgen.log_info("starting discovery") local files = sbomgen.find_files_by_name({"requirements.txt"}) sbomgen.log_debug(string.format("matched %d files", #files)) if #files == 0 then sbomgen.log_warn("no requirements.txt files found") end return files end

Puntos de interrupción

Se usa sbomgen.breakpoint() para pausar la ejecución del complemento y bloquearlo hasta que presione Entrar. Funciona como un depurador simple: combínalo con sentencias de registro para inspeccionar el estado en puntos específicos.

function discover() local files = sbomgen.find_files_by_name({"requirements.txt"}) sbomgen.log_info(string.format("about to inspect %d files", #files)) sbomgen.breakpoint("before file inspection — press Enter to continue") local found = {} for _, f in ipairs(files) do if not f:match("[/\\]tests[/\\]") then table.insert(found, f) end end sbomgen.log_info(string.format("kept %d files after filtering", #found)) sbomgen.breakpoint("after filtering — press Enter to continue") return found end

El mensaje de punto de interrupción se imprime en stderr. La ejecución se detiene hasta que pulse Entrar, lo que le da tiempo para revisar el resultado del registro.

Problemas comunes

Síntoma Causa Corregir
El complemento no está cargado Falta init.lua Asegúrese de que el punto de entrada esté en la profundidad de directorio correcta
«falta la función requerida» Error tipográfico en el nombre de la función Compruebe queget_scanner_name,get_scanner_description,get_scanner_groups,discover,get_event_name,get_localhost_scan_paths, get_collector_namecollect, subscribe_to_event estén definidas
El complemento de colección nunca se llamó El nombre del evento no coincide Verifica get_event_name() y subscribe_to_event() devuelve la misma cadena
No hay paquetes en la SBOM push_packageno se ha llamado o faltan campos obligatorios Asegúrese name de que component_type estén configurados en todas las push_package llamadas (incluidas las de los niños). purl_type Usa sbomgen.component_types.* constantes.
Error de tiempo de ejecución en el complemento Error de Lua durante la ejecución Compruebe la salida de sbomgen para ver si hay mensajes de advertencia con los detalles del error
«OMITIDO: el nombre del evento de descubrimiento... ya está registrado» Otro complemento usa el mismo nombre de evento Cambie el nombre get_event_name() a un valor único
«OMITIDO: el nombre del escáner... ya está registrado» Otro complemento usa el mismo nombre de escáner Cambie el nombre get_scanner_name() a un valor único
«OMITIDO: el nombre del recopilador... ya está registrado» Otro complemento usa el mismo nombre de recopilador Cambie el nombre get_collector_name() a un valor único

referencia de la API

El catálogo completo de funciones se incluye en un documento complementario:

Referencia de la API de complementos

La referencia de la API abarca todas las sbomgen.* funciones (E/S de archivos, utilidades binarias, salida de paquetes, expresiones regulares, análisis estructurado, registro de Windows, registro, depuración), la testing.* API disponible en los archivos de prueba, todas las constantes integradas (,, properties groupscomponent_types,platform) y el ciclo de vida global de los complementos.

Gestión de errores

Las funciones de la API que pueden fallar devuelven dos valores:. value, err En caso de éxito, err esnil. En caso de error, el primer valor es nil y err es una cadena de error.

local content, err = sbomgen.read_file(path) if err then sbomgen.log_error("failed to read " .. path .. ": " .. err) return end -- content is safe to use here

Si un complemento genera un error de Lua no controlado, sbomgen registra una advertencia y continúa con el siguiente archivo o complemento. Los demás complementos no se ven afectados.

Restricciones de Sandbox

Los complementos se ejecutan en una máquina virtual Lua aislada con acceso limitado a la biblioteca estándar:

Library Disponible Notas
base dofile,loadfile, se eliminan loadstring
string Manipulación completa de cadenas
table Manipulación completa de la tabla
math Biblioteca matemática completa
package require()restringido al directorio de complementos
io Utilice sbomgen.* I/O funciones en su lugar
os Bloqueado por motivos de seguridad
debug Bloqueado para evitar la introspección de las máquinas virtuales
coroutine ¿No está cargado

El acceso directo al sistema de archivos mediante io.open o no os.execute está disponible. Todas las operaciones con los archivos deben pasar por la sbomgen API, lo que garantiza un comportamiento coherente en todos los tipos de artefactos e impide que los complementos accedan a archivos ajenos al artefacto.

require()solo puede cargar módulos desde el árbol de directorios del plugin. El recorrido entre el directorio principal, por ejemplo, está bloqueado. require("../shared")

Compartir código entre complementos

Puedes usarlo require() para cargar módulos auxiliares desde el directorio de tu complemento:

my-ecosystem/ ├── init.lua └── helpers.lua
-- helpers.lua local M = {} function M.parse_version(s) return string.match(s, "(%d+%.%d+%.%d+)") end return M
-- init.lua local helpers = require("helpers") function subscribe_to_event() return "MyEvent" end function collect(file_path) local content, err = sbomgen.read_file(file_path) if err then return end local version = helpers.parse_version(content) -- ... end

También se admiten subdirectorios coninit.lua:

my-ecosystem/ ├── init.lua └── parsers/ └── init.lua
local parsers = require("parsers")

require()está restringido al directorio de tu plugin. No puedes cargar módulos desde otros complementos o rutas del sistema. No se admiten bibliotecas Lua de terceros (p. ej., de LuaRocks); solo se pueden cargar los módulos auxiliares locales del directorio de complementos.