
Git diff для SBOM — сравнивайте документы CycloneDX, SPDX и Syft, обнаруживайте подделку и контролируйте CI.
git diff для вашего SBOM. Сравните два SBOM (Software Bills of Materials) и узнайте, что изменилось между сборками, версиями и релизами.
sbomlyze сравнивает хэши компонентов, а не только строки версий. Когда злоумышленник подменяет пакет, не меняя его версию, sbomlyze помечает это. Генераторы и сканеры уязвимостей этого не замечают.
[![CI][ci-img]][ci] [![GitHub Marketplace][marketplace-img]][marketplace] [![GitHub Release][release-img]][release] [![Go Report Card][go-report-img]][go-report] [![OpenSSF Scorecard][scorecard-img]][scorecard] [![License: Apache-2.0][license-img]][license] [![Downloads][download-img]][download]
Узнайте, чем этот сигнал отличается от манифеста или обычного сравнения компонентов, в Разница между манифестом, SBOM-диффом и дрейфом целостности.
Генераторы создают SBOM, а сканеры находят CVE. sbomlyze показывает, что изменилось между двумя SBOM и можно ли этому доверять. Запускайте его после вашего генератора:
syft image:tag -o cyclonedx-json | sbomlyze - --compliance— анализирует и оценивает сгенерированный SBOM без временного файла. Сравните его с базовым, чтобы классифицировать дрейф и управлять пайплайном.
Добавьте [SBOMlyze Diff из GitHub Marketplace][marketplace], чтобы сравнить включённый в репозиторий или отдельно сгенерированный SBOM с его базовым состоянием в git. Указанный ниже неизменяемый SHA — это опубликованное Action v0.5.1:```yaml
steps:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0
uses: rezmoss/sbomlyze@31503690611fda8ebba4ed2bd186eda000442594 # v0.5.1 with: sbom-path: build/sbom.cdx.json
Действие по умолчанию записывает Job Summary и может применять политики, сообщать об отклонениях целостности, выгружать SARIF или поддерживать единый комментарий в pull request. Полное описание Action см. в [справочнике по Action](https://github.com/rezmoss/sbomlyze/blob/HEAD/ACTION.md): входные данные, выходные данные, разрешения и рекомендации по безопасности. Пример с проходящим обновлением зависимостей и блокированным изменением хеша без смены версии см. в [живом демонстрационном репозитории](https://github.com/rezmoss/sbomlyze-action-demo) — там доступны публичные запуски workflow и SARIF-свидетельства.
Для проверки на собственном примере (dogfood) применительно к конкретным форматам используйте публичные примеры [Go + SPDX](https://github.com/rezmoss/sbomlyze-go-spdx-demo), [Node + CycloneDX](https://github.com/rezmoss/sbomlyze-node-cyclonedx-demo) или [container](https://github.com/rezmoss/sbomlyze-container-demo). В каждом — пять воспроизводимых сценариев проверки. В [10-минутном бета-руководстве](https://github.com/rezmoss/sbomlyze/blob/HEAD/BETA.md) собраны четыре ключевых вопроса по активации и качеству сигналов.
Сгенерированные SBOM не обязательно коммитить: `baseline: workflow-artifact` получает самый свежий подходящий артефакт из успешного запуска на ветке по умолчанию. [Зафиксированный сопутствующий workflow для Syft](https://github.com/rezmoss/sbomlyze/blob/HEAD/examples/workflows/syft-companion.yml) показывает генерацию и публикацию базовой линии, а SBOMlyze остаётся ответственным за проверку и политики.
## Зачем sbomlyze?
Многие инструменты генерируют SBOM. Немногие сравнивают их, и ещё меньше сообщают, является ли изменение рутинным или красным флагом цепочки поставок. sbomlyze заполняет этот пробел.
| Возможность | **sbomlyze** | cyclonedx-cli | sbomqs | syft / trivy |
|---|:---:|:---:|:---:|:---:|
| Сравнение SBOM с SBOM (**diff**) | ✅ | базово | ❌ | ❌ |
| Отклонение **целостности / подмены** (хеш изменился без смены версии) | ✅ | ❌ | ❌ | ❌ |
| Дифф графа зависимостей + риск транзитивной глубины | ✅ | ❌ | ❌ | ❌ |
| Оценка соответствия **NTIA / CISA / BSI** | ✅ | ❌ | ✅ | ❌ |
| Конвертация форматов (Syft / CycloneDX / SPDX) | ✅ | ✅ | ❌ | частично |
| Обозреватели **TUI + Web UI** | ✅ | ❌ | ❌ | ❌ |
| Политический шлюз + SARIF / JUnit / Markdown / HTML / Patch | ✅ | частично | частично | частично |
## Возможности
- **Дифф SBOM**: Сравнивайте два SBOM и видите добавленные, удалённые и изменённые компоненты с первого взгляда
- **Классификация отклонений**: Отличайте версионные отклонения от **отклонений целостности** (хеш изменился без смены версии — признак подмены) и отклонений метаданных
- **Оценка соответствия**: Оценивайте любой SBOM по минимальным элементам **NTIA**, **CISA 2025** и **BSI TR-03183**
- **Дифф графа зависимостей**: Отслеживайте транзитивные зависимости и глубину цепочки поставок
- **Поддержка нескольких форматов**: Syft, CycloneDX, SPDX (JSON)
- **Конвертация форматов**: Преобразование между форматами CycloneDX, SPDX и Syft
- **Надёжное сопоставление идентификаторов**: Приоритет PURL → CPE → BOM-ref → namespace/name
- **Режим статистики**: Анализ отдельных SBOM по метрикам лицензий, зависимостей и целостности
- **Интерактивный TUI-режим**: Исследуйте SBOM с помощью навигации с клавиатуры и поиска
- **Режим Web UI**: Браузерный обозреватель SBOM с загрузкой через drag-and-drop
- **Политический движок**: Применение правил отклонений, лицензий и оценки соответствия в CI-пайплайнах
- **GitHub Marketplace Action**: Контролируйте pull request-ы на предмет отклонений SBOM с помощью Job Summary, SARIF и опционального комментария
- **Обнаружение дубликатов и коллизий**: Найдите несколько версий одного пакета и неоднозначные совпадения идентификаторов
- **Множество выходных форматов**: Text, JSON, SARIF, JUnit XML, Markdown, HTML, JSON Patch
- **Устойчивый парсинг**: Продолжение работы при ошибках со структурированными предупреждениями
## Установка
### Homebrew (macOS/Linux)```bash
brew install rezmoss/sbomlyze/sbomlyze
Скрипт установки загружает правильный бинарный файл для вашей ОС/архитектуры:```bash
curl -sSfL https://raw.githubusercontent.com/rezmoss/sbomlyze/main/install.sh | sh
curl -sSfL https://raw.githubusercontent.com/rezmoss/sbomlyze/main/install.sh | sudo sh -s -- -b /usr/local/bin
curl -sSfL https://raw.githubusercontent.com/rezmoss/sbomlyze/main/install.sh | sh -s -- -v 0.4.0
**Параметры установщика:**
| Параметр | Описание |
|--------|-------------|
| `-b <dir>` | Каталог установки (по умолчанию: `./bin`) |
| `-d` | Включить отладочный вывод |
| `-v <ver>` | Установить конкретную версию (по умолчанию: последняя) |
Установщик всегда проверяет контрольную сумму релиза. Если установлен совместимый GitHub CLI, он также проверяет происхождение сборки релиза и блокирует установку, если проверка не удалась.
### Установка через Go```bash
go install github.com/rezmoss/sbomlyze/cmd/sbomlyze@latest
Загрузите последний бинарный файл с GitHub Releases.
Начиная с v0.3.7, архивы релизов публикуются с аттестациями артефактов GitHub. Проверьте загрузку независимо с помощью:```bash
gh attestation verify ./sbomlyze_0.4.0_Linux_x86_64.tar.gz
--repo rezmoss/sbomlyze
--signer-workflow rezmoss/sbomlyze/.github/workflows/release.yml
Инструкции по использованию неподписанных репозиториев apt, rpm и apk были удалены до тех пор, пока
репозитории не будут поддерживать проверку подписи встроенными средствами менеджера пакетов.
**Пользователи macOS:** Снимите флаг карантина после скачивания:```bash
xattr -d com.apple.quarantine ./sbomlyze
chmod +x ./sbomlyze
git clone https://github.com/rezmoss/sbomlyze.git cd sbomlyze go build -o sbomlyze ./cmd/sbomlyze
## Быстрый старт```bash
# Compare two SBOMs (the headline use case)
sbomlyze before.json after.json
# Analyze a single SBOM
sbomlyze image.json
# Read an SBOM from standard input
syft image:tag -o cyclonedx-json | sbomlyze -
# Use standard input on either side of a diff
syft image:tag -o cyclonedx-json | sbomlyze baseline.json -
# Score an SBOM against NTIA / CISA / BSI minimum elements
sbomlyze image.json --compliance
# Interactive TUI explorer
sbomlyze image.json -i
# Web UI (opens browser)
sbomlyze -web
# Convert between SBOM formats
sbomlyze convert syft.json --to spdx
sbomlyze convert cdx.json --to syft -o output.json
# JSON output for CI integration
sbomlyze before.json after.json --json
# SARIF output for GitHub Code Scanning
sbomlyze before.json after.json --format sarif
# Markdown report for PR comments
sbomlyze before.json after.json --format markdown
# Apply policy checks
sbomlyze before.json after.json --policy policy.json
sbomlyze <sbom1|-> [sbom2|-] [options] sbomlyze convert <sbom|-> --to [-o output]
Modes: Single file: sbomlyze [--json] Show statistics Interactive: sbomlyze -i Interactive explorer Convert: sbomlyze convert --to Convert SBOM format Web server: sbomlyze -web [--port 8080] Web UI explorer Two files: sbomlyze [...] Show diff
Use - in place of one SBOM path to read it from standard input.
Options: -i, --interactive Interactive TUI explorer -web, --web Start web UI server --port Web server port (default 8080) --json Output in JSON format (shortcut for --format json) --format Output format: text, json, sarif, junit, markdown, html, patch --compliance Show NTIA/CISA/BSI compliance scoring --policy Policy file for CI checks --strict Fail on parse warnings --tolerant Continue on parse warnings (default) --no-pager Disable automatic paging of output --to Target format for convert: cyclonedx (cdx), spdx, syft -o, --output Output file for convert (default: stdout) --version, -v Show version information --help, -h Show this help message
## Команды
### Режим статистики (один файл)
Анализ SBOM для получения информации о компонентах, лицензиях и зависимостях.```bash
sbomlyze image.json
Вывод включает контекст сканирования, автоматически обнаруженные ключевые находки и статистику:``` Scan Context: Tool: syft 1.40.1 Schema: 16.0.18 Scan Scope: all-layers Source Type: image Source: alpine:latest
Key Findings: 💻 OS/Distro: Alpine Linux v3.21 📦 Dominated by apk: 71 of 71 packages (100.0%) 📂 8,542 files tracked on filesystem 🔗 Relationships: 71 containment + 64 dependency 📜 License profile: 72% permissive, 20% copyleft ⚠️ Low hash coverage: 0.0% (71 of 71 missing) 🔍 Top catalogers: apkdb-cataloger (71)
Total Components: 71
By Package Type: apk 71
Licenses: With license: 71 Without license: 0
Top Licenses: MIT 17 BSD-3-Clause 8 GPL-2.0-only 8
Integrity: With hashes: 0 Without hashes: 71
Dependencies: Components with deps: 65 Total dep relations: 176
#### Ключевые результаты
sbomlyze автоматически формирует аналитическую информацию о вашем SBOM. Для анализа одного файла сюда входят:
| Результат | Описание |
|---------|-------------|
| **Определение ОС/дистрибутива** | Определяет операционную систему или дистрибутив по метаданным SBOM |
| **Доминирующая экосистема** | Сообщает, когда один тип пакетов доминирует (>60% всех пакетов) |
| **След в файловой системе** | Количество отслеживаемых файлов в файловой системе |
| **Плотность связей** | Количество связей containment и dependency-of |
| **Горячие точки расположения** | Основные каталоги, где находятся компоненты |
| **Профиль лицензионного риска** | Разбивка процентов разрешительных/copyleft/неизвестных лицензий |
| **Предупреждения о качестве данных** | Предупреждения при низком покрытии лицензиями (<50%), хэшами (<50%) или PURL (<80%) |
| **Предупреждения о дубликатах** | Отмечает дублирующиеся группы компонентов |
| **Разбивка по каталогизаторам** | Основные сканеры/каталогизаторы, которые обнаружили компоненты (SBOM Syft) |
#### Метрики покрытия
Режим статистики вычисляет проценты покрытия для оценки качества данных:
| Метрика | Описание |
|--------|-------------|
| **Покрытие PURL** | Процент компонентов с Package URLs |
| **Покрытие CPE** | Процент компонентов с CPE (готовность к сканированию уязвимостей) |
| **Покрытие лицензиями** | Процент компонентов хотя бы с одной лицензией |
| **Покрытие хэшами** | Процент компонентов с хэшами целостности |
#### Категоризация лицензий
Лицензии автоматически категоризируются на:
| Категория | Примеры |
|----------|----------|
| **Копилефт** | GPL, LGPL, AGPL, MPL, EPL, CDDL |
| **Разрешительная** | MIT, BSD, Apache, ISC, Zlib, Unlicense |
| **Общественное достояние** | Посвящения в общественное достояние |
| **Неизвестно** | Нераспознанные или отсутствующие лицензии |
### Режим конвертации
Конвертируйте SBOM между форматами CycloneDX, SPDX и Syft JSON. Формат входного файла определяется автоматически.```bash
# CycloneDX to SPDX
sbomlyze convert image.cdx.json --to spdx
# Syft to CycloneDX (cdx is an alias for cyclonedx)
sbomlyze convert syft-output.json --to cdx
# SPDX to Syft, writing to a file
sbomlyze convert spdx-output.json --to syft -o converted.json
При конвертации сохраняются имена компонентов, версии, PURLs, CPEs, лицензии, хэши, информация о поставщике и зависимости. Поля, специфичные для формата (например, язык Syft, foundBy, locations), переносятся через свойства CycloneDX при конвертации в CDX.
Сравните два SBOM, чтобы увидеть, что изменилось между версиями.```bash sbomlyze v1.0.json v2.0.json
#### Обзор различий
Отчет о различиях начинается с параллельного сравнения метаданных (имена файлов, размеры, информация об ОС, информация об инструменте, количество компонентов), за которым следуют сведения о контексте сканирования, если они доступны.
#### Вывод```
📊 Drift Summary:
📦 Version drift: 58 components
⚠️ Integrity drift: 1 component (hash changed without version change!)
📝 Metadata drift: 2 components
🔑 Key Findings:
📈 Attack surface: +5 packages (7.0%), +120 files (3.2%)
🚨 2 version downgrades detected: openssl 3.1.4→3.0.2, curl 8.5.0→8.4.0
🔄 56 version upgrades (2 major, 12 minor, 42 patch) among 65 shared packages
⚠️ Integrity drift (1 total): 1 npm (review recommended)
❌ python ecosystem entirely removed (15 → 0 packages)
➕ New ecosystem: golang (8 packages)
✅ Core system packages stable: apk (71) unchanged
+ Added (2):
+ libgcrypt 1.10.3-r0
+ libgpg-error 1.49-r0
- Removed (3):
- libapk 3.0.3-r1
- libgcc 15.2.0-r2
- nghttp3 1.13.1-r0
~ Changed (58):
~ nginx
version: 1.29.4-r1 -> 1.27.3-r1
~ suspicious-pkg ⚠️ [INTEGRITY]
hash[SHA256]: abc123 -> def456
>> Added dependencies:
pkg:apk/alpine/libxslt: +[so:libgcrypt.so.20]
<< Removed dependencies:
pkg:apk/alpine/libcurl: -[so:libnghttp3.so.9]
🔗 New transitive dependencies (3):
+ pkg:npm/lodash (depth 2)
via: [pkg:npm/my-app pkg:npm/express pkg:npm/lodash]
+ pkg:npm/underscore (depth 3)
via: [pkg:npm/my-app pkg:npm/express pkg:npm/lodash pkg:npm/underscore]
📊 New deps by depth:
Depth 2: 1
Depth 3+ (risky): 2 ⚠️
В режиме diff sbomlyze автоматически генерирует более детальные сведения, сравнивая оба SBOM:
Добавленные и удалённые компоненты группируются по типу пакета с примерами списков, что позволяет легко увидеть, что изменилось в каждой экосистеме.
Оцените любой SBOM по трём основным фреймворкам минимальных элементов, чтобы ответить на вопрос, который постоянно задают аудиторы и закупочные команды: «Достаточно ли полон этот SBOM?»```bash
sbomlyze image.json --compliance
sbomlyze before.json after.json --compliance
sbomlyze image.json --compliance --json
### Оценённые фреймворки
| Фреймворк | Проверки | Ключевые требования |
|-----------|--------|----------------------|
| **NTIA Minimum Elements** (2021) | 7 | имя, версия, поставщик, уникальные идентификаторы (PURL/CPE), связи зависимостей, автор SBOM, отметка времени |
| **CISA 2025 Minimum Elements** (авг. 2025, черновик) | 10 | добавляет производителя ПО, информацию о лицензии, **хэш компонента** и имя инструмента поверх NTIA |
| **BSI TR-03183-2** (v2.1.0, 2025) | 9 | требует контакт создателя компонента, **хэш SHA-512**, лицензии в формате SPDX и контакт создателя SBOM |
### Отображение оценки
Каждый фреймворк сообщает процент (пройденные проверки / всего проверок) плюс общую оценку (среднюю по фреймворкам), с индикаторами статуса:
| Индикатор | Оценка |
|-----------|-------|
| 🟢 | ≥ 90% |
| 🟡 | 70–89% |
| 🟠 | 50–69% |
| 🔴 | < 50% |
Вывод JSON (`--compliance --json`) включает полный отчёт с деталями прохождения/непрохождения по каждой проверке; формат HTML встраивает отчёт о соответствии в страницу отчёта.
### Ограничение соответствия в CI
Принудительно применяйте пороги соответствия через [механизм политик](#policy-engine). Установка любого порога запускает оценку соответствия без флага `--compliance`:```json
{
"min_ntia_score": 85,
"min_cisa_score": 70,
"min_bsi_score": 80,
"min_overall_compliance": 75
}
Входной фрагмент пуст — нечего переводить.```bash sbomlyze image.json --policy compliance-policy.json
## Сравнение графа зависимостей
sbomlyze выходит за рамки простого сравнения списков компонентов и анализирует полный граф зависимостей, выявляя риски цепочки поставок, возникающие из-за транзитивных зависимостей.
### Возможности
| Функция | Описание |
|---------|-------------|
| **Сравнение рёбер** | Добавленные/удалённые прямые зависимости (A зависит от B) |
| **Достижимость транзитивных зависимостей** | Новые косвенные зависимости, появляющиеся через граф |
| **Отслеживание потери транзитивных зависимостей** | Транзитивные зависимости, которые были удалены |
| **Отслеживание пути** | Показывает точно, как достигается каждая новая транзитивная зависимость |
| **Отслеживание глубины** | На сколько переходов каждая новая зависимость удалена от вашего кода |
| **Сводка по рискам** | Зависимости глубиной 3+ помечены как более рискованные |
### Почему глубина важна
Зависимости, добавляемые глубже в граф зависимостей,:
- Сложнее проверять и анализировать
- Часто подтягиваются без явного согласования
- Частые векторы атак на цепочку поставок (например, инцидент event-stream)
Сводка по глубине помогает расставить приоритеты при проверке:
| Глубина | Уровень риска | Описание |
|-------|------------|-------------|
| **1** | Низкий | Прямые зависимости (вы выбрали их) |
| **2** | Средний | Зависимости ваших зависимостей |
| **3+** | Высокий ⚠️ | Глубокие транзитивные зависимости — проверяйте внимательно |
### Пример: обнаружение глубоких транзитивных зависимостей```bash
# Before: app -> express (simple, 1 dep)
# After: app -> express -> lodash -> underscore -> deep-lib (chain of 4)
sbomlyze before.json after.json
Вывод:``` 🔗 New transitive dependencies (3):
📊 New deps by depth: Depth 2: 1 Depth 3+ (risky): 2 ⚠️
### JSON-вывод для графа зависимостей```json
{
"dependencies": {
"added_deps": {
"pkg:npm/express": ["pkg:npm/lodash", "pkg:npm/body-parser"]
},
"removed_deps": {},
"transitive_new": [
{
"target": "pkg:npm/underscore",
"via": ["pkg:npm/my-app", "pkg:npm/express", "pkg:npm/lodash", "pkg:npm/underscore"],
"depth": 3
}
],
"transitive_lost": [],
"depth_summary": {
"depth_1": 0,
"depth_2": 2,
"depth_3_plus": 2
}
}
}
sbomlyze классифицирует изменения компонентов по трём типам расхождений, помогая отличить обычные обновления от потенциально подозрительных изменений.
Расхождение целостности возникает, когда хеш компонента изменяется, но его версия остаётся прежней. Это может указывать на:
~ suspicious-pkg ⚠️ [INTEGRITY] hash[SHA256]: abc123 -> def456
**Рекомендация**: Всегда исследуйте дрейф целостности. Он может быть безвредным, но это ключевой сигнал для безопасности цепочки поставок.
### JSON-вывод для дрейфа
Сводка по дрейфу находится внутри объекта `diff`:```json
{
"diff": {
"changed": [
{
"id": "pkg:npm/suspicious-pkg",
"name": "suspicious-pkg",
"changes": ["hash[SHA-256]: abc123 -> def456"],
"drift": {
"type": "integrity",
"hash_changes": {
"changed": {
"SHA-256": {"before": "abc123", "after": "def456"}
}
}
}
}
],
"drift_summary": {
"version_drift": 55,
"integrity_drift": 1,
"metadata_drift": 2
}
}
}
Извлечение сводки дрейфа:```bash
sbomlyze before.json after.json --json | jq '.diff.drift_summary'
sbomlyze before.json after.json --json | jq -e '.diff.drift_summary.integrity_drift > 0'
## Обнаружение дубликатов и коллизий
### Обнаружение дубликатов
sbomlyze определяет компоненты с одинаковой идентичностью, но разными версиями в SBOM:```
⚠️ Duplicates Found: 2
lodash: [4.17.20, 4.17.21]
express: [4.18.0, 4.19.2]
В режиме diff отслеживание изменений версий дубликатов включает:
Коллизии — это неоднозначные совпадения идентификаторов, когда компоненты имеют один и тот же ID, но конфликтующие характеристики:
| Тип | Описание |
|---|---|
| Несовпадение имени | Разные имена компонентов, сопоставленные с одним и тем же идентификатором ID |
| Несовпадение хеша | Одна и та же версия компонента имеет разные хеши (возможное вмешательство) |
sbomlyze sbom.json -i

### Горячие клавиши TUI
#### Навигация
| Клавиша | Действие |
|-----|--------|
| `↑` / `k` | Переместиться вверх |
| `↓` / `j` | Переместиться вниз |
| `PgUp` / `Ctrl+u` | На полстраницы вверх |
| `PgDn` / `Ctrl+d` | На полстраницы вниз |
| `Home` / `g` | Перейти в начало |
| `End` / `G` | Перейти в конец |
| `Enter` | Просмотреть сведения о компоненте |
| `Esc` / `Backspace` | Назад |
| `q` / `Ctrl+c` | Выйти |
#### Поиск и фильтрация
| Клавиша | Действие |
|-----|--------|
| `/` | Глубокий поиск по всем полям (имя, PURL, лицензии, исходный JSON) |
| `t` | Фильтрация по типу пакета (npm, apk, golang, pypi и т. д.) |
| `c` | Сбросить все активные фильтры |
#### Представления
| Клавиша | Контекст | Действие |
|-----|---------|--------|
| `j` | Детальный просмотр | Просмотр исходного JSON компонента с подсветкой синтаксиса |
| `d` | JSON-просмотр | Вернуться к детальному просмотру |
| `Enter` | JSON-просмотр | Экспортировать JSON компонента в файл |
| `?` | Любое представление | Показать справку со всеми сочетаниями клавиш |
### Детальный просмотр компонента
Детальный просмотр показывает полную информацию о компоненте:
- Информация о пакете (имя, версия, PURL, пространство имён, поставщик)
- Лицензии с визуальными индикаторами
- Хэши целостности
- CPE (Common Platform Enumeration)
- Список зависимостей
- Идентификаторы (ID, BOM-ref, SPDX-ID)
## Режим веб-интерфейса
Запустите браузерный обозреватель SBOM с загрузкой файлов методом перетаскивания:```bash
# Start web server on default port 8080
sbomlyze -web
# Start on custom port
sbomlyze -web --port 3000
Затем откройте http://localhost:8080 в браузере.
Веб-интерфейс показывает полную статистику, включая:
Проверка безопасности
Аудит соответствия
Отладка разработки
Веб-интерфейс включает полноценный обозреватель файловой системы для изучения файлов в SBOM (особенно полезен для SBOM, созданных Syft, с метаданными файлов):
*.so, /usr/lib/**/*.conf)-i (Интерактивный режим)Запустите терминальный TUI-обозреватель для навигации по SBOM с помощью клавиатуры.```bash sbomlyze image.json -i
Features: навигация по дереву, сведения о компонентах, поиск, проверка лицензий/хэшей.
### `-web` (Режим веб-сервера)
Запустите веб-сервер для просмотра SBOM через браузер.```bash
# Default port 8080
sbomlyze -web
# Custom port
sbomlyze -web --port 3000
Веб-интерфейс предоставляет загрузку перетаскиванием, интерактивное дерево, глубокий поиск и панель статистики.
--complianceОцените SBOM на соответствие фреймворкам минимальных элементов NTIA, CISA 2025 и BSI TR-03183. См. Оценка соответствия.```bash sbomlyze image.json --compliance sbomlyze image.json --compliance --json
### `--format` / `-f`
Выберите выходной формат. Доступно семь форматов:
| Формат | Флаг | Описание | Лучше всего для |
|--------|------|-------------|----------|
| **text** | `--format text` (по умолчанию) | Человекочитаемый вывод в терминал | Локальный просмотр |
| **json** | `--json` или `--format json` | Структурированный JSON | CI-конвейеры, скрипты |
| **sarif** | `--format sarif` | SARIF 2.1.0 для GitHub Code Scanning | Интеграция с GitHub |
| **junit** | `--format junit` | Результаты тестов JUnit XML | CI-панели тестирования |
| **markdown** | `--format markdown` | Markdown-отчёт, готовый для PR-комментариев | Комментарии к Pull request |
| **html** | `--format html` | Автономный HTML-отчёт (встроенные CSS/JS) | Аудиторы, отчёты для распространения |
| **patch** | `--format patch` | Операции JSON Patch (RFC 6902) | Программное применение патчей |```bash
# SARIF output for GitHub Code Scanning
sbomlyze before.json after.json --format sarif > results.sarif
# JUnit output for CI test dashboards
sbomlyze before.json after.json --format junit > results.xml
# Markdown report for PR comments
sbomlyze before.json after.json --format markdown > report.md
# Self-contained HTML report
sbomlyze before.json after.json --format html > report.html
# JSON Patch operations
sbomlyze before.json after.json --format patch > changes.json
Формирует отчёт SARIF 2.1.0, подходящий для GitHub Code Scanning. Определяемые правила включают:
integrity-drift (ошибка): хэш изменён без изменения версииdeep-dependency (предупреждение): новая зависимость на глубине 3+new-component / removed-component (примечание): добавление/удаление компонентовversion-change (примечание): обновление версий компонентовpolicy-violation (ошибка/предупреждение): нарушения правил политикиФормирует JUnit XML с тестовыми случаями для проверки:
Формирует отчёт в формате Markdown со следующими элементами:
Формирует один автономный HTML-файл (встроенные CSS и JavaScript, без внешних ресурсов), который удобно отправлять аудиторам по электронной почте или прикреплять к релизу. Он включает панель статистики, дерево зависимостей, сводку дрейфа, а при установке --compliance — также встроенный отчёт о соответствии.
Формирует массив операций RFC 6902 JSON Patch (add, remove, replace), представляющих различия.
--jsonСокращение для --format json. Выводит результаты в формате JSON для программного использования.```bash
sbomlyze image.json --json
sbomlyze before.json after.json --json
**Структура JSON-статистики:**```json
{
"stats": {
"total_components": 71,
"by_type": {"apk": 71},
"by_license": {"MIT": 17, "BSD-3-Clause": 8},
"without_license": 0,
"with_hashes": 0,
"without_hashes": 71,
"total_dependencies": 176,
"with_dependencies": 65,
"duplicate_count": 0,
"by_language": {"go": 45, "python": 12},
"by_found_by": {"apk-db-cataloger": 71},
"license_categories": {
"copyleft": 8,
"permissive": 55,
"public_domain": 0,
"unknown": 8
},
"with_cpes": 71,
"without_cpes": 0,
"with_purl": 71,
"without_purl": 0
},
"warnings": []
}
--policy <file>Применяет правила политики и завершает CI с ошибкой при нарушении.```bash sbomlyze before.json after.json --policy policy.json
См. [Policy Engine](#policy-engine) для подробностей.
### `--strict`
Немедленно завершать работу при любой ошибке разбора.```bash
sbomlyze broken.json --strict
# Error parsing broken.json: unknown SBOM format
# exit status 1
--tolerant (по умолчанию)Продолжать обработку при ошибках, собирать предупреждения.```bash sbomlyze broken.json --tolerant
Предупреждения при разборе включают структурированную информацию: исходный файл, человекочитаемое сообщение и, опционально, поле, вызвавшее проблему.
### `--no-pager`
Отключает автоматический постраничный вывод. Полезно при передаче вывода в другую команду или при работе в неинтерактивных средах.```bash
sbomlyze image.json --no-pager
sbomlyze before.json after.json --no-pager | head -20
Создавайте политики для применения правил в конвейерах CI/CD. sbomlyze завершает работу с кодом 1 при возникновении нарушений.
{ "max_added": 10, "max_removed": 5, "max_changed": 100, "deny_licenses": ["GPL-3.0", "AGPL-3.0"], "require_licenses": true, "deny_duplicates": true, "deny_integrity_drift": true, "max_depth": 3, "warn_supplier_change": true, "warn_new_transitive": true, "min_ntia_score": 85, "min_cisa_score": 70, "min_bsi_score": 80, "min_overall_compliance": 75 }
### Правила политики
| Правило | Тип | Описание |
|------|------|-------------|
| `max_added` | int | Максимальное количество новых компонентов (0 = без ограничений) |
| `max_removed` | int | Максимальное количество удалённых компонентов (0 = без ограничений) |
| `max_changed` | int | Максимальное количество изменённых компонентов (0 = без ограничений) |
| `deny_licenses` | []string | Список запрещённых идентификаторов лицензий |
| `require_licenses` | bool | Требовать, чтобы все *добавленные* компоненты имели лицензии (в режиме diff проверяются только новые компоненты) |
| `deny_duplicates` | bool | Ошибка, если в результате существуют дублирующиеся пакеты |
| `deny_integrity_drift` | bool | Ошибка, если хэш компонента изменился без изменения версии (риск цепочки поставок) |
| `max_depth` | int | Ошибка, если новые транзитивные зависимости на глубине >= N (0 = без ограничений) |
| `warn_supplier_change` | bool | Предупреждать (не ошибка), если поставщик/автор компонента изменился |
| `warn_new_transitive` | bool | Предупреждать (не ошибка) о любых новых транзитивных зависимостях |
| `min_ntia_score` | int | Ошибка, если оценка соответствия NTIA ниже этого (0-100, 0 = отключено) |
| `min_cisa_score` | int | Ошибка, если оценка соответствия CISA ниже этого (0-100, 0 = отключено) |
| `min_bsi_score` | int | Ошибка, если оценка соответствия BSI ниже этого (0-100, 0 = отключено) |
| `min_overall_compliance` | int | Ошибка, если общая оценка соответствия ниже этого (0-100, 0 = отключено) |
> Установка любого порога `min_*_score` автоматически запускает оценку соответствия, даже без флага `--compliance`.
### Пример: строгая политика```json
{
"max_added": 5,
"max_removed": 3,
"max_changed": 20,
"deny_licenses": ["GPL-3.0", "AGPL-3.0", "SSPL-1.0"],
"require_licenses": true,
"deny_duplicates": true,
"deny_integrity_drift": true,
"max_depth": 3,
"warn_supplier_change": true,
"warn_new_transitive": true,
"min_overall_compliance": 80
}
!! Policy Violations (3): [max_added] too many components added: 10 > 5 [max_removed] too many components removed: 7 > 3 [deny_licenses] component foo has denied license: GPL-3.0
## Поддерживаемые форматы SBOM
| Формат | Определение файла | Извлекаемые идентификаторы |
|--------|----------------|----------------------|
| Syft (нативный) | ключ JSON `"artifacts"` + один из `"source"`, `"distro"`, `"descriptor"` | PURL, CPE, name |
| CycloneDX | ключ JSON `"bomFormat"` = `"CycloneDX"`, или `"$schema"`, содержащий `cyclonedx` | PURL, CPE, BOM-ref, group (namespace) |
| SPDX | ключ JSON `"spdxVersion"`, начинающийся с `"SPDX-"` | PURL, CPE, SPDXID |
Все форматы должны быть JSON. Поддержка XML в настоящее время недоступна.
### Преобразование форматов
sbomlyze может преобразовывать между любыми из трёх поддерживаемых форматов:```bash
sbomlyze convert input.json --to spdx # any format → SPDX 2.3
sbomlyze convert input.json --to cyclonedx # any format → CycloneDX 1.5
sbomlyze convert input.json --to syft # any format → Syft JSON
Подробнее см. в режиме преобразования.
sbomlyze может сравнивать SBOM в разных форматах:```bash
sbomlyze syft-output.json cyclonedx-output.json
sbomlyze spdx-output.json syft-output.json
**Примечание:** Различные форматы SBOM извлекают разные уровни детализации. Межформатный diff может показывать изменения, отражающие различия форматов (например, доступность полей), а не реальные изменения системы. Система ключевых результатов предупредит о несоответствиях контекста сканирования при их обнаружении.
## Сопоставление идентификаторов компонентов
Компоненты сопоставляются с помощью системы идентификации, основанной на приоритете:
| Priority | Identifier | Example | Description |
|----------|------------|---------|-------------|
| 1 | PURL | `pkg:npm/lodash` | Package URL (без версии) |
| 2 | CPE | `cpe:vendor:product` | CPE vendor:product (без версии) |
| 3 | BOM-ref / SPDXID | `ref:component-123` | CycloneDX bom-ref или идентификатор SPDX |
| 4 | Namespace + Name | `com.example/mypackage` | Группа/namespace и имя |
| 5 | Name | `simple-package` | Запасной вариант — только имя |
## Интеграция с CI/CD
### GitHub Actions
SBOMlyze поставляется как JavaScript Action без зависимостей. Он сравнивает сохранённый в репозитории
или созданный отдельно head SBOM с файлом в git-базе pull request,
публикует Job Summary и опционально формирует SARIF или обновляет один комментарий PR.```yaml
name: SBOM Check
on:
pull_request:
permissions:
contents: read
jobs:
sbom-diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- id: sbomlyze
uses: rezmoss/sbomlyze@31503690611fda8ebba4ed2bd186eda000442594 # v0.5.1
with:
sbom-path: build/sbom.cdx.json
policy: .github/sbom-policy.json
fail-on: policy
Действие никогда не запускает команды генератора. Создавайте головной SBOM на отдельном,
проверенном этапе или фиксируйте его в репозитории. comment и sarif по умолчанию имеют значение
false; PR из форков по-прежнему получают полную сводку задания, когда
недоступно разрешение на комментирование. См. справочник Action для получения информации обо всех
входных/выходных параметрах, SHA-pinning, загрузке SARIF, разрешениях и поведении безопасности.
sbom-diff: stage: test script: - syft . -o json > current.json - sbomlyze baseline.json current.json --policy policy.json --json > sbom-report.json - sbomlyze baseline.json current.json --format junit > sbom-junit.xml artifacts: paths: - sbom-report.json reports: junit: sbom-junit.xml when: always
### Предупреждение о дрейфе целостности```bash
# Alert on any integrity drift (CI example)
if sbomlyze baseline.json current.json --json | jq -e '.diff.drift_summary.integrity_drift > 0' > /dev/null; then
echo "⚠️ INTEGRITY DRIFT DETECTED - Investigate immediately!"
exit 1
fi
if sbomlyze baseline.json current.json --json | jq -e '.diff.dependencies.depth_summary.depth_3_plus > 0' > /dev/null; then echo "⚠️ New deep transitive dependencies detected - Review required!" fi
### Шлюз соответствия```bash
# Fail the build if the SBOM doesn't meet minimum-element requirements
sbomlyze current.json --policy compliance-policy.json
# where compliance-policy.json sets min_overall_compliance / min_ntia_score / etc.
| Код | Значение |
|---|---|
| 0 | Успех, нет различий или нарушений |
| 1 | Найдены различия (любые добавленные/удалённые/изменённые компоненты), нарушения политик или ошибки |
Примечание: В режиме diff код выхода 1 возвращается при любых обнаруженных изменениях компонентов, даже без файла политик. Это делает его пригодным для использования в качестве простого шлюза «что-то изменилось?» в CI.
syft nginx:1.25-alpine -o json > nginx-125.json syft nginx:1.26-alpine -o json > nginx-126.json
sbomlyze nginx-125.json nginx-126.json
### Аудит лицензий```bash
# Check for GPL licenses in new dependencies
cat > audit-policy.json << EOF
{
"deny_licenses": ["GPL-2.0", "GPL-3.0", "LGPL-2.1", "LGPL-3.0"],
"require_licenses": true
}
EOF
sbomlyze old.json new.json --policy audit-policy.json
cat > no-drift.json << EOF { "max_added": 0, "max_removed": 0, "max_changed": 0 } EOF
sbomlyze baseline.json current.json --policy no-drift.json
### Проверка соответствия```bash
# Score an SBOM and enforce a minimum
sbomlyze image.json --compliance
cat > compliance-policy.json << EOF
{
"min_ntia_score": 90,
"min_overall_compliance": 80
}
EOF
sbomlyze image.json --policy compliance-policy.json
syft alpine:latest -o json > alpine-syft.json sbomlyze convert alpine-syft.json --to cyclonedx -o alpine-cdx.json
sbomlyze convert vendor-sbom.cdx.json --to spdx > vendor-sbom.spdx.json
sbomlyze convert input.json --to spdx | jq '.packages | length'
### Explore SBOM in Browser```bash
# Generate SBOM and explore in web UI
syft alpine:latest -o json > alpine.json
# Start web server
sbomlyze -web
# Then open http://localhost:8080 and drag-drop alpine.json
sbomlyze alpine.json -i
## Разработка
### Запуск тестов```bash
make test
# or
go test -v ./...
make lint # runs go vet + golangci-lint + staticcheck make vulncheck # runs govulncheck for known CVEs
### Сборка```bash
make build-quick
# or
go build -o sbomlyze ./cmd/sbomlyze
make all # Run test, lint, and build make test # Run all tests with race detector make lint # Run go vet, golangci-lint, and staticcheck make vulncheck # Run govulncheck for known vulnerabilities make build # Build with goreleaser (snapshot) make build-quick # Quick build for development make snapshot-test # Run snapshot tests only make update-snapshot # Update snapshot golden files make clean # Remove build artifacts
## Contributing
Вклад приветствуется! Задачи для первого вклада помечены меткой [`good first issue`](https://github.com/rezmoss/sbomlyze/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). Смотрите [CONTRIBUTING.md](https://github.com/rezmoss/sbomlyze/blob/HEAD/CONTRIBUTING.md), если он есть, и смело открывайте issue или обсуждение, чтобы предложить изменения.
[ci]: https://github.com/rezmoss/sbomlyze/actions/workflows/ci.yml
[ci-img]: https://github.com/rezmoss/sbomlyze/actions/workflows/ci.yml/badge.svg
[marketplace]: https://github.com/marketplace/actions/sbomlyze-diff
[marketplace-img]: https://img.shields.io/badge/Marketplace-SBOMlyze%20Diff-blue?logo=github
[release]: https://github.com/rezmoss/sbomlyze/releases
[release-img]: https://img.shields.io/github/v/release/rezmoss/sbomlyze
[go-report]: https://goreportcard.com/report/github.com/rezmoss/sbomlyze
[go-report-img]: https://goreportcard.com/badge/github.com/rezmoss/sbomlyze
[license]: https://raw.githubusercontent.com/rezmoss/sbomlyze/main/LICENSE
[license-img]: https://img.shields.io/badge/License-Apache%202.0-blue.svg
[download]: https://github.com/rezmoss/sbomlyze/releases
[download-img]: https://img.shields.io/github/downloads/rezmoss/sbomlyze/total
[scorecard]: https://scorecard.dev/viewer/?uri=github.com/rezmoss/sbomlyze
[scorecard-img]: https://api.scorecard.dev/projects/github.com/rezmoss/sbomlyze/badge
| Формат | Значение --to | Вывод |
|---|
| CycloneDX 1.5 | cyclonedx or cdx | CycloneDX JSON с метаданными, зависимостями и свойствами |
| SPDX 2.3 | spdx | SPDX JSON с пакетами, связями и внешними ссылками |
| Syft | syft | Syft JSON с артефактами, связями, источником и информацией о дистрибутиве |
| Вывод | Описание |
|---|
| Несоответствие контекста сканирования | Предупреждает, если версия схемы или область сканирования изменились между SBOM |
| Дельта поверхности атаки | Изменения количества пакетов, файлов и связей с процентами |
| Исчезнувшие/новые экосистемы | Типы пакетов, которые полностью появились или исчезли |
| Миграция ОС/дистрибутива | Обнаруживает изменения операционной системы между сканированиями |
| Анализ изменений версий | Подсчитывает обновления и понижения версий, классифицирует изменения как major/minor/patch |
| Понижения версий | Помечает понижения версий как сигнал безопасности с деталями компонентов |
| Контекст отклонений целостности | Разбивает отклонения целостности по типам пакетов с рекомендациями по рискам |
| Доминирующие паттерны путей | Сосредоточенные изменения по типу и пути файловой системы |
| Зоны удаления/добавления | Главные каталоги, затронутые изменениями |
| Стабильные типы | Типы пакетов с идентичным количеством (неизменное ядро) |
| Сдвиги категорий лицензий | Изменения баланса copyleft/пермиссивных лицензий |
| Пробелы каталогизаторов | Сканеры, которые нашли пакеты в Before, но ни одного в After |
| Тип | Индикатор | Описание | Серьёзность |
|---|
| Версия | 📦 | Изменён номер версии | Нормальная |
| Целостность | ⚠️ | Хеш изменён БЕЗ изменения версии | Высокая — требует проверки! |
| Метаданные | 📝 | Изменены только метаданные (лицензии и т. д.) | Низкая |
| Функция | Описание |
|---|
| Загрузка перетаскиванием | Перетащите любой файл SBOM (Syft, CycloneDX, SPDX) на страницу (до 500 МБ) |
| Дерево зависимостей | Интерактивное дерево с навигацией разворачивания/сворачивания (постраничное для >5000 компонентов) |
| Сведения о компонентах | Просмотр лицензий, хэшей, зависимостей, информации о поставщике, количества файлов |
| Просмотр необработанного JSON | JSON с подсветкой синтаксиса для каждого компонента |
| Глубокий поиск | Поиск по всем полям, включая необработанные JSON-данные |
| Панель статистики | Метрики покрытия, категории лицензий, распределение языков |
| Обозреватель файловой системы | Просмотр файлов внутри SBOM с навигацией по каталогам, поиском и фильтрацией по слоям |