Skip to content

geminishkv/sbom_genform

repo size last commit commit activity open PRs contributors

CI Docker Hub PyPI Python License GitHub Package

Инструмент для безопасной генерации, анализа и форматирования Software Bill of Materials (SBOM). runhelp

Навигация

Документация (docs/):

Разделы README:

Что делает:

  • Генерирует SBOM двумя генераторами (cdxgen + syft) и объединяет результат — из локальной директории, Git-репозитория (GitHub / GitLab) или контейнерного образа
  • Дедуплицирует компоненты по PURL и уязвимости по CVE+компонент
  • Создаёт два подписанных SBOM: без уязвимостей и с ними
  • Сканирует уязвимости параллельно через Trivy, OWASP Dependency-Check, Clair
  • Встраивает найденные уязвимости в SBOM (CycloneDX 1.5)
  • Опционально обогащает уязвимости идентификаторами БДУ ФСТЭК
  • Экспортирует читаемые отчёты: Excel (.xlsx), Word (.docx), ODT (.odt)
  • Готовит SBOM под требования ФСТЭК (secsbom cert — поля GOST)

Main CLI

mainhelp


Установка

PyPI:

pip install sbom-pipeline

GitHub Packages:

pip install sbom-pipeline \
  --index-url https://${GITHUB_TOKEN}@pypi.pkg.github.com/geminishkv/

Исходники:

git clone https://github.com/geminishkv/sbom_genform.git
cd sbom_genform
python3 -m venv venv && source venv/bin/activate
pip install -e ".[dev]"

Запуск утилиты

После установки доступна помощь:

secsbom --help

📖 Полное пошаговое руководство со всеми командами, сценариями и переменными окружения — в docs/USAGE.md.

Утилиту нужно запускать от обычного пользователя. Запуск с правами администратора/root завершается ошибкой, чтобы не выполнять сканеры и Docker-команды с лишними привилегиями.

Быстрый старт

Полный пайплайн генерирует SBOM, дедуплицирует компоненты, подписывает SBOM, сканирует уязвимости и экспортирует отчёты:

# локальный демо-проект
secsbom run

# указание локального проекта из примеров
secsbom run --path examples/project_inject

# удалёный репозиторий github с токеном
secsbom run --url https://github.com/org/repo --token ghp_... 

# удалёный репозиторий gitlab с токеном
secsbom run --url https://gitlab.com/org/repo --token glpat-... 

По умолчанию артефакты пишутся в secgensbom_out, отчёты — в secgensbom_reports.

Основные режимы

Сгенерировать и подписать SBOM без этапа сканирования уязвимостей:

secsbom gen-sbom --path examples/project_inject

Просканировать уже готовый SBOM (и/или контейнерный образ) и сформировать отчёты только по уязвимостям:

# путь к папке проекта + готовый SBOM
secsbom scan secgensbom_out/app-bom-dedup-signed.json --path examples/project_inject

# только готовый SBOM
secsbom scan secgensbom_out/app-bom-dedup-signed.json

# только контейнерный образ
secsbom scan --clair --image nginx:latest

Отформатировать готовые SBOM JSON в Excel/Word/ODT:

secsbom format --sbom-dir secgensbom_out --report-dir secgensbom_reports

Проверить подпись SBOM:

secsbom verify secgensbom_out/merged-bom-signed.json

Примечание: SHA-256-подпись — это контрольная сумма целостности (защита от случайной порчи), а не криптографическая подпись: она не подтверждает аутентичность источника, поскольку хэш и .sig пересчитываются после любого изменения файла. Для аутентичности и неотрекаемости используйте внешнюю подпись (cosign / sigstore).

Посмотреть краткую информацию по SBOM:

secsbom info secgensbom_out/merged-bom-signed.json

Проверить наличие внешних инструментов:

secsbom status

Сравнить два SBOM:

secsbom diff old-bom.json new-bom.json

Добавить поля GOST для отчёта по требованиям ФСТЭК:

secsbom cert sbom.json \
  --component-name "My Product" \
  --component-version "1.0.0" \
  --manufacturer "My Company"

Полезные флаги и переменные

secsbom run --no-cdxgen          # не использовать cdxgen
secsbom run --no-syft            # не использовать syft
secsbom run --bdu                # включить BDU-обогащение
secsbom run --clair --image nginx:latest
secsbom run -o secgensbom_out --reports-dir secgensbom_reports

Те же настройки можно передавать через переменные окружения:

export PROJECT_DIR=examples/project_inject
export OUTPUT_DIR=secgensbom_out
export REPORTS_DIR=secgensbom_reports
export BDU=true
export NVD_API_KEY=<token>

secsbom run

Для scan используются кэши внешних данных:

  • .dependency-check-data / DEP_CHECK_DATA — база NVD для OWASP Dependency-Check
  • .bdu_cache / BDU_CACHE_DIR — соответствия CVE -> BDU ID

Сами этапы scan при повторном запуске выполняются заново, кэшируются именно базы и справочные ответы внешних инструментов.


Выходные артефакты

SBOM JSON

Файл Описание
secgensbom_out/app-bom-cdxgen.json SBOM от cdxgen
secgensbom_out/app-bom-syft.json SBOM от syft
secgensbom_out/app-bom-merged.json Объединённый SBOM (cdxgen + syft)
secgensbom_out/app-bom-dedup.json После дедупликации компонентов
secgensbom_out/app-bom-dedup-signed.json Подписанный SBOM без уязвимостей
secgensbom_out/app-bom-dedup-signed.sig SHA-256 контрольная сумма (без уязв.)
secgensbom_out/merged-bom-signed.json Подписанный SBOM с уязвимостями
secgensbom_out/merged-bom-signed.sig SHA-256 контрольная сумма (с уязв.)
secgensbom_out/vulns-normalized.json Нормализованные уязвимости
<sbom>(cert).json SBOM с полями GOST/ФСТЭК (команда cert)

Если включено BDU-обогащение, в merged-bom-signed.json идентификатор БДУ записывается в vulnerabilities[].properties[] как свойство с именем ru.fstec.bdu:id.

Отчёты сканеров

Путь Сканер
secgensbom_out/trivy/trivy-fs.json Trivy — файловая система
secgensbom_out/trivy/sbom-vulns.json Trivy — анализ SBOM
secgensbom_out/dependency-check/ OWASP Dependency-Check
secgensbom_out/clair/ Clair (если включён)

Reports

Путь Формат Содержимое
secgensbom_reports/excel/*.xlsx Excel Лист 1: компоненты, Лист 2: уязвимости
secgensbom_reports/docx/*.docx Word Таблица компонентов + таблица уязвимостей
secgensbom_reports/odt/*.odt ODT То же самое

Лист «Компоненты»

Колонка Источник
№ п/п порядковый номер
Наименование компонента components[].name из SBOM
Версия компонента components[].version из SBOM
Тип пакета / тип компонента тип экосистемы из PURL (pypi, maven, npm, apk, …)
PURL / технический идентификатор компонента components[].purl из SBOM
Язык (языки) определяется по PURL-типу (dependency.py)
Признак принадлежности к поверхности атаки свойство компонента CycloneDX: attack-surface / attackSurface / isAttackSurface / GOST: attack_surface
Признак выполнения функций безопасности свойство компонента CycloneDX: security-function / securityFunction / isSecurityFunction / GOST: security_function
Принадлежность к контейнерному образу metadata.component.name (только если type = "container")
Роль компонента в составе контейнерного образа свойство компонента: container-role / containerRole / cdx:docker:layer / layer
Адрес веб-ресурса реестровый URL, вычисленный по PURL

Лист «Уязвимости»

Колонка Источник
Компонент имя пакета из сканера
Версия версия при сканировании
CVE / ID идентификатор уязвимости
CVSS оценка CVSS v3 / v2
Критичность CRITICAL / HIGH / MEDIUM / LOW / UNKNOWN
Описание первые 200 символов описания
Сканер trivy / clair / dependency-check
Исправлено в версии версия с исправлением (если известна)
Рекомендация / компенсирующая мера Trivy: PrimaryURL → «Обновить до X»; Clair: Links[0]; Dependency-Check: notesreferences[].url
Статус допустимости в рассматриваемой конфигурации Trivy: поле Status (fixed, affected, will_not_fix, end_of_life, …)

Если пайплайн запущен с --bdu или BDU=true, во всех форматах отчётов уязвимостей появляется отдельная колонка BDU / ID. Если BDU-обогащение выключено, эта колонка не выводится.


Примеры результатов

Подробные примеры итогового SBOM, vulns-normalized.json и экспортируемых таблиц вынесены в docs/RESULT_EXAMPLES.md.

Короткий пример структуры после полного запуска:

secgensbom_out/
├── app-bom-dedup-signed.json
├── merged-bom-signed.json
├── vulns-normalized.json
├── dependency-check/
├── trivy/
└── clair/
secgensbom_reports/
├── excel/merged-bom-signed.xlsx
├── docx/merged-bom-signed.docx
└── odt/merged-bom-signed.odt

BDU Enrichment

Обогащение идентификаторами БДУ ФСТЭК выключено по умолчанию.

Включение через CLI:

secsbom run --bdu

Включение через переменную окружения:

export BDU=true
secsbom run

При включённом BDU пайплайн:

  • запрашивает соответствия CVE -> BDU ID через bdu.fstec.ru
  • добавляет BDU ID в итоговый CycloneDX SBOM как свойство уязвимости
  • выводит BDU ID в экспортируемые отчёты

Пример фрагмента SBOM:

{
  "id": "CVE-2023-1234",
  "properties": [
    {
      "name": "ru.fstec.bdu:id",
      "value": "BDU:2023-01813"
    }
  ]
}

Docker

Образ включает Python, Syft, Trivy, Docker CLI и Node.js/npx (cdxgen для non-Python проектов). OWASP Dependency-Check запускается внутри утилиты через docker run (Docker-in-Docker), его Java-зависимость утяжелила бы основной образ на ~400 МБ. Clair требует отдельного работающего HTTP-сервера — поэтому он вынесен в docker-compose.yml.

Безопасность образа: контейнер работает от непривилегированного пользователя sbom (uid 1001) — secsbom отказывается запускаться от root. В docker-compose.yml сервисам secgensbom / scan заданы security_opt: no-new-privileges и cap_drop: ALL. В образ встроен HEALTHCHECK, OCI-метки указывают лицензию Apache-2.0.

Docker Hub (только Trivy, без Clair/Dependency-Check)

docker pull geminishkv/sbom-pipeline:latest

docker run --rm \
  -v "$(pwd)/examples/project_inject:/app/project_inject" \
  -v "$(pwd)/secgensbom_out:/app/secgensbom_out" \
  -v "$(pwd)/secgensbom_reports:/app/secgensbom_reports" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  geminishkv/sbom-pipeline:latest

Docker Compose (Trivy + Dependency-Check + Clair)

Полный стек с OWASP Dependency-Check и Clair v4 запускается через docker-compose.yml.

Всё одной командой (компоненты + контейнеры + SBOM + отчёты)

Поднимает Clair, собирает SBOM по исходному коду, сканирует уязвимости (Trivy + Dependency-Check + Clair) и контейнерный образ, обогащает БДУ ФСТЭК и выгружает отчёты — NVD-ключ не нужен:

SKIP_CLAIR=false BDU=true IMAGE_NAME=nginx:latest docker compose up --build
  • Код проекта берётся из ./examples/project_inject — замените содержимое этой папки на свой проект (или переопределите volume secgensbom в docker-compose.yml).
  • IMAGE_NAME — контейнерный образ для сканирования через Clair (по умолчанию postgres:14).
  • SKIP_CLAIR=false включает анализ контейнерного образа; BDU=true добавляет идентификаторы БДУ ФСТЭК.
  • Без NVD_API_KEY база NVD для Dependency-Check скачается автоматически при первом запуске (~220 МБ, несколько минут; она кэшируется в ./.dependency-check-data и переиспользуется далее). Clair на первом запуске прогревает updater'ы до ~10 минут.
  • Результат: ./secgensbom_out/ (SBOM-артефакты) + ./secgensbom_reports/{excel,docx,odt}/ (отчёты по компонентам и уязвимостям).

Минимальный запуск (только демо-проект, без сканирования образа):

docker compose up --build

Порядок запуска:

  1. clair-db (Postgres) — база данных Clair, ожидает healthcheck
  2. clair — HTTP-сервер уязвимостей Clair v4, ожидает готовности БД
  3. secgensbom — основной пайплайн, стартует после того, как Clair пройдёт healthcheck

Что происходит внутри secgensbom:

  • Trivy запускается напрямую (встроен в образ)
  • OWASP Dependency-Check запускается через docker run owasp/dependency-check (Docker-in-Docker через /var/run/docker.sock)
  • Clair сканирует образ через clairctl, подключаясь к http://clair:8080

Переменные окружения:

Переменная По умолчанию Описание
SOURCE local Источник проекта: local, github, gitlab
PROJECT_DIR /app/project_inject Путь к проекту внутри контейнера
SKIP_CLAIR false Отключить сканирование Clair (true/false)
CLAIR_ENDPOINT http://clair:8080 Адрес Clair API
IMAGE_NAME Docker-образ для сканирования Clair
BDU false Включить обогащение идентификаторами БДУ ФСТЭК
DEP_CHECK_DATA /app/.dependency-check-data Кэш NVD для Dependency-Check
NVD_CACHE_DIR $DEP_CHECK_DATA/nvd-api-cache Кэш ответов NVD API для повторного CVSS lookup
SBOM_COMPONENT_NETWORK false Разрешить сетевые уточнения языков/URL при экспорте компонентов

Примечание: Если IMAGE_NAME не задан, шаг Clair пропускается автоматически.

NVD_CACHE_DIR хранит ответы NVD API по CVE и используется Clair fallback при заполнении пустого CVSS. Повторный запуск берёт оценку из уже сохранённого ответа и не делает новый HTTP-запрос. По умолчанию экспорт компонентов не ходит в npm/NuGet/Debian/GitHub за уточнениями; для максимально быстрых и воспроизводимых отчётов язык и URL вычисляются из PURL.

Troubleshooting

Частые ошибки запуска, сетевых лимитов NVD, Docker/Clair и пустых отчётных колонок собраны в docs/TROUBLESHOOTING.md.


CI/CD

GitHub Actions

Workflow Триггер Назначение
ci.yml push / PR → main lint + mypy + pytest (3.11–3.13)
secgensbom.yml push → securitycheck, вручную запуск пайплайна, сохранение SBOM и отчётов
publish.yml тег v*.*.* GitHub Packages + PyPI + Docker Hub + GitHub Release

Публикация новой версии — один тег запускает всё:

git tag v2.2.0 -m "Release v2.2.0"
git push origin v2.2.0

Shared template

Файл secgensbom/secgensbom.yml — это переиспользуемый шаблон CI для GitLab. Любой другой проект в GitLab может подключить готовый SBOM-шаг одной строкой, не копируя конфигурацию:


Архитектура

Пайплайн secsbom run

flowchart TD
    IN(["Источник\nlocal / github / gitlab / образ"]) --> STEP1

    subgraph pipeline["secsbom run — этапы"]
        subgraph STEP1["1 · Генерация SBOM"]
            direction TB
            CDXGEN["cdxgen\napp-bom-cdxgen.json"]
            SYFT["syft\napp-bom-syft.json"]
            GEN["generate.py — merge\napp-bom-merged.json"]
            CLAIR_SCAN["clair.py — run_scan_report()\nclair-*.json\nполучение пакетов образа"]
            CLAIR_ENRICH["clair.py — enrich_sbom_with_clair_packages()\nдобавление пакетов образа в SBOM\n(только добавление, без обновления)"]
            CDXGEN --> GEN
            SYFT --> GEN
            GEN --> CLAIR_SCAN --> CLAIR_ENRICH
        end

        STEP1 --> DEDUP["2 · dedup.py\napp-bom-dedup.json\nдедуп компонентов по PURL\n(cdxgen + syft + Clair)"]
        DEDUP --> SIGN1["3 · sign.py\napp-bom-dedup-signed.json + .sig\nSHA-256 — SBOM без уязвимостей"]
        SIGN1 --> SCAN

        subgraph SCAN["4 · scanner/ — параллельно (ThreadPoolExecutor)"]
            direction LR
            TRIVY_FS["trivy.py — scan_filesystem\ntrivy-fs.json (опц. --path)"]
            TRIVY_SBOM["trivy.py — scan_sbom\nsbom-vulns.json"]
            DEPCHECK["depcheck.py — docker run\ndependency-check-report.* (опц. --path)"]
            CLAIR_VULNS["clair.py — parse_report_findings()\n+ NVD CVSS fallback (опц. --image)"]
        end

        TRIVY_FS & TRIVY_SBOM & DEPCHECK & CLAIR_VULNS --> CROSS["cross-populate CVSS\nмежду сканерами"]
        CROSS --> DDUP2["5 · dedup.py\nдедуп уязвимостей\nпо CVE + компонент"]
        DDUP2 --> MERGE["6 · vuln_merger.py\nvulnerabilities[] в SBOM\n+ БДУ ФСТЭК (опц. --bdu)\nvulns-normalized.json"]
        MERGE --> SIGN2["7 · sign.py\nmerged-bom-signed.json + .sig\nSHA-256 — SBOM с уязвимостями"]
        SIGN2 --> EXPORT["8 · exporter.py"]
    end

    CLAIR_SCAN -.->|"отчёт повторно используется\nна этапе 4"| CLAIR_VULNS

    EXPORT --> XLSX["secgensbom_reports/\n*.xlsx"]
    EXPORT --> DOCX["secgensbom_reports/\n*.docx"]
    EXPORT --> ODT["secgensbom_reports/\n*.odt"]
Loading

Структура репозитория

sbom_genform/
├── src/sbom_pipeline/
│   ├── cli.py            # secsbom / secsbom-pipeline (typer)
│   ├── pipeline.py       # оркестратор
│   ├── generate.py       # генерация SBOM
│   ├── dedup.py          # дедупликация
│   ├── sign.py           # SHA-256 подпись
│   ├── exporter.py       # xlsx / docx / odt
│   ├── vuln_merger.py    # встраивание уязвимостей
│   ├── config.py         # конфигурация
│   ├── scanner/
│   │   ├── trivy.py
│   │   ├── depcheck.py
│   │   └── clair.py
│   └── enrichters/
│       ├── bdu.py        # БДУ ФСТЭК (CVE → BDU ID)
│       └── nvd.py        # NVD API (CVSS fallback)
├── docker/
│   └── Dockerfile.secgensbom
├── examples/project_inject/   # уязвимый PHP проект
├── secgensbom/secgensbom.yml  # GitLab CI shared template
├── .github/workflows/
│   ├── ci.yml
│   ├── secgensbom.yml
│   └── publish.yml
├── tests/test_smoke.py
├── pyproject.toml
└── .env.example

Copyright (c) 2026 Elijah S Shmakov

Logo

About

Инструмент для безопасной генерации, анализа и форматирования Software Bill of Materials (SBOM).

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors