Spot the Gaps: AIBOM Lab
An AIBOM can pass its schema and still be wrong. This lab gives you 10 documents to review, from CycloneDX ML-BOMs to Hugging Face dataset cards, each with planted gaps. Flag what is wrong, say who would care, and see the exact field that fixes it.
Who this is for: GRC reviewers who sign off model documentation, AppSec and AI-security engineers who review AIBOMs before a release, SOC analysts who will rely on them in an incident, and CISOs approving an AI model or vendor. Every document describes Northwind Health, a fictional company.
What this lab is
- 10 documents to review: CycloneDX 1.6 ML-BOMs, SPDX 3.0.1 AI and Dataset profile graphs, and Hugging Face model and dataset cards. Together they hide 21 planted gaps among decoys that look wrong but are fine.
- For each document you flag what is wrong and name who would care most: the auditor, the incident responder or the buyer.
- Each answer gives the field that fixes the gap and where the spec defines it, with a link to the AIBOM Library page that explains it.
- Every JSON document in the lab passes its official schema. The gaps are the ones a validator cannot see: a missing base model, a stale version, a metric with no test set, a tool server nobody listed.
- Your debrief scores each persona lens and exports as PDF, CSV or JPG. All documents describe Northwind Health, a fictional company.
The 10 documents
Rookie gives you the first four, Pro the first seven, Elite all ten. Each is labelled with its format and the fictional system it describes. The excerpt is trimmed to the part under review.
- The release ML-BOM (Rookie): CycloneDX 1.6 ML-BOM (JSON) for Triage Assistant v2.3. 2 planted gaps among 6 claims.
- The model card on the internal hub (Rookie): Hugging Face model card (README.md) for Triage Assistant v2.3. 2 planted gaps among 6 claims.
- The training dataset card (Rookie): Hugging Face dataset card (README.md) for support-tickets-2025 (training data for Triage Assistant). 2 planted gaps among 5 claims.
- The ticket router BOM (Rookie): CycloneDX 1.6 ML-BOM (JSON) for Ticket Router v1.4 (a classifier that routes tickets to teams). 2 planted gaps among 5 claims.
- The SPDX 3.0 AI package (Pro): SPDX 3.0.1 AI / Dataset profile (JSON-LD) for Triage Assistant v2.3. 2 planted gaps among 6 claims.
- The runtime BOM (Pro): CycloneDX 1.6 ML-BOM (JSON) for Triage Assistant v2.3 in production. 2 planted gaps among 5 claims.
- The claims letter model card (Pro): Hugging Face model card (README.md) for Claims Letter Drafter v1.1. 2 planted gaps among 5 claims.
- The BOM in the incident ticket (Elite): CycloneDX 1.6 ML-BOM (JSON) for Triage Assistant in production. 2 planted gaps among 5 claims.
- The SPDX dataset package (Elite): SPDX 3.0.1 AI / Dataset profile (JSON-LD) for support-tickets-2025. 3 planted gaps among 6 claims.
- The signed release BOM (Elite): CycloneDX 1.6 ML-BOM (JSON) for Triage Assistant v2.3. 2 planted gaps among 5 claims.
The three lenses
- Auditor (GRC / compliance reviewer): “Can I show where this fact came from, and does the record agree with itself?”
- Incident responder (SOC / incident response): “When something goes wrong, can I tell exactly what was running and what it could reach?”
- Buyer (CISO / procurement approving the model): “Am I allowed to use this, for what, and what risk do I inherit?”
The gap reference
Every kind of gap the lab plants, who it hurts, and the field that closes it in each format. “None” means the format has no place for that fact, so it has to live somewhere else. Field names are as each spec writes them (SPDX in its JSON-LD form).
| Gap | Who cares | CycloneDX 1.6 | SPDX 3.0.1 | Hugging Face card |
|---|---|---|---|---|
| Base model not recorded | Buyer, Incident responder | component.pedigree.ancestors[] | Relationship descendantOf (or ancestorOf) | base_model, base_model_relation |
| Wrong licence on the base model | Buyer | pedigree.ancestors[].licenses[] | hasDeclaredLicense / hasConcludedLicense on the ancestor | license on the base model’s own card |
| No hash for the weights | Incident responder, Auditor | component.hashes[] (alg, content) | verifiedUsing → Hash (algorithm, hashValue) | None (the Hub git commit identifies a revision) |
| Pickle weights with no scan | Incident responder, Buyer | externalReferences[] type static-analysis-report; format in properties[] or mime-type | externalRef type staticAnalysisReport | None |
| Unsigned model, no build provenance | Incident responder, Buyer | externalReferences[] types digital-signature and attestation | No signature property; build_Build for the build, externalRef for the signature bundle | None |
| BOM describes a different version than production | Incident responder, Auditor | component.version, hashes[], metadata.timestamp | software_packageVersion, verifiedUsing, creationInfo.created | None (Hub revision) |
| Model licence missing | Buyer | component.licenses[] | hasDeclaredLicense / hasConcludedLicense | license (+ license_name, license_link for other) |
| Dataset licence unknown or unreconciled | Auditor, Buyer | licenses[] on the data component | hasDeclaredLicense on dataset_DatasetPackage | license on the dataset card |
| Sensitive personal data not stated | Auditor | data[].sensitiveData[], data[].classification | dataset_hasSensitivePersonalInformation, dataset_anonymizationMethodUsed | Dataset card: Personal and Sensitive Information |
| Dataset origin missing | Auditor, Buyer | data[].governance (owners, custodians) | originatedBy (required on dataset_DatasetPackage) | Dataset card: Source Data |
| Dataset size in the wrong unit | Auditor | None | dataset_datasetSize is in bytes | size_categories (record-count bucket) |
| Metric with no test dataset | Auditor, Buyer | modelParameters.datasets[] (no train/test flag); performanceMetrics[] | Relationship testedOn | model-index results[].dataset; Testing Data |
| Out-of-scope use not stated | Buyer, Auditor | No dedicated field (considerations.technicalLimitations[] as a workaround) | ai_limitation (free text) | Uses › Out-of-Scope Use |
| Autonomy contradicts human oversight | Auditor, Buyer | None (considerations.useCases[] text) | ai_autonomyType (yes / no / noAssertion) | Uses › Direct Use (text) |
| Tool server (MCP) not listed | Incident responder, Buyer | services[] (endpoints, authenticated, trustZone, data) | No service element; ai_informationAboutApplication (text) | None |
| Serving framework without a version | Incident responder | component.version, purl | software_packageVersion, software_packageUrl | None |
| Retrieval (RAG) index not listed | Incident responder, Auditor | A data component + dependencies[] | dataset_DatasetPackage + dataset_datasetUpdateMechanism | None |
Why a schema check is not enough
All seven JSON documents in the lab validate against the official CycloneDX 1.6 and SPDX 3.0.1 JSON schemas. They still carry gaps, because most AIBOM fields are optional and a schema cannot know what is deployed. A BOM for version 2.2.0 is valid; it is just not the model that is running. An ai_autonomyType of yes is valid; it just contradicts the human approval step written two lines above it.
Use the AIBOM Validator for the structural checks, then review the content the way this lab trains you to. The AIBOM parameters checklist lists the fields; the AIBOM Format Field Map shows the same field across formats. Worked examples of complete files are in CycloneDX ML-BOM: fields and a worked example and SPDX 3.0 AI and Dataset profiles; for the cards, see model card templates compared and dataset card templates compared.
How scoring works
- 2 points for each planted gap you flag, and 1 more if you name a persona who would care about it.
- Minus 1 for each decoy you flag. A document never scores below zero.
- Your percentage feeds the same S to D grade as every PlayCISO lab, with a small bonus for speed. 75% clears the lab.
- The persona lens shows, for each reader, how many of the gaps they would raise you caught.
The debrief sends you on: missed dataset gaps to the Dataset Card Builder, missed model-card gaps to the Model Card Scorer, and missed field or format issues to the field map. Everything else in the series is on the AIBOM Library hub.
Sources
Every field name was checked against these on 29 October 2026. CycloneDX JSON was validated against bom-1.6.schema.json and SPDX JSON-LD against the SPDX 3.0.1 JSON schema.
- CycloneDX 1.6 JSON reference (component, pedigree, hashes, modelCard, data, services, externalReferences)
- SPDX 3.0.1 AI profile: AIPackage (required fields and AI properties)
- SPDX 3.0.1 Dataset profile: DatasetPackage
- SPDX 3.0.1 RelationshipType (trainedOn, testedOn, descendantOf)
- Hugging Face model card template
- Hugging Face model card metadata spec (base_model, license, model-index)
- Hugging Face dataset card template
- Hugging Face licence identifiers (includes "unknown" and "other")
- Python pickle documentation: security warning
- OpenSSF model signing (sigstore/model-transparency)
Frequently asked questions
How do you review an AIBOM?
Check three things in order. Lineage: is the base model recorded with its licence, is there a hash for the weights, is there a signature and build provenance. Data: does every dataset have a licence, an origin and a statement on personal data, and is every reported metric tied to the dataset it was measured on. Runtime: does the document match what is deployed (version and hash), and does it list the serving stack, the retrieval index and every tool server the model can call. A schema validator checks none of these.
What are the most common gaps in an AIBOM?
In the drills here: the base model missing from pedigree or lineage, no hash or signature for the weights, pickle weights with no scan on record, a dataset licence left as unknown, sensitive personal data not addressed, metrics with no test dataset, a missing out-of-scope section, and runtime pieces (an MCP tool server, a RAG index, an unversioned serving framework) left out. These are examples built for practice, not survey results.
Does a valid CycloneDX or SPDX file mean the AIBOM is complete?
No. Every JSON document in this lab validates against the CycloneDX 1.6 or SPDX 3.0.1 JSON schema and still has gaps. Most AIBOM fields are optional, a schema cannot tell that a version is stale or that two fields contradict each other, and some SPDX rules (such as originatedBy being required on a DatasetPackage) are cardinality constraints in the SPDX model that the JSON schema does not enforce.
Who reads an AIBOM, and what does each reader need?
An auditor needs facts that can be traced to evidence and a record that agrees with itself. An incident responder needs to know exactly what was running and what it could reach: version, hash, serving stack, tools and data sources. A buyer approving a model needs the licence terms, the intended and out-of-scope uses, and the risk it inherits from its base model and data. The lab scores you against each of these lenses.
Are the documents in the lab real?
No. Every document describes Northwind Health, a fictional company used across the PlayCISO AIBOM Library. Hashes, URLs, datasets and metric values are made up. The base models named (Mistral-7B-Instruct-v0.3, distilbert-base-uncased) are real public models; the fine-tunes of them are not.
How is this different from the AIBOM Validator?
The AIBOM Validator checks a CycloneDX file you paste in: is it valid, are models and datasets inventoried, does every component have a licence. This lab trains the judgement a validator does not have: reading a document against what is actually deployed and spotting what is missing or contradictory.
More free security tools
The tools people use most on PlayCISO.
Catch injected instructions hiding in content your AI agent should only read.
Score your readiness against the first international standard for AI security threats.
Critical CVEs across 21 major vendors, month by month — and what the 2026 surge means.
Build an ordered ruleset, replay labelled packets and catch shadowed and any-to-any rules.
Self-assess all six Functions, from Govern to Recover, and see your weakest one.
Search 172 threat actors across Microsoft, CrowdStrike, Mandiant and community names.