CtrlK
BlogDocsLog inGet started
Tessl Logo
PluginPublic

testland/syft-generation

Use when a team needs SBOMs for compliance (US EO 14028, EU CRA, FDA), SBOM-based vulnerability scanning or drift checks between releases. Generates CycloneDX or SPDX SBOMs with Syft from images or folders, scans them with Grype, diffs SBOMs in CI and explains how to choose a format.

Quality

90%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

spdx.mdreferences/

SPDX - Software Package Data Exchange (format reference)

Companion reference for sbom-formats.md. Consult when the SBOM consumer requires SPDX (US Federal procurement, Linux Foundation members, license-compliance focus); the SKILL.md covers CycloneDX and the format-choice guidance.

SPDX is the Linux Foundation's SBOM standard, originally focused on license compliance. Per spdx.org/specifications:

Two active major versions:

VersionStatusNotable
SPDX 2.3Stable; broadly tooledTag-Value / JSON / YAML / RDF / Spreadsheet; ISO/IEC 5962:2021
SPDX 3.0Recent (2024); growing toolingProfile-based: core + software + AI + dataset + build + security; JSON-LD primary

When SPDX is the right format

  • US Federal procurement context (NIST SP 800-218 + EO 14028 guidance favor SPDX).
  • Linux Foundation member organization workflow.
  • License-compliance focused use case (SPDX has the richest license-expression vocabulary).
  • A consumer (regulator, customer) requires SPDX format specifically.

SPDX 2.3 top-level structure (JSON)

{
  "spdxVersion": "SPDX-2.3",
  "dataLicense": "CC0-1.0",
  "SPDXID": "SPDXRef-DOCUMENT",
  "name": "my-app-1.0.0-sbom",
  "documentNamespace": "https://example.com/spdx/my-app/1.0.0",
  "creationInfo": {
    "created": "2026-05-06T12:00:00Z",
    "creators": ["Tool: syft-1.16.0", "Organization: Acme Corp"]
  },
  "packages": [
    {
      "SPDXID": "SPDXRef-Package-myapp",
      "name": "my-app",
      "versionInfo": "1.0.0",
      "downloadLocation": "NOASSERTION",
      "filesAnalyzed": false,
      "licenseConcluded": "Apache-2.0",
      "licenseDeclared": "Apache-2.0"
    },
    {
      "SPDXID": "SPDXRef-Package-lodash",
      "name": "lodash",
      "versionInfo": "4.17.20",
      "downloadLocation": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
      "filesAnalyzed": false,
      "licenseConcluded": "MIT",
      "licenseDeclared": "MIT"
    }
  ],
  "relationships": [
    {
      "spdxElementId": "SPDXRef-DOCUMENT",
      "relationshipType": "DESCRIBES",
      "relatedSpdxElement": "SPDXRef-Package-myapp"
    },
    {
      "spdxElementId": "SPDXRef-Package-myapp",
      "relationshipType": "DEPENDS_ON",
      "relatedSpdxElement": "SPDXRef-Package-lodash"
    }
  ]
}

Required fields per SPDX 2.3

Per spdx-spec:

FieldRequired?Use
spdxVersionyesMust be "SPDX-2.3"
dataLicenseyes"CC0-1.0" (CC0 - the SBOM data itself)
SPDXIDyes"SPDXRef-DOCUMENT"
nameyesHuman-readable doc name
documentNamespaceyesUnique URI per BOM revision
creationInfo.createdyesISO 8601 timestamp
creationInfo.creatorsyesTool / org / person who created
packages[]required for non-empty BOMInventory
relationships[]required (at least DESCRIBES)Dep graph

License expressions

SPDX is the canonical source for license identifiers (cross-format standard - even CycloneDX uses SPDX license IDs).

"licenseConcluded": "Apache-2.0",
"licenseConcluded": "MIT OR Apache-2.0",
"licenseConcluded": "(MIT AND BSD-3-Clause) OR GPL-2.0-only WITH Classpath-exception-2.0"

Full list: spdx.org/licenses (current count ~600+).

The LicenseRef- prefix declares custom licenses:

"hasExtractedLicensingInfos": [{
  "licenseId": "LicenseRef-AcmeProprietary",
  "extractedText": "Acme Proprietary License Text..."
}],
"licenseConcluded": "LicenseRef-AcmeProprietary"

Relationships

The relationships[] block is the dep-graph (SPDX equivalent of CycloneDX's dependencies[]):

RelationshipTypeUse
DESCRIBES / DESCRIBED_BYDocument to top-level package
DEPENDS_ON / DEPENDENCY_OFCompile-time / runtime dep
BUILD_DEPENDENCY_OFBuild-only dep
DEV_DEPENDENCY_OFTest/dev-only dep
RUNTIME_DEPENDENCY_OFRuntime-only dep
OPTIONAL_DEPENDENCY_OFOptional dep
CONTAINS / CONTAINED_BYContainer to contained file/package
GENERATED_FROMSource-of-build
STATIC_LINK / DYNAMIC_LINKLinkage type

Tag-Value format (SPDX-native)

Some toolchains use the SPDX Tag-Value format (older but well-tooled):

SPDXVersion: SPDX-2.3
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: my-app-1.0.0-sbom
DocumentNamespace: https://example.com/spdx/my-app/1.0.0
Creator: Tool: syft-1.16.0
Creator: Organization: Acme Corp
Created: 2026-05-06T12:00:00Z

PackageName: my-app
SPDXID: SPDXRef-Package-myapp
PackageVersion: 1.0.0
PackageDownloadLocation: NOASSERTION
FilesAnalyzed: false
PackageLicenseConcluded: Apache-2.0
PackageLicenseDeclared: Apache-2.0

Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-myapp

JSON is preferred for new toolchains; Tag-Value persists for legacy integrations.

SPDX 3.0 profiles and the SPDX tooling landscape are cataloged in spdx3-profiles-and-tooling.md; for most teams, stay on SPDX 2.3 unless 3.0 features are required.

Validation

# Python spdx-tools
pip install spdx-tools
pyspdxtools --infile sbom.spdx.json --version SPDX-2.3
# Validates structural conformance + license-expression syntax

# Validation via spdx online tool
# Upload to https://tools.spdx.org/app/

CI integration

jobs:
  spdx:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: anchore/sbom-action@v0
        with:
          format: spdx-json
          output-file: sbom.spdx.json
      - run: |
          pip install spdx-tools
          pyspdxtools --infile sbom.spdx.json --version SPDX-2.3
      - uses: actions/upload-artifact@v4
        with:
          name: spdx-sbom
          path: sbom.spdx.json

Worked example

A team must deliver an SPDX 2.3 SBOM to a US Federal procurement consumer for an app that bundles one proprietary component:

  1. Generates via Syft in CI: anchore/sbom-action with format: spdx-json, producing sbom.spdx.json with spdxVersion: "SPDX-2.3", dataLicense: "CC0-1.0", and a unique documentNamespace.
  2. The app package uses a non-standard license, so the team declares it via hasExtractedLicensingInfos and sets licenseConcluded: "LicenseRef-AcmeProprietary"; every third-party package keeps its standard SPDX ID (MIT, etc.).
  3. Adds relationships[]: SPDXRef-DOCUMENT DESCRIBES the app package, and the app DEPENDS_ON each dependency.
  4. Validates: pyspdxtools --infile sbom.spdx.json --version SPDX-2.3 - structural + license-expression checks pass.

Result: a validated SPDX 2.3 JSON SBOM whose custom license resolves cleanly and whose relationship graph satisfies the federal consumer's format requirement.

SPDX anti-patterns

Anti-patternWhy it failsFix
Skip documentNamespaceCan't deduplicate across BOM revisionsGenerate unique URI per BOM
Use SPDX 3.0 with consumer expecting 2.3Tooling incompatStick to SPDX 2.3 unless 3.0 required
Manual license assignment without LicenseRef- for customLicense-expression validation failsUse proper SPDX license ID or LicenseRef-
Skip relationships[] (just packages)No dep-graph; downstream tools degradeAlways include DESCRIBES + DEPENDS_ON
Mix Tag-Value + JSON in same workflowToolchain confusionPick one format per workflow

SPDX limitations

  • SPDX 2.3 vuln support is weaker than CycloneDX 1.6 (no first-class vulnerabilities block - relies on companion VEX docs).
  • License-expression validation is strict; non-standard licenses require LicenseRef- boilerplate.
  • SPDX 3.0 tooling is still maturing; many tools still produce 2.3.
  • Tag-Value parsing is whitespace-sensitive; subtle formatting bugs.

Sources

  • spdx-spec - official specification
  • spdx3-profiles-and-tooling.md - SPDX 3.0 profiles + tooling landscape
  • spdx.dev - landing
  • spdx.org/licenses - license ID list
  • iso.org/standard/81870.html - ISO/IEC 5962:2021 (SPDX 2.2.1 ISO publication)
  • tools.spdx.org - online validator
  • github.com/spdx/tools-python - Python reference impl

SKILL.md

tile.json