Как читать авторский курс и нормативные материалы
Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.
Конспект: форматы SBOM — CycloneDX, SPDX, SWID
Зачем модуль
Заголовок «CycloneDX, SPDX, SWID» провоцирует ошибку: считать это тремя взаимозаменяемыми форматами SBOM и выбирать «по вкусу». На практике задачи у них разные. CycloneDX вырос из AppSec-сообщества OWASP и заточен под безопасность и обмен данными об уязвимостях. SPDX вырос из Linux Foundation и исторически заточен под лицензионный комплаенс. SWID (ISO/IEC 19770-2) вообще не контейнер для SBOM — это тег идентификации установленного продукта, который в SBOM играет роль одного из ключей компонента. Если этого не различать, легко принять решение «генерируем SWID-теги» и обнаружить, что ни один регулятор не примет это как SBOM.
Ключевые идеи
1. Что считается форматом SBOM по BSI. BSI TR-03183-2 v2.1.0 (раздел 4) допускает только два формата: CycloneDX версии 1.6 и выше и SPDX версии 3.0.1 и выше, в JSON или XML. SWID в стандарте упоминается лишь как тип значения поля «Other unique identifiers». То есть SWID-тег живёт внутри компонента CycloneDX/SPDX, а не заменяет SBOM.
2. Назначение и сильные стороны. CycloneDX компактен, имеет нативные блоки vulnerabilities, compositions, поддержку VEX и подпись через signature; его сериализуют в JSON, XML и Protobuf, и он удобен для портфельных инструментов (например, Dependency-Track принимает именно CycloneDX). SPDX 3.0 — это граф элементов и связей (Relationship с relationshipType вроде contains, dependsOn, hasDeclaredLicense), он точнее описывает происхождение, разделяет пакеты и файлы и сильнее в лицензионном комплаенсе; сериализуется в JSON, XML, RDF, YAML. SWID отвечает на вопрос «что установлено на машине», это XML-тег продукта по ISO/IEC 19770-2, и он хорошо ложится на инвентаризацию активов, но не описывает дерево зависимостей. Выбор формата — это выбор задачи: безопасность и обмен — CycloneDX, лицензии и provenance — SPDX, инвентарь активов — SWID как идентификатор.
3. Три категории лицензий BSI. Стандарт намеренно вводит свои термины поверх форматных: original licence (что назначил автор), distribution licence (под чем компонент можно использовать получателю) и effective licence (под чем его использует создатель данного SBOM). В CycloneDX это licenses[].acknowledgement со значениями declared / concluded плюс свойство bsi:component:effectiveLicense; в SPDX — отношения hasDeclaredLicense / hasConcludedLicense. См. М07 Лицензионная чистота и юридический workflow.
4. Машиночитаемость и потери при конвертации. Структуры форматов не изоморфны: SPDX разделяет software_Package и software_File и связывает их через Relationship, CycloneDX использует единый component с полем type и отдельный блок dependencies. Из-за этого одно и то же утверждение «файл X входит в пакет Y» кодируется по-разному, а часть полей BSI ни один формат не имеет нативно — executable / archive / structured property приходится кодировать через property-taxonomy bsi:component:* (CycloneDX) или software_additionalPurpose (SPDX). Поэтому автоматическая конвертация CycloneDX↔SPDX почти всегда теряет данные: чаще всего исчезают hash deployable-компонента, различие declared/concluded и пользовательские свойства. Отдельно BSI требует не смешивать в одном файле SBOM и информацию об уязвимостях: SBOM статичен, а уязвимости динамичны, и их распространение внутри SBOM засоряет всю цепочку поставки — для уязвимостей предусмотрен CSAF/VEX (см. М06 Поиск уязвимостей и управление VDR VEX).
Как выглядит на практике
Один и тот же компонент в трёх «языках» (для SWID — как идентификатор, а не как SBOM):
// CycloneDX 1.6 — компонент
{ "type": "library", "name": "zlib", "version": "1.3.1",
"purl": "pkg:generic/zlib@1.3.1",
"swid": { "tagId": "zlib-1.3.1", "name": "zlib" },
"licenses": [{ "expression": "Zlib", "acknowledgement": "concluded" }],
"hashes": [{ "alg": "SHA-512", "content": "..." }] }
// SPDX 3.0.1 — пакет + идентификатор SWID
{ "type": "software_Package", "name": "zlib",
"software_packageVersion": "1.3.1",
"externalIdentifiers": [
{ "externalIdentifierType": "packageURL", "identifier": "pkg:generic/zlib@1.3.1" },
{ "externalIdentifierType": "swid", "identifier": "zlib-1.3.1" } ] }
| Критерий | CycloneDX 1.6+ | SPDX 3.0.1+ | SWID (19770-2) |
|---|---|---|---|
| Это формат SBOM по BSI | да | да | нет (только идентификатор) |
| Профиль задачи | безопасность, VEX | лицензии, provenance | инвентаризация активов |
| Модель | один component + type |
граф Package/File + Relationship |
XML-тег продукта |
| Уязвимости нативно | да (vulnerabilities) |
нет | нет |
| Сериализация | JSON, XML, Protobuf | JSON, XML, RDF, YAML | XML |
Слепые зоны именно этой темы - «Сгенерировали SWID — значит, есть SBOM» — нет, SWID не SBOM по BSI. - SBOM в CycloneDX 1.4/1.5 или SPDX 2.x формально не проходит BSI v2.1.0 (нужны 1.6 / 3.0.1). - Поля executable/archive/structured нет в форматах — без
bsi:component:*SBOM «формально валиден, но не полон по BSI». - Конвертация «на автомате» теряет различие declared/concluded/effective licence.
Связь с нормативкой
BSI TR-03183-2 v2.1.0 (разделы 4, 5.2, 6.1, 8.2) — версии, обязательные поля, лицензии, маппинг. CycloneDX ECMA-424 и SPDX ISO IEC 5962 — сами спецификации. CISA Minimum Elements for SBOM и NTIA Minimum Elements for SBOM — минимальный набор для рынка США; EU Cyber Resilience Act делает SBOM обязательным.
Что уносим в работу
- Закрепить в Организации, что «SBOM» = CycloneDX ≥ 1.6 или SPDX ≥ 3.0.1 (см. Соглашение о качестве данных SBOM).
- Выбирать формат по задаче, а не по привычке инструмента; SWID использовать только как идентификатор.
- Проверять обязательные поля компонента по BSI (раздел 5.2.2) — П02. Чтение CycloneDX JSON руками, П34. SBOM quality gate.
- Не смешивать SBOM и уязвимости в одном файле.
Практики: П02. Чтение CycloneDX JSON руками · П03. Генерация SBOM через Syft · П34. SBOM quality gate · П24. PURL нормализация и private qualifiers.