Skip to content
All posts
Seriesaibom-library

SPDX 3.0 AI and Dataset Profiles, With Example

October 29, 2026 · PlayCISO
TL;DR

SPDX 3.0 describes an AI model as an AIPackage (AI profile) and each dataset as a DatasetPackage (Dataset profile), serialised as JSON-LD in one @graph and linked by Relationship elements: trainedOn and testedOn from the model to its data, descendantOf to the base model, dependsOn for run-time parts. The current version is 3.0.1. This guide explains every AI and Dataset property against one schema- and SHACL-valid example for a fictional support assistant, shows the gaps you hit (no service class, no signature reference type, dataset size in bytes), and says when to choose SPDX over CycloneDX.

Put it into practice
Download the complete SPDX 3.0.1 AIBOM
The full Northwind JSON-LD file, valid against the SPDX 3.0.1 schema and SHACL shapes, plus a form that regenerates it with your own model and datasets. Pro.
Open the Template Library

SPDX 3.0 describes an AI model as an AIPackage from the AI profile and each dataset as a DatasetPackage from the Dataset profile. Both are software packages, so they carry the usual name, version, supplier and download location. They are joined by separate Relationship elements: trainedOn and testedOn from the model to its data, descendantOf to the base model. The current version is 3.0.1.

Who this is for: AppSec engineers whose SBOM pipeline already speaks SPDX and now has to cover models, and GRC teams who receive SPDX files as evidence and need to know what each AI field claims. For the general idea, start with what an AIBOM is; for a format-neutral field list, see the AIBOM parameters checklist.

Fictional example. Northwind Health, Triage Assistant and its datasets, services, scores and URLs are invented for illustration; the base model and open-source libraries are real.

How an SPDX 3.0 AIBOM is laid out

An SPDX 3.0 file in JSON-LD is one @context and one flat @graph of elements. Five things to know before reading one:

  • Everything is an element with an spdxId, a URI. Northwind uses https://northwind-health.example/spdx/triage-assistant-2.3.0#….
  • One shared CreationInfo says who produced the data and when (spec version 3.0.1). Every element points at it.
  • Profiles are declared. The SpdxDocument lists profileConformance: core, software, ai, dataset and simpleLicensing for Northwind.
  • Property names carry the profile as a prefix in JSON-LD: ai_limitation, dataset_datasetType, software_packageVersion. Core properties such as name have none.
  • Links are elements too. “The model was trained on this dataset” is a Relationship node with from, relationshipType and to, not a field inside the model. Licences work the same way, through hasDeclaredLicense.

If you know SPDX 2.x, note that 3.0 is a new model, not an extension of 2.x documents. Tools written for 2.x will not read it.

AIPackage: the AI profile

An AIPackage must have the six package properties in the first rows. Every ai_ property is optional. Cardinality is from the SPDX 3.0.1 class page.

PropertyCardinalityWhat it recordsNorthwind
name, software_packageVersion1 eachModel identitynorthwind/triage-assistant, 2.3.0
software_downloadLocation1Where the weights areInternal model store URL
software_primaryPurpose1What kind of package this ismodel
suppliedBy, releaseTime1 eachAccountable supplier and release dateNorthwind Health, 2026-02-16
ai_typeOfModel0..*Free-text model typedecoder-only transformer (causal language model)
ai_domain0..*Where the model is meant to be usedcustomer support
ai_informationAboutTraining0..1How it was trained, in wordsLoRA fine-tune on the ticket dataset
ai_informationAboutApplication0..1Intended applicationDrafts for human approval
ai_limitation0..1Known limits and out-of-scope uses, as one stringMedical advice; sending without approval
ai_metric, ai_metricDecisionThreshold0..* eachMetric results, and thresholds, as key/value DictionaryEntry pairsanswer-accuracy 0.87; toxicity-rate 0.002 (fictional). No thresholds.
ai_hyperparameter0..*Training settings as key/value pairsfinetuning_method = LoRA; task
ai_modelDataPreprocessing0..*Data preparation before trainingDe-identification
ai_autonomyType0..1Whether it acts without a human in the loop: yes, no, noAssertionno
ai_safetyRiskAssessment0..1Self-assessed risk: serious, high, medium, lowmedium
ai_useSensitivePersonalInformation0..1Whether sensitive personal data was usedno
ai_modelExplainability, ai_standardCompliance, ai_energyConsumption0..* / 0..* / 0..1Explainability notes, standards complied with, energy used in training, fine-tuning and inferenceNot recorded

Two of these are judgements, not facts. ai_safetyRiskAssessment is the supplier’s own rating on a four-level scale, and ai_useSensitivePersonalInformation is the supplier’s claim after its own de-identification. Read both as claims to test.

DatasetPackage: the Dataset profile

A DatasetPackage must have at least one dataset_datasetType, plus builtTime, releaseTime, originatedBy, a download location and a primary purpose (data).

PropertyCardinalityWhat it recordsNorthwind training set
dataset_datasetType1..*text, image, audio, structured and ten moretext
builtTime, releaseTime, originatedBy1 each (originatedBy at most 1)When the data was built and released, and who created it2025-12-31, 2026-01-20, Northwind Health
dataset_dataCollectionProcess0..1How the data was collectedExport from the ticketing system
dataset_dataPreprocessing0..*Steps between raw data and training dataDropped no-reply tickets; de-identified
dataset_anonymizationMethodUsed0..*How identifiers were removedNER plus pattern rules, sample review
dataset_hasSensitivePersonalInformation0..1yes, no, noAssertionno
dataset_confidentialityLevel0..1Traffic Light Protocol style: clear, green, amber, redamber
dataset_intendedUse, dataset_knownBias0..1 / 0..*What the data is for, and known biasesFine-tuning the model; written channels only
dataset_datasetUpdateMechanism0..1How the data is updatedNone: static 2025 snapshot
dataset_datasetSize0..1Size in bytes (not records)Left out; record count is in the description
dataset_datasetAvailability, dataset_datasetNoise, dataset_sensor0..1 / 0..1 / 0..*How it can be obtained, known noise, sensors usedNot recorded (internal text data)

Relationships that make it an AIBOM

  • describes: the SBOM element describes the application.
  • dependsOn: the application depends on the model, vLLM 0.6.3, the RAG index and the MCP server; vLLM depends on its libraries.
  • descendantOf: the fine-tune is a descendant of mistralai/Mistral-7B-Instruct-v0.3.
  • trainedOn and testedOn: the model was trained on northwind/support-tickets-2025 and tested on northwind/triage-eval-v4. The direction is always from the model to the data.
  • hasDeclaredLicense: each package to a simplelicensing_LicenseExpression element. The base model gets Apache-2.0; Northwind’s own model and data get a LicenseRef- identifier mapped to a licence URL.

The Northwind field table

FieldNorthwind valueWhat it tells you
@contexthttps://spdx.org/rdf/3.0.1/spdx-context.jsonldDeclares SPDX 3.0.1 JSON-LD. Every node lives in one @graph.
CreationInfo (specVersion, created, createdBy)3.0.1, 2026-02-16T09:00:00Z, Northwind HealthWho produced the SPDX data and when. Shared by every element.
SpdxDocument.profileConformancecore, software, ai, dataset, simpleLicensingWhich SPDX profiles the document uses. "ai" and "dataset" are the AIBOM parts.
software_Sbom.software_sbomTypebuildGenerated at build time.
ai_AIPackage name / software_packageVersionnorthwind/triage-assistant / 2.3.0Model identity. AIPackage requires name, version, download location, supplier, release time and primary purpose.
software_primaryPurposemodelSays this package is a model (datasets use "data").
suppliedBy / releaseTimeNorthwind Health / 2026-02-16T09:00:00ZAccountable supplier and release date.
verifiedUsing (Hash sha256)3bad18cc9805… (placeholder)Integrity check of the weights file.
ai_typeOfModel / ai_domaindecoder-only transformer / customer supportFree-text model type and the domain it is meant for.
ai_informationAboutTrainingLoRA fine-tune on northwind/support-tickets-2025How the model was trained, in words.
ai_informationAboutApplicationDraft replies to customer support tickets for a human support agent to review, edit and approve before sending.Intended application.
ai_limitationMedical advice or clinical triage of symptoms; Sending any reply to a customer without human approvalKnown limitations and out-of-scope uses. One string in SPDX 3.0.1.
ai_metric (DictionaryEntry)answer-accuracy 0.87; toxicity-rate 0.002 (fictional)Metric name and value as key/value pairs.
ai_hyperparameterfinetuning_method = LoRA; task = text-generationTraining settings worth recording.
ai_autonomyTypenoNo: a human approves every output before it has effect.
ai_safetyRiskAssessmentmediumNorthwind Health's own risk rating on SPDX's four-level scale (serious, high, medium, low). Fictional.
ai_useSensitivePersonalInformationnoPublisher asserts no sensitive personal data was used in training, after de-identification.
dataset_DatasetPackage (training)northwind/support-tickets-2025, datasetType text, confidentialityLevel amberThe training data as its own element. datasetType is the one Dataset-profile field that is required.
dataset_anonymizationMethodUsed / dataset_hasSensitivePersonalInformationNER plus pattern rules, sample review / noHow identifiers were removed, and the resulting claim. De-identified is not the same as anonymous.
dataset_datasetSize(omitted)Size in bytes, not records. The record count (48,210) goes in the description.
Relationship descendantOftriage-assistant → mistralai/Mistral-7B-Instruct-v0.3Lineage to the base model.
Relationship trainedOn / testedOnnorthwind/support-tickets-2025 / northwind/triage-eval-v4Which data trained the model and which tested it.
Relationship dependsOnTriage Assistant → model, vllm 0.6.3, northwind-helpcentre-index, ticketing-mcpRun-time dependencies. SPDX 3.0.1 has no service class, so the RAG index is a dataset and the MCP server a package.
Relationship hasDeclaredLicenseApache-2.0 (base model); LicenseRef proprietary (model, data)Licences, as simplelicensing_LicenseExpression elements.
externalRef (model)documentation (model card); other: Sigstore bundle; other: in-toto provenanceLinks to the signature and provenance. SPDX 3.0.1 has no dedicated signature or SLSA ref type, so these use "other" with a contentType.

The example file, excerpted

The model with its signature link, the training dataset, and the two relationships that say where the model came from and what it learned from.

{
  "@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
  "@graph": [
    {
      "type": "ai_AIPackage",
      "spdxId": "https://northwind-health.example/spdx/triage-assistant-2.3.0#model",
      "name": "northwind/triage-assistant",
      "software_packageVersion": "2.3.0",
      "software_primaryPurpose": "model",
      "suppliedBy": "https://northwind-health.example/spdx/triage-assistant-2.3.0#org-northwind-health",
      "releaseTime": "2026-02-16T09:00:00Z",
      "ai_typeOfModel": ["decoder-only transformer (causal language model)"],
      "ai_limitation": "Out of scope: Medical advice or clinical triage of symptoms; Sending any reply to a customer without human approval.",
      "ai_autonomyType": "no",
      "ai_safetyRiskAssessment": "medium",
      "ai_useSensitivePersonalInformation": "no",
      "externalRef": [
        {
          "type": "ExternalRef",
          "externalRefType": "other",
          "locator": [
            "https://models.northwind-health.example/northwind/triage-assistant/2.3.0/model.sig"
          ],
          "contentType": "application/vnd.dev.sigstore.bundle.v0.3+json",
          "comment": "Sigstore model signature (OpenSSF model signing), produced in CI."
        }
      ]
    },
    {
      "type": "dataset_DatasetPackage",
      "spdxId": "https://northwind-health.example/spdx/triage-assistant-2.3.0#dataset-support-tickets-2025",
      "name": "northwind/support-tickets-2025",
      "builtTime": "2025-12-31T23:59:59Z",
      "originatedBy": [
        "https://northwind-health.example/spdx/triage-assistant-2.3.0#org-northwind-health"
      ],
      "dataset_datasetType": ["text"],
      "dataset_anonymizationMethodUsed": [
        "Named-entity detection plus pattern rules to remove names, email addresses, phone numbers, postal addresses and account or member numbers; manual review of a sample."
      ],
      "dataset_confidentialityLevel": "amber",
      "dataset_hasSensitivePersonalInformation": "no"
    },
    {
      "type": "Relationship",
      "from": "https://northwind-health.example/spdx/triage-assistant-2.3.0#model",
      "relationshipType": "descendantOf",
      "to": ["https://northwind-health.example/spdx/triage-assistant-2.3.0#base-model"]
    },
    {
      "type": "Relationship",
      "from": "https://northwind-health.example/spdx/triage-assistant-2.3.0#model",
      "relationshipType": "trainedOn",
      "to": [
        "https://northwind-health.example/spdx/triage-assistant-2.3.0#dataset-support-tickets-2025"
      ]
    }
  ]
}

Excerpt, 59 lines: the AIPackage (metrics and two of its three external references left out), the training DatasetPackage, and the descendantOf and trainedOn relationships. Keys and list entries not shown are left out; every value shown is exactly as in the full file, which runs to 608 lines pretty-printed.

The complete file, with the application, the base model, the evaluation set, the RAG index, the MCP server, the libraries, the licences and every relationship, is in the AIBOM Template Library (Pro).

Gaps we hit, and what we did

Building the Northwind file in SPDX 3.0.1 ran into five places where the model has no field for something an AI system needs. None makes the file invalid. All of them push facts into free text.

GapWhyWhat the Northwind file does
No service classCycloneDX has services for things called at run time. SPDX 3.0.1 does not.The RAG index is a dataset_DatasetPackage with software_primaryPurpose: data and a weekly update mechanism; the MCP server is a software_Package with primaryPurpose: application. Authentication, trust boundary and tool permissions go into the description, where tools cannot query them.
No reference type for a model signature or SLSA provenanceExternalRefType has 46 values but none for a signature bundle or build provenance. secureSoftwareAttestation exists, but it means an SSDF or CISA secure-development attestation form.Both links use externalRefType: other with a contentType: application/vnd.dev.sigstore.bundle.v0.3+json for the signature and application/vnd.in-toto+json for the provenance, plus a comment.
datasetSize is bytesThe spec says the size “is to be measured in bytes”. Writing 48210 there would claim a 48 KB dataset.dataset_datasetSize is left out; “48,210 de-identified support tickets” goes in the description.
ai_limitation holds one stringMaximum cardinality is 1.The two out-of-scope uses are joined into one sentence.
Metrics have no sliceai_metric is a key/value pair; there is no slot for the dataset a metric was measured on.The dataset goes into the key (answer-accuracy (northwind/triage-eval-v4)), and a testedOn relationship links the model to the evaluation set.

SPDX or CycloneDX?

Neither is better in general. Pick by what you need to express and who reads it.

If…ChooseWhy
Your SBOM pipeline and your customers already use SPDXSPDXThe AIBOM should come out of the same pipeline as the SBOM.
You need to show RAG indexes, tool servers and trust boundariesCycloneDXCycloneDX has services with endpoints, authentication, trust boundary and data flows. SPDX 3.0.1 has no service class.
Dataset facts matter most (anonymisation, confidentiality, bias, collection)SPDXThe Dataset profile has named fields for these. CycloneDX data components have classification and sensitive-data notes only.
You want a structured model card inside the BOMCycloneDXmodelCard has separate lists for use cases, limitations, trade-offs, ethical, environmental and fairness considerations. SPDX has free-text strings.
Licence compliance is the main useSPDXLicence expressions are first-class elements, linked by hasDeclaredLicense.
You need autonomy, safety-risk or energy fieldsSPDXautonomyType, safetyRiskAssessment and energyConsumption have no direct CycloneDX equivalent.
You want PlayCISO’s validator and diffCycloneDXThe AIBOM Validator and AIBOM Diff read CycloneDX.

The CycloneDX ML-BOM guide uses the same Northwind system, so you can compare the two files field by field. The AIBOM Format Field Map (Pro) does that comparison for every field. For how the three bill-of-materials ideas differ, see SBOM vs AIBOM vs MLBOM.

How to validate it

  1. Structure: the official SPDX 3.0.1 JSON schema checks that the JSON-LD has the right shape.
  2. Meaning: the SHACL shapes in the SPDX model file (spdx-model.ttl) check required properties, cardinalities and enumerated values, for example with pySHACL. This is what catches a DatasetPackage without a datasetType.
  3. Both at once: the community tool spdx3-validate runs the schema and SHACL checks together, with some extra checks for documents that reference each other.

The Northwind file passes the official SPDX 3.0.1 JSON schema and the SHACL shapes (checked with pySHACL). As with any format, valid only means well-formed. The facts inside, such as the de-identification claim, still need evidence.

Where to go next

This guide is part of the AIBOM Library. The same Northwind system in the other formats: CycloneDX ML-BOM and Croissant RAI. To choose between formats, start with AIBOM standards and templates compared; to see one field across every format, use the AIBOM Format Field Map (Pro).

Frequently asked questions

What is the SPDX AI profile?

The part of SPDX 3.0 that describes AI models. It adds the AIPackage class, a software package with properties such as typeOfModel, informationAboutTraining, informationAboutApplication, limitation, metric, hyperparameter, autonomyType, safetyRiskAssessment, useSensitivePersonalInformation and energyConsumption. The Dataset profile adds DatasetPackage for training and test data.

What fields does an SPDX AIPackage require?

In SPDX 3.0.1 every AIPackage needs a name, packageVersion, downloadLocation, primaryPurpose, suppliedBy and releaseTime, plus the spdxId and creationInfo every element has. All the ai_ properties are optional. A DatasetPackage needs datasetType, builtTime, releaseTime, originatedBy, downloadLocation and primaryPurpose.

How do you link a model to its training data in SPDX 3.0?

With Relationship elements. A relationship from the model to a dataset with relationshipType trainedOn says the model was trained on it; testedOn says it was tested on it; descendantOf from the fine-tune to the base model records lineage. Relationships are separate nodes in the @graph, not properties nested inside the model.

Can SPDX 3.0 describe a RAG pipeline or an MCP server?

Only partly. SPDX 3.0.1 has no class for a service called at run time. You can model a retrieval index as a DatasetPackage and a tool server as a software Package, linked with dependsOn, but authentication, trust boundaries and tool permissions end up in free text. CycloneDX services hold them as fields.

Is SPDX 3.0 an ISO standard?

No. ISO/IEC 5962:2021 is SPDX 2.2.1. The AI and Dataset profiles are new in SPDX 3.0, so they are not part of that ISO text. The current SPDX version is 3.0.1; SPDX 3.1 was at release-candidate stage in October 2026.

Should I use SPDX or CycloneDX for an AIBOM?

Use the format your SBOM pipeline and your customers already use. Choose CycloneDX if you need run-time services with trust boundaries or a structured model card. Choose SPDX if your focus is licence compliance or detailed dataset facts such as anonymisation method and confidentiality level. You can produce both from one source.

Sources

Checked on 29 October 2026. PlayCISO is not affiliated with OWASP, Ecma, the Linux Foundation or MLCommons. This is general information, not legal advice.

Download the complete SPDX 3.0.1 AIBOM
The full Northwind JSON-LD file, valid against the SPDX 3.0.1 schema and SHACL shapes, plus a form that regenerates it with your own model and datasets. Pro.
Open the Template Library

Ready to practise the decisions these articles describe?

Run your first War Room free →

One run free with a free account · more runs with Pro

🎉 New here? Use code WELCOME10 for 10% off any plan at checkout