Пиков / КАПО
Как читать авторский курс и нормативные материалы

Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.

П02. Чтение CycloneDX JSON руками

Цель

Научиться читать CycloneDX JSON глазами, до всякой автоматизации: найти и назвать назначение пяти верхнеуровневых ключей (bomFormat, specVersion, serialNumber, metadata, components), показать у одного компонента его purl и лицензию, и отличить лицензию-идентификатор от лицензии-выражения. Проверяемый результат — вы можете на чужом bom.json за минуту сказать, сколько в нём компонентов и какой это формат/версия, не запуская ни одного сканера.

Команда или действие

# Сколько компонентов в SBOM — первый ориентир
jq '.components | length' bom.json

# Шапка SBOM: формат, версия спецификации, серийный номер, кто сгенерировал
jq '{bomFormat, specVersion, serialNumber, version, tool: .metadata.tools}' bom.json

# Координаты и лицензии по каждому компоненту
jq '.components[] | {name, version, purl, licenses}' bom.json

Сначала глазами, потом jq jq здесь — не инструмент анализа, а лупа. Цель практики — чтобы вы понимали структуру и без него: открыли файл, увидели "bomFormat": "CycloneDX" и поняли, что это, где искать состав, а где — связи. jq лишь подсвечивает то, что вы уже умеете находить руками.

Что вы должны увидеть

Скелет валидного CycloneDX 1.6 (JSON). Запомните каркас — по нему вы ориентируетесь в любом SBOM:

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
  "version": 1,
  "metadata": {
    "timestamp": "2026-06-17T10:00:00Z",
    "tools": [{ "name": "syft", "version": "1.18.1" }],
    "component": { "type": "application", "name": "sample-app", "version": "0.1.0" }
  },
  "components": [
    {
      "type": "library",
      "bom-ref": "pkg:npm/lodash@4.17.21",
      "name": "lodash",
      "version": "4.17.21",
      "purl": "pkg:npm/lodash@4.17.21",
      "licenses": [ { "license": { "id": "MIT" } } ]
    },
    {
      "type": "library",
      "bom-ref": "pkg:maven/org.springframework/spring-core@6.1.5",
      "name": "spring-core",
      "version": "6.1.5",
      "purl": "pkg:maven/org.springframework/spring-core@6.1.5",
      "licenses": [ { "expression": "Apache-2.0 OR MIT" } ]
    }
  ],
  "dependencies": [
    { "ref": "pkg:npm/lodash@4.17.21", "dependsOn": [] }
  ]
}

jq '.components | length' на таком файле вернёт 2. Ключевое, что нужно разглядеть: лицензия записывается двумя разными способами — как идентификатор ("license": {"id": "MIT"}) и как выражение ("expression": "Apache-2.0 OR MIT"). А dependencies — это отдельный граф: связи задаются ключом bom-ref (syft проставляет его равным purl), а ссылки ref / dependsOn указывают именно на bom-ref, а не на purl. Граф НЕ дублирует список components.

Что именно проговорить вслух «Это CycloneDX 1.6, сгенерирован syft, в нём 2 компонента-библиотеки. У lodash лицензия задана идентификатором SPDX MIT, у spring-core — выражением Apache-2.0 OR MIT. Корень дерева — metadata.component (само приложение), связи лежат в dependencies отдельно от состава.»

Если не получилось

Критерий зачёта

На предоставленном bom.json показать преподавателю: число компонентов (jq '.components | length'), формат и версию спецификации из шапки, и для одного компонента — его purl и лицензию, проговорив, идентификатор это или выражение. Зачёт — если объяснение даётся без подсказок и без запуска сканера.

Нормативная связка

Структура файла задаётся спецификацией CycloneDX ECMA-424; минимальный набор полей, которые в нём обязаны присутствовать, — это CISA Minimum Elements for SBOM и измеримые критерии BSI TR-03183-2 v2.1.0. Чек-лист для приёмки такого файла — Чек-лист качества CycloneDX. Смежные практики: стенд для запуска — П01. Стенд WSL2 Docker и базовая гигиена; как этот файл порождается — П03. Генерация SBOM через Syft; как те же поля превращаются в gate — П34. SBOM quality gate. Модуль: М03. Форматы SBOM: CycloneDX, SPDX, SWID.