As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Guia do desenvolvedor de plug-ins
Este guia explica como estender o Amazon Inspector SBOM Generator (inspector-sbomgen) com plug-ins Lua personalizados. Os plug-ins permitem que você adicione suporte para novos ecossistemas de pacotes sem modificar o código-fonte do sbomgen ou ter que recompilar.
Para obter o catálogo completo de funções, consulte Referência da API de plug-in o. Para obter orientação sobre como escrever testes, consulte Guia de teste de plug-ins o.
Visão geral do
Os plug-ins Sbomgen são escritos em Lua e seguem um pipeline de duas etapas:
-
Descoberta — escaneie a lista de arquivos do artefato e relate quais arquivos são relevantes para o seu ecossistema.
-
Coleção — analise cada arquivo descoberto e envie as descobertas do pacote para o SBOM.
Modelo de evento de plug-in
Os plug-ins do Discovery precisam de uma forma de informar aos plug-ins de coleção que os arquivos contendo metadados do pacote foram descobertos no artefato em inventário. Para facilitar esse compartilhamento de dados, os plug-ins de descoberta definem um nome de evento e retornam uma lista de caminhos de arquivo. Os plug-ins de coleção se inscrevem nesse evento e recebem cada caminho de arquivo correspondente. Isso dissocia a detecção de arquivos da análise — você pode fazer com que um plug-in de descoberta alimente vários coletores (padrão de distribuição). No entanto, cada plug-in de descoberta deve ter um nome de evento exclusivo e cada plug-in de coleção deve ter um nome de coletor exclusivo. Para mais detalhes, consulte Regras de colisão de plug-ins.
Os desenvolvedores podem reconhecer isso como o padrão de design do observador.
Esse design permite que um único plug-in de descoberta acione várias análises independentes de maneira eficiente. Por exemplo, um plug-in de descoberta pode localizar tudo requirements.txt em um artefato e, em seguida, alimentar:
-
Um coletor de pacotes que analisa cada linha nas descobertas do SBOM ().
name==version -
Um coletor de segredos que sinaliza linhas contendo chaves de API ou tokens fixados acidentalmente como versões.
-
Um coletor de políticas que relata especificadores de versão não fixados ou com caracteres curinga.
Cada coletor é executado de forma independente na mesma lista de arquivos sem precisar alterar o sistema de arquivos do artefato. Isso também permite que os autores de plug-ins adicionem novos plug-ins de coleção que se inscrevem em eventos existentes sem precisar alterar o plug-in de descoberta correspondente.
Início rápido: criação de novos plug-ins
A maneira mais rápida de criar um novo plug-in é usando o comando scaffolding embutido:
inspector-sbomgen plugin new
O comando solicita o nome do plug-in e o diretório do projeto. Pressionar Enter aceita o padrão mostrado entre colchetes:
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]:
Você também pode passar argumentos diretamente:
inspector-sbomgen plugin new --name cmake --path /tmp/custom-plugins
Começando com um exemplo prático
Se você quiser experimentar plug-ins antes de escrever sua própria lógica, crie um novo plug-in usando a --with-example bandeira:
inspector-sbomgen plugin new --with-example
Isso gera um projeto de plug-in totalmente funcional com um exemplo de analisador de arquivo de bloqueio, dados de teste e testes de aprovação. O plug-in de exemplo descobre example.lock arquivos, analisa name==version entradas e envia pacotes para o SBOM. Você pode executar os testes imediatamente para ver o sistema de plug-ins em ação e, em seguida, modificar o código para atingir seu ecossistema real.
Para andaimes avançados que incluem todas as funções de substituição opcionais (get_scanner_name,, get_event_nameget_scanner_groups, descoberta de vários eventos etc.), use a --with-overrides bandeira (falaremos mais sobre isso posteriormente):
inspector-sbomgen plugin new --with-overrides
Completando seu plug-in
Depois da montagem, os arquivos de plug-in gerados contêm TODO marcadores indicando onde adicionar sua lógica específica do ecossistema. Use esses marcadores para transformar o andaime em um plug-in funcional:
-
Substitua todos
TODOos marcadores por seus valores reais -
Atualize o padrão de arquivo
discover()para corresponder aos seus arquivos de destino -
Implemente a lógica de análise
collect()e chamesbomgen.push_package()cada pacote
Teste seu plug-in
Há duas maneiras de testar seus plug-ins:
1. Equipamento de teste integrado — Use inspector-sbomgen plugin test para validar a lógica do plug-in durante o desenvolvimento. Isso executa seus arquivos init_test.lua de teste sem precisar de um artefato real para digitalizar:
inspector-sbomgen plugin test --path ./my-plugins
Consulte o Guia de teste de plug-ins para obter detalhes sobre como escrever arquivos de teste e usar a testing.* API.
2. End-to-endscan — Invoque seu plug-in usando comandos sbomgen padrão para verificar se ele funciona com artefatos reais. Para essa abordagem, você precisa fornecer um artefato contendo os arquivos de destino do plug-in (por exemplo, um diretório com requirements.txt ou equivalente) e o caminho para o diretório do plug-in:
inspector-sbomgen directory \ --path /path/to/test/dir \ --plugin-dir ./my-plugins \ --disable-native-scanners \ -o sbom.json
O --disable-native-scanners sinalizador garante que somente seus plug-ins Lua sejam executados, facilitando o teste sem a saída dos scanners integrados (nativos).
Configuração do IDE
O Sbomgen fornece preenchimento de código, verificação de tipos e documentação embutida para toda a sbomgen.* API no VS Code.
Código VS com servidor de linguagem Lua
-
Instale a extensão Lua: sumneko.lua
-
Abra qualquer
.luaarquivo no seu projeto de plug-in
Isso é tudo! O plugin new comando é library/sbomgen.lua gerado .vscode/settings.json e detectado automaticamente pelo Lua Language Server. Você receberá imediatamente:
-
Preenchimento de código para todas as
sbomgen.*funções -
Dicas de parâmetros com tipos
-
Documentação do mouse
-
Verificação de tipo
Estrutura do diretório de plug-ins
Os plug-ins de descoberta e coleta do Sbomgen devem seguir a seguinte estrutura de diretórios:
{plugin-dir}/ ├── discovery/ │ └── {platform}/ │ └── {category}/ │ └── {ecosystem}/ │ └── init.lua # REQUIRED entrypoint └── collection/ └── {platform}/ └── {category}/ └── {ecosystem}/ └── init.lua # REQUIRED entrypoint
Esses nomes de diretório têm significado semântico — sbomgen os usa para derivar metadados padrão para seu plug-in, incluindo o nome do scanner, o nome do evento, os grupos de scanners e a filtragem da plataforma. Isso reduz a quantidade de textos padronizados que os desenvolvedores teriam que escrever de outra forma. A escolha dos valores corretos garante que seu plug-in se integre adequadamente ao modelo de seleção e execução do scanner sbomgen.
As seções abaixo exploram a estrutura de diretórios com mais detalhes, fornecendo orientação sobre o significado semântico e as convenções.
Plataforma
O diretório da plataforma controla em quais sistemas operacionais seu plug-in é executado.
| Valor | Quando usar |
|---|---|
cross-platform |
O plug-in funciona em qualquer sistema operacional (a maioria dos plug-ins) |
linux |
Lógica de detecção específica para Linux |
windows |
Lógica de detecção específica para Windows |
macos |
Lógica de detecção específica para macOS |
Categoria
O diretório de categorias determina os grupos de scanners padrão atribuídos ao seu plug-in, que controla se ele é executado por padrão ou se requer aceitação explícita. Veja como Seleção do scanner os grupos afetam a execução.
| Valor | Grupos padrão | Quando usar |
|---|---|---|
proglang |
programming-language-packages, pkg-scanner |
Pacotes de linguagens de programação (pip, npm, maven, etc.) |
os |
os, pkg-scanner |
Gerenciadores de pacotes do sistema operacional (dpkg, rpm, apk etc.) |
extra-ecosystems |
extra-ecosystems, pkg-scanner |
Aplicativos e tempos de execução (nginx, curl, wordpress etc.) |
Se você usar um nome de categoria que não corresponda a nenhum dos itens acima, o nome da categoria em si será usado como grupo.
Ecossistema
Um nome para o ecossistema de pacotes específico (por exemplopython-pip,,python-poetry,debian-dpkg,curl). Nomes com hífen são uma convenção comum, mas não um requisito estrito.
O nome do scanner e o nome do coletor são derivados diretamente do nome do diretório do ecossistema.
Combinação de nomes de eventos
Os plug-ins de descoberta e coleta no mesmo caminho de diretório são automaticamente emparelhados. Por exemplo, um plug-in de descoberta é emparelhado discovery/cross-platform/proglang/python-pip/ automaticamente com collection/cross-platform/proglang/python-pip/ o.
Você pode substituir isso definindo get_event_name() e subscribe_to_event() em seus plug-ins.
Plugins de descoberta
Um plug-in de descoberta requer apenas a discover() função. Todas as outras funções são opcionais — os padrões são derivados do caminho do diretório.
A maioria dos plug-ins de descoberta funciona localizando arquivos cujos nomes ou caminhos identificam um ecossistema específico — por exemplo, requirements.txt para Python pippackage.json, para npm ou para Rust cargo. Cargo.lock As sbomgen.find_files_by_* funções realizam essa correspondência fora da VM Lua, o que as torna significativamente mais rápidas do que a iteração da lista completa de arquivos em Lua:
-- REQUIRED: Scans the artifact and returns a table of file paths. function discover() return sbomgen.find_files_by_name({"requirements.txt"}) end
discover()deve retornar uma tabela Lua (matriz) de strings. Se nenhum arquivo for encontrado, retorne uma tabela vazia{}.
Padrões de descoberta comuns
| Objetivo | Função recomendada |
|---|---|
| Combine um ou mais nomes de arquivo exatos | sbomgen.find_files_by_name({names}) |
| Combine nomes de arquivos sem distinção entre maiúsculas e minúsculas | sbomgen.find_files_by_name_icase({names}) |
Correspondência por sufixo de caminho (por exemplo,/pom.properties) |
sbomgen.find_files_by_suffix({suffixes}) |
| Combine por regex de caminho completo | sbomgen.find_files_by_path_regex({patterns}) |
Correspondência de nome de base no estilo Glob (por exemplo,) *.lock |
sbomgen.glob_find_files(pattern) |
Quando sua lógica exige pós-filtragem — por exemplo, manter arquivos com um sufixo, mas excluir diretórios de compilação e saída — combine uma chamada com um loop 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() a descoberta, a menos que nenhum outro combinador se encaixe — ele copia todos os caminhos para a Lua VM e pode levar vários segundos em artefatos grandes. Consulte o Referência da API de plug-in para obter detalhes.
Descoberta de vários eventos
Por padrão, todos os arquivos discover() retornados por são publicados em um único evento (deget_event_name()). Se o scanner precisar rotear arquivos diferentes para coletores diferentes, retorne uma tabela com chave em vez disso:
function discover() return { EventNameFoundCurl = sbomgen.find_files_by_name({"curl", "curl.exe"}), EventNameFoundLibcurl = sbomgen.find_files_by_name({"curlver.h"}), } end
Quando discover() retorna uma tabela com chaves de string, cada chave é tratada como um nome de evento separado e seu valor (uma tabela de caminhos de arquivo) é publicado nesse evento. Os plug-ins de coleção se inscrevem em subscribe_to_event() eventos específicos normalmente.
Isso é compatível com versões anteriores — retornar uma tabela sequencial {"file1", "file2"} ainda funciona como modo de evento único. A detecção é automática: tabelas com qualquer chave de string são multieventos, tabelas com apenas chaves inteiras (ou vazias) são eventos únicos.
Ao usar vários eventos, não get_event_name() é usado para publicação (os nomes dos eventos vêm das chaves da tabela retornadas). No entanto, ele ainda é chamado durante o carregamento do plug-in para detecção de colisão, portanto, ele deve retornar um valor exclusivo ou ser omitido para usar o padrão.
Funções de descoberta opcionais
Todos eles têm padrões sensatos derivados do caminho do diretório. Defina-os somente se você precisar substituí-los:
| Função | Padrão | Substituir quando... |
|---|---|---|
get_scanner_name() |
{ecosystem}(por exemplo,python-pip) |
Você quer um nome de scanner personalizado |
get_scanner_description() |
"Lua discovery plugin: {ecosystem}" |
Você quer uma descrição personalizada |
get_scanner_groups() |
Derivado do diretório de categorias | Você precisa de grupos não padrão |
get_event_name() |
Derivado do caminho do diretório | Você precisa de um roteamento de eventos personalizado |
get_localhost_scan_paths() |
Nenhum | Seu plug-in precisa de caminhos específicos escaneados durante localhost as varreduras |
Caminhos de escaneamento do localhost
Quando o sbomgen executa uma localhost varredura, ele percorre os diretórios especificados pelo usuário, além de quaisquer caminhos padrão declarados pelos scanners. Por padrão, os plug-ins de descoberta do Lua não contribuem com nenhum caminho, portanto, arquivos fora dos diretórios especificados pelo usuário não aparecerão na lista de arquivos.
get_localhost_scan_paths()Defina para retornar diretórios ou caminhos de arquivo que o localhost walker deve incluir:
function get_localhost_scan_paths() return { "/usr/bin", "/usr/local/bin", } end
Os caminhos retornados são anexados à lista de escaneamento do andador somente durante localhost os escaneamentos — eles não têm efeito sobre container os escaneamentos. directory archive
Caminhos de escaneamento específicos da plataforma
Quando os arquivos que você gosta estão em locais diferentes no Windows, macOS e Linux, ramifique sbomgen.get_platform() e retorne os caminhos apropriados para o 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
No Windows, use sbomgen.get_system_drive() para resolver a letra da unidade do sistema (por exemplo,"C:") em vez de codificá-la. Para caminhos derivados de variáveis de ambiente, como LOCALAPPDATA ouPROGRAMFILES, itere sbomgen.get_env_vars() e pesquise o valor por chave. Consulte o Referência da API de plug-in para obter detalhes.
Plugins de coleção
Um plug-in de coleção requer apenas a collect() função. Todas as outras funções são opcionais.
collect(file_path)é chamado uma vez por arquivo descoberto pelo plug-in de descoberta emparelhado. O padrão típico é:
-
Leia o conteúdo do arquivo usando
sbomgen.read_file()(para arquivos pequenos carregados na memória) ousbomgen.open_file()(para leitura de arquivos grandes line-by-line). -
Analise o conteúdo — correspondência de strings para manifestos simples,
sbomgen.json_decode()para JSON, para XML ousbomgen.xml_decode()sbomgen.search_binary()para binários compilados. -
Publique cada pacote descoberto chamando
sbomgen.push_package()com os metadados do pacote.
-- 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()não retorna um valor. Cada push_package() chamada requer namepurl_type, component_type e. Consulte o Referência da API de plug-in para ver todos os campos compatíveis.
Anexando metadados aos componentes
O Sbomgen suporta duas maneiras de anexar metadados a um componente do pacote: qualificadores PURL e propriedades do CycloneDX. Eles servem a propósitos diferentes, e a escolha entre eles tem implicações na forma como o Amazon Inspector identifica vulnerabilidades no SBOM resultante.
| Mecanismo | Onde aparece | Use para |
|---|---|---|
qualifiers |
Dentro da URL do pacote (por exemplo,pkg:deb/debian/curl@7.88.1?arch=amd64) |
Dados que fazem parte da identidade do pacote |
properties |
Na matriz do SBOM components[].properties |
Metadados descritivos que não alteram a forma como o pacote é identificado |
Recomendação: prefira as propriedades do CycloneDX (em seu próprio namespace) para metadados personalizados. As propriedades não alteram a identidade de um componente, portanto, não podem afetar a identificação da vulnerabilidade do Amazon Inspector. Reserve qualificadores de PURL para casos em que o tipo de PURL do seu ecossistema os exija.
qualificadores PURL
Alguns qualificadores de PURL têm significado semântico para o Amazon Inspector e influenciam a identificação de vulnerabilidades. Por exemplo, em deb componentes, o Inspector usa qualificadores como arch e distro para selecionar o feed de vulnerabilidade correto; em generic componentes para binários compilados, qualificadores como go_toolchain ou rust_toolchain identificam a cadeia de ferramentas usada. Definir um qualificador que o Inspector não reconhece, ou omitir um que ele espera, pode fazer com que as vulnerabilidades sejam perdidas ou atribuídas incorretamente.
Consulte O que é um URL de pacote? no guia do usuário do Amazon Inspector para as convenções de qualificadores que o Inspector reconhece por tipo de PURL.
Defina as eliminatórias por meio da qualifiers tabela emsbomgen.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", }, })
Defina qualificadores somente quando eles se alinharem às expectativas do Inspetor em relação ao tipo de PURL. Se você precisar registrar metadados que não façam parte da identidade do pacote, use as propriedades do CycloneDX.
Propriedades do CycloneDX
As propriedades CyclonedX são anotações de valores-chave que aparecem na matriz do SBOM. components[].properties Eles descrevem um componente sem afetar a forma como ele é identificado, portanto, são a escolha segura para metadados definidos por plug-ins.
Os amazon:inspector:* namespaces são reservados para o Amazon Inspector. Especificamente:
-
amazon:inspector:sbom_generator:*— reservado para o sbomgen e seus scanners integrados. -
amazon:inspector:sbom_scanner:*— reservado para a API Amazon Inspector Scan.
Os autores de plug-ins não devem emitir chaves dentro desses namespaces reservados. Escrever neles pode interferir no comportamento do Inspetor e pode ser sobrescrito. Para obter a lista completa de chaves reservadas, consulte Usando namespaces CycloneDX com o Amazon Inspector.
Use seu próprio namespace (normalmente seu identificador de organização ou plug-in) ao definir propriedades:
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", }, })
Principais regras de nomenclatura
As chaves de propriedade são processadas pelo sbomgen da seguinte forma:
-
Uma chave que contém dois pontos é usada literalmente no SBOM. Sempre inclua pelo menos dois pontos em suas chaves para controlar o namespace.
-
Uma chave que não contém dois pontos é automaticamente prefixada com
amazon:inspector:sbom_generator:— colocando-a dentro do namespace reservado do Inspector. Evite essa forma para propriedades personalizadas.
properties = { ["acme:my_plugin:detected_via"] = "lockfile", -- used as-is (recommended) detected_via = "lockfile", -- becomes "amazon:inspector:sbom_generator:detected_via" (avoid) }
As sbomgen.properties.* constantes existem para que os scanners oficiais emitam chaves consistentes dentro do namespace reservado. Eles não são pontos de extensão para plug-ins personalizados. Em vez disso, use seu próprio namespace.
Propriedades e qualificadores em componentes secundários
Os componentes aninhados children são independentes. Cada filho tem suas próprias qualifiers tabelas; properties os metadados definidos no pai não se propagam para os filhos. Defina valores explicitamente para cada criança que precisa deles.
Funções de coleta opcionais
| Função | Padrão | Substituir quando... |
|---|---|---|
get_collector_name() |
{ecosystem}(por exemplo,python-pip) |
Você quer um nome de coletor personalizado |
get_collector_description() |
string vazia | Você quer uma descrição? |
subscribe_to_event() |
Derivado do caminho do diretório | Você precisa de um roteamento de eventos personalizado |
Executando seus plug-ins
Para que os plug-ins produzam metadados de pacotes, o sbomgen deve receber um artefato para escanear que contenha os arquivos de destino do plug-in (por exemplo, um diretório com requirements.txtpackage.json, ou arquivos de manifesto de pacote equivalentes).
Uso básico
inspector-sbomgen <artifact type> <arguments> --plugin-dir /path/to/plugins
Exemplo:
inspector-sbomgen directory --path /target -o /tmp/sbom.json --plugin-dir /path/to/plugins
Com os scanners nativos desativados (modo somente LUA)
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --disable-native-scanners -o sbom.json
Com registro detalhado
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --verbose -o sbom.json
Listando scanners disponíveis
Use list-scanners para ver todos os scanners disponíveis para o sbomgen. Isso inclui os scanners nativos integrados, todos os plug-ins oficiais do Lua fornecidos com o sbomgen e quaisquer plug-ins Lua personalizados que você tenha fornecido por meio 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 │ └─────────────────────┴────────┴───────────────────────────────┴─────────────────────────────┘
A coluna SOURCE mostra de onde vem cada scanner:
| Origem | Significado |
|---|---|
native |
Scanner embutido fornecido com sbomgen |
official |
Plugins Lua fornecidos com sbomgen |
custom |
Plugin Lua fornecido pelo usuário carregado via --plugin-dir |
A execução list-scanners sem --plugin-dir ainda inclui ambos native e official scanners — eles estão sempre disponíveis. A --plugin-dir bandeira adiciona seus custom scanners ao anúncio.
Para listar somente scanners Lua sem scanners nativos:
inspector-sbomgen list-scanners --plugin-dir /path/to/plugins --disable-native-scanners
Seleção do scanner
Os plug-ins Lua discovery participam do mesmo modelo de seleção de scanner dos scanners nativos integrados. Por padrão, o sbomgen executa todos os scanners cujos grupos correspondem aos grupos de scanners padrão para o tipo de artefato. Você pode substituir isso com três sinalizadores:
Execute somente scanners específicos
Use --scanners para executar somente os scanners nomeados. Todos os outros scanners estão excluídos:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --scanners python-requirements \ -o sbom.json
Isso executa somente o python-requirements scanner. Você pode passar vários nomes de scanner separados por vírgulas ou passar um nome de grupo de scanners (por exemplo,programming-language-packages) para habilitar cada scanner que pertença a esse grupo.
Excluir scanners específicos
Use --skip-scanners para excluir scanners nomeados enquanto executa todo o resto:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --skip-scanners python-poetry \ -o sbom.json
Isso executa todos os scanners padrão, excetopython-poetry. Por exemplo--scanners, esse sinalizador também aceita nomes de grupos, portanto, a passagem --skip-scanners programming-language-packages desativa todos os scanners desse grupo.
nota
--scannerse --skip-scanners são mutuamente exclusivos. Passar os dois produz um erro.
Adicione scanners de grupos não padrão
O conjunto de scanners padrão depende do tipo de artefato que está sendo digitalizado (veja a matriz Como os grupos afetam a seleção abaixo). Um scanner cujos grupos não façam parte do conjunto padrão para o tipo de artefato não será executado a menos que você o ative. Use --additional-scanners para acrescentar scanners ao conjunto padrão sem substituí-lo:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --additional-scanners my-extra-scanner \ -o sbom.json
Isso executa todos os scanners padrão para o tipo de artefato, maismy-extra-scanner. O sinalizador aceita uma lista separada por vírgulas de nomes de scanners ou nomes de grupos e se acumula com o conjunto padrão em vez de substituí-lo. Use list-scanners para verificar a quais grupos um scanner pertence.
Como os grupos afetam a seleção
A get_scanner_groups() função em seu plug-in de descoberta determina a quais grupos o scanner pertence. A execução de um scanner por padrão depende de seus grupos e do tipo de artefato que está sendo escaneado. A matriz abaixo mostra quais grupos estão incluídos no conjunto de scanners padrão para cada tipo de artefato:
| 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 os scanners desse grupo são executados por padrão para esse tipo de artefato. A — significa que o grupo não está no conjunto padrão, portanto, seus scanners só são executados se selecionados explicitamente por meio --scanners de ou. --additional-scanners
Detalhes notáveis:
-
customestá sempre no conjunto padrão — plug-ins personalizados carregados via recebem--plugin-dirautomaticamente ocustomgrupo, então eles são executados por padrão, independentemente do tipo de artefato. -
extra-ecosystemsé padrão paravolumeescaneamentoscontainerlocalhost, e, mas não paradirectoryarchive, oubinaryescaneamentos. Para esses tipos, você deve passar--additional-scanners(pelo nome ou peloextra-ecosystemsgrupo) para incluí-los. -
pkg-scanneré informativo — marca um scanner como um coletor de pacotes para exibiçãolist-scanners, mas, por si só, não faz com que o scanner seja executado. Combine-o com um grupo de execução (por exemplo,programming-language-packages) emget_scanner_groups().
Por exemplo, um plug-in que retorna {sbomgen.groups.EXTRA_ECOSYSTEMS, sbomgen.groups.PACKAGE_COLLECTOR} será executado por padrão em escaneamentos de contêiner, localhost e volume, mas exigirá --additional-scanners (ou--scanners) escaneamentos de diretórios, arquivamentos e binários.
Regras de colisão de plug-ins
O Sbomgen impõe metadados exclusivos em todos os plug-ins carregados para evitar substituições silenciosas e garantir a integridade do SBOM. Quando uma colisão é detectada, o plug-in posterior é ignorado e um aviso é registrado.
O que é verificado
| Metadados | Escopo | Em caso de colisão |
|---|---|---|
Nome do evento Discovery (get_event_name) |
Todos os plug-ins de descoberta | Segundo plugin ignorado |
Nome do scanner (get_scanner_name) |
Todos os plug-ins de descoberta | Segundo plugin ignorado |
Nome do coletor () get_collector_name |
Todos os plug-ins da coleção | Segundo plugin ignorado |
O que é permitido
Vários plug-ins de coleção podem se inscrever no mesmo evento viasubscribe_to_event(). Esse é o padrão de distribuição pretendido: um plug-in de descoberta pode alimentar vários coletores, cada um fazendo coisas diferentes (por exemplo, um extrai pacotes, outro detecta segredos).
Evitando colisões
Se dois plug-ins usarem o mesmo nome de scanner, nome do evento ou nome do coletor, o segundo carregado será ignorado. Para resolver colisões, renomeie os metadados conflitantes definindo a função de substituição apropriada em seu plug-in (get_scanner_name(), ou). get_event_name() get_collector_name()
Exemplo de aviso de colisão
[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.
O aviso informa qual plug-in foi ignorado, o que colidiu, qual plug-in já possui esse nome e qual função alterar.
Depuração
Registro em log do console
Os plug-ins podem emitir mensagens para a saída do console do sbomgen usando as seguintes funções:
| Função | Nível | Visível por padrão? |
|---|---|---|
sbomgen.log_debug(message) |
DEBUG | Não — requer --verbose |
sbomgen.log_info(message) |
INFO | Sim |
sbomgen.log_warn(message) |
WARN | Sim |
sbomgen.log_error(message) |
ERROR | Sim |
Toda a saída de log de um plug-in é automaticamente prefixada com a origem e o caminho do plug-in (por exemplo,[custom:python-pip]), para que as mensagens de diferentes plug-ins sejam fáceis de distinguir. log_infolog_warn, e log_error sempre imprime; log_debug só imprime quando sbomgen é invocado com. --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
Pontos de interrupção
Use sbomgen.breakpoint() para pausar a execução do plug-in e bloquear até pressionar Enter. Isso funciona como um depurador básico — combine-o com instruções de registro para inspecionar o estado em pontos 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
A mensagem do ponto de interrupção é impressa em stderr. A execução é pausada até você pressionar Enter, dando tempo para revisar a saída do log.
Problemas comuns
| Sintomas | Causa | Corrigir |
|---|---|---|
| Plugin não carregado | init.lua ausente |
Certifique-se de que o ponto de entrada exista na profundidade correta do diretório |
| “falta a função necessária” | Erro de digitação no nome da função | Verifique seget_scanner_name,get_scanner_description,get_scanner_groups,discover,get_event_name,get_localhost_scan_paths,get_collector_name,collect, subscribe_to_event estão definidos |
| O plugin de coleção nunca foi chamado | Incompatibilidade do nome do evento | Verifique get_event_name() e subscribe_to_event() retorne a mesma string |
| Nenhum pacote no SBOM | push_packagenão chamado ou faltam campos obrigatórios |
Certifique-se de que namepurl_type, e component_type estão configurados em todas as push_package chamadas (incluindo crianças). Use sbomgen.component_types.* constantes. |
| Erro de tempo de execução no plugin | Erro Lua durante a execução | Verifique a saída sbomgen para mensagens de aviso com os detalhes do erro |
| “IGNORADO: nome do evento de descoberta... já está registrado” | Outro plugin usa o mesmo nome de evento | Renomear get_event_name() para um valor exclusivo |
| “IGNORADO: nome do scanner... já está registrado” | Outro plugin usa o mesmo nome de scanner | Renomear get_scanner_name() para um valor exclusivo |
| “IGNORADO: nome do colecionador... já está registrado” | Outro plugin usa o mesmo nome de coletor | Renomear get_collector_name() para um valor exclusivo |
Referência da API
O catálogo completo de funções é mantido em um documento complementar:
→ Referência da API de plug-in
A referência da API abrange todas as sbomgen.* funções (E/S de arquivo, utilitários binários, saída de pacote, regex, análise estruturada, registro do Windows, registro, depuração), a testing.* API disponível em arquivos de teste, todas as constantes integradas (properties,,,) e os dados globais do ciclo de vida do groups component_types plug-in. platform
Tratamento de erros
Funções de API que podem falhar retornam dois valores:value, err. Sobre o sucesso, err énil. Em caso de falha, o primeiro valor é nil e err é uma string de erro.
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
Se um plug-in gerar um erro Lua não tratado, o sbomgen registra um aviso e continua com o próximo arquivo ou plug-in. Outros plug-ins não são afetados.
Restrições do Sandbox
Os plug-ins são executados em uma VM Lua em sandbox com acesso limitado à biblioteca padrão:
| Ferramentas | Disponível | Observações |
|---|---|---|
base |
✓ | dofile,loadfile, loadstring são removidos |
string |
✓ | Manipulação completa de strings |
table |
✓ | Manipulação completa da tabela |
math |
✓ | Biblioteca matemática completa |
package |
✓ | require()restrito ao diretório de plug-ins |
io |
✗ | Em vez disso, use sbomgen.* I/O funções |
os |
✗ | Bloqueado por motivos de segurança |
debug |
✗ | Bloqueado para evitar a introspecção da VM |
coroutine |
✗ | Não carregado |
Acesso direto ao sistema de arquivos via io.open ou não os.execute está disponível. Todas as operações de arquivo devem passar pela sbomgen API, o que garante um comportamento consistente em todos os tipos de artefato e impede que plug-ins acessem arquivos fora do artefato.
require()pode carregar módulos somente de dentro da própria árvore de diretórios do plug-in. A travessia do diretório principal, como está bloqueada. require("../shared")
Compartilhamento de código entre plug-ins
Você pode usar require() para carregar módulos auxiliares de dentro do diretório do seu plugin:
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
Também há suporte para init.lua subdiretórios com:
my-ecosystem/ ├── init.lua └── parsers/ └── init.lua
local parsers = require("parsers")
require()está restrito ao diretório do seu plugin. Você não pode carregar módulos de outros plug-ins ou caminhos do sistema. Bibliotecas Lua de terceiros (por exemplo, from LuaRocks) não são suportadas — somente módulos auxiliares locais dentro do diretório do plug-in podem ser carregados.