Skip to content
All posts
Seriesaibom-library

Croissant RAI: Dataset Metadata With an Example

October 29, 2026 · PlayCISO
TL;DR

Croissant is MLCommons’ JSON-LD format for machine-learning datasets: schema.org Dataset metadata, the files (distribution) and the record structure (recordSet and field). Croissant RAI 1.0 adds rai: properties for collection, preprocessing, annotation, sensitive information, biases, limitations and intended use. In an AIBOM, a Croissant file describes one data component, joined to the BOM by URL and SHA-256. This guide walks through a valid Croissant 1.1 + RAI file for a fictional support-ticket dataset, explains why de-identified is not anonymous, and documents a naming mismatch: the reference library mlcroissant 1.1.1 reads rai:dataCollectionTimeFrame and rai:dataDataManipulationProtocol, while the RAI vocabulary defines rai:dataCollectionTimeframe and rai:dataManipulationProtocol.

Put it into practice
Download the complete Croissant RAI file
The full Northwind dataset file, validated with mlcroissant 1.1.1, plus a form that regenerates it for your own dataset. Pro.
Open the Template Library

Croissant is MLCommons’ JSON-LD format for describing a machine-learning dataset: schema.org Dataset metadata, the files that hold the data, and the structure of each record. Croissant RAI adds rai: properties for how the data was collected and cleaned, what sensitive information it holds, its known biases and limits, and what it may be used for. In an AIBOM, a Croissant file describes one data component; it says nothing about the model or the system.

Who this is for: AppSec and AI-security engineers who vet or publish training data, and GRC teams who need dataset documentation that both people and tools can read. The current versions are Croissant 1.1 (29 January 2026) and Croissant RAI 1.0 (6 March 2024).

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.

The dataset in the example

northwind/support-tickets-2025 holds 48,210 de-identified customer support tickets closed between 2025-01-01 and 2025-12-31, each paired with the agent reply that resolved it. Northwind Health used it to fine-tune northwind/triage-assistant 2.3.0. It is internal and under a proprietary licence. The file is northwind-support-tickets-2025.croissant.json. It validates with mlcroissant 1.1.1, the MLCommons reference library, with no errors.

Croissant core: metadata, files, records

A Croissant file has three layers.

  1. Dataset metadata. schema.org properties. These are required:
PropertyWhat it recordsNorthwind
@context, @typeThe JSON-LD context and sc:Datasetschema.org vocabulary plus cr:, rai: and dct: prefixes; sc:Dataset
conformsToWhich Croissant version (and extensions) the file followsCroissant 1.1 and RAI 1.0
name, descriptionWhat the dataset isnorthwind-support-tickets-2025; 48,210 de-identified tickets with the resolving reply
licenseLicence URL; Croissant recommends an SPDX licence URLNorthwind’s proprietary licence URL
url, creator, datePublishedWhere it lives, who made it, whenInternal dataset page; Northwind Health; 2026-01-20

Recommended on top: keywords, publisher, version and dateCreated. Northwind sets all four, plus citeAs (a BibTeX entry) and isLiveDataset: false. Croissant asks for semantic versioning: bump MAJOR when existing records change or are removed.

  1. Resources. distribution lists the files as cr:FileObject (one file) or cr:FileSet (many files, by glob), with contentUrl, encodingFormat and a checksum. Northwind has one JSON Lines file with a SHA-256.
  2. Structure. recordSet describes the records. Each field has a dataType and a source that says which file it comes from and how to extract it (here a jsonPath). Northwind’s record set tickets has six fields, keyed on tickets/ticket_id.

Croissant RAI: every property, and which Northwind uses

The RAI 1.0 vocabulary has 20 properties. The table lists them with the cardinality from the spec and whether the Northwind file uses each. A property left out should be left out for a reason you can state.

PropertyCardinalityUsedNorthwind, or why not
rai:dataCollectionONEYesHow the tickets were exported and paired with replies.
rai:dataCollectionTypeMANYYesCustomer feedback data, one of the spec’s recommended values.
rai:dataCollectionRawDataONEYesThe ticketing system export.
rai:dataCollectionTimeframeMANYYesSee the naming mismatch below.
rai:dataCollectionMissingDataONEYesNo-reply tickets excluded; phone issues missing.
rai:dataPreprocessingProtocolMANYYesDedupe, de-identify, sample review.
rai:dataAnnotationProtocol, rai:dataAnnotationPlatform, rai:annotationsPerItemONE / MANY / ONEYesThe label is the category the agent chose at closure; one per ticket.
rai:dataAnnotationAnalysis, rai:annotatorDemographics, rai:machineAnnotationToolsMANY eachNoNo separate annotation pass, so nothing to analyse. The de-identification tools are preprocessing, not annotation.
rai:dataImputationProtocol, rai:dataManipulationProtocolONE eachNoNo values were imputed. De-identification is recorded under preprocessing instead.
rai:personalSensitiveInformationMANYYesDirect identifiers removed; health context may remain.
rai:dataBiases, rai:dataLimitationsMANY eachYesWritten channels only; 2025 policies; not for medical advice.
rai:dataUseCasesMANYYesFine-tuning the triage model; not for medical advice or profiling.
rai:dataSocialImpactONEYesFaster replies; risk of repeating agent mistakes.
rai:dataReleaseMaintenancePlanMANYYesStatic snapshot, yearly successor.

The naming mismatch in mlcroissant

MLCommons’ own materials spell two RAI properties three different ways, and the reference library uses a fourth.

SourceCollection periodManipulation protocol
RAI 1.0 spec, property tablerai:dataCollectionTimeframe (sc:DateTime, MANY)rai:dataManipulationProtocol
RAI vocabulary, croissant_rai.ttlrai:dataCollectionTimeframe, described as an ISO 8601 interval such as "2020/2022"rai:dataManipulationProtocol
RAI 1.0 spec, prose and examplerai:dataCollectionTimeFrame in the prose; rai:dataCollectionTimeFrameStart and …End in the examplerai:dataManipulationProtocol
mlcroissant 1.1.1 (and the main branch)rai:dataCollectionTimeFramerai:dataDataManipulationProtocol

We checked the library in the mlcroissant 1.1.1 source (constants.py) and on the main branch on 29 October 2026, and ran it against the Northwind file. What happens:

  • A file that follows the vocabulary passes, and the library drops the field. The Northwind file writes rai:dataCollectionTimeframe. mlcroissant validates it with no errors and no warnings, and its metadata object returns nothing for the collection period. Unknown rai: names are ignored silently.
  • The library’s own spelling with an interval string gives a wrong date. We added "rai:dataCollectionTimeFrame": "2025-01-01/2025-12-31", the interval form the vocabulary describes. mlcroissant parsed it into a single, wrong timestamp, again with no warning.
  • Two dates work. "rai:dataCollectionTimeFrame": ["2025-01-01", "2025-12-31"] was read as a start and an end date.
  • rai:dataDataManipulationProtocol with a doubled “Data” appears only in the library. It looks like a typo.

What we recommend: write the names the vocabulary defines, as Northwind does, because that is the standard other tools will follow. If a consumer reads your file with mlcroissant and needs the collection period, add the library’s spelling as a second property with two dates, never an interval string. Do not write rai:dataDataManipulationProtocol into a file. Whatever you choose, do not take a clean mlcroissant validate run as proof that your RAI fields were read.

De-identified is not anonymous

Northwind removed names, email addresses, phone numbers, postal addresses and account or member numbers with named-entity detection and pattern rules, then reviewed a sample by hand. That is de-identification. It is not the same as anonymisation.

Under GDPR Recital 26, data is anonymous only if a person can no longer be identified by any means reasonably likely to be used, taking cost, time and available technology into account. Pseudonymised data, which could be re-linked with extra information, is still personal data. Support tickets are free text: “my son’s insulin pump order from last Tuesday” can identify someone with no name in it. That is why Northwind’s rai:personalSensitiveInformation says health context may remain, and why the dataset is classified confidential.

The same example’s SPDX file sets dataset_hasSensitivePersonalInformation: no. Read that as Northwind’s claim after de-identification, and the Croissant entry as the residual risk behind it. A reviewer should ask for the evidence: the de-identification method, the sample size reviewed and what was found. The AI Training Data Provenance checklist structures those questions.

How Croissant fits into an AIBOM

An AIBOM in CycloneDX or SPDX lists the dataset as one component and links the model to it. Croissant describes that component in depth. In the Northwind files the three agree on two join keys: the dataset URL and the SHA-256 of the data file. A verifier can check that the BOM, the Croissant file and the bytes on disk all describe the same thing.

FactCroissantCycloneDX data componentSPDX DatasetPackage
Same dataseturldata[].contents.url on the data componentsoftware_downloadLocation
Same bytesdistribution[].sha256hashesverifiedUsing
LicencelicenselicenseshasDeclaredLicense
How it was collectedrai:dataCollectionNo field (description only)dataset_dataCollectionProcess
Preprocessingrai:dataPreprocessingProtocolNo fielddataset_dataPreprocessing
Sensitive datarai:personalSensitiveInformationdata[].sensitiveDatadataset_hasSensitivePersonalInformation, dataset_anonymizationMethodUsed
Biasesrai:dataBiasesNo fielddataset_knownBias
Intended userai:dataUseCasesNo fielddataset_intendedUse
Maintenancerai:dataReleaseMaintenancePlanNo fielddataset_datasetUpdateMechanism
Collection periodrai:dataCollectionTimeframeNo fieldNo field (builtTime is when it was built)

The pattern is clear: CycloneDX carries identity, integrity and licence for a dataset but little about how the data was made, while Croissant RAI and the SPDX Dataset profile carry the collection and use facts. If your AIBOM is CycloneDX, link the Croissant file from the data component. The AIBOM Format Field Map (Pro) shows the same mapping for every field.

The Northwind field table

FieldNorthwind valueWhat it tells you
@contextschema.org vocabulary plus cr:, rai: and dct: prefixesCroissant is schema.org Dataset markup with ML and RAI extensions.
@typesc:DatasetA schema.org Dataset, so dataset search engines can read it.
conformsTohttp://mlcommons.org/croissant/1.1, http://mlcommons.org/croissant/RAI/1.0Required. Declares Croissant 1.1 and the Responsible AI extension.
name / alternateNamenorthwind-support-tickets-2025 / northwind/support-tickets-2025Dataset name, plus the repo-style ID used elsewhere in the AIBOM.
description48,210 de-identified tickets with the resolving replyRequired. What is in the dataset.
licensehttps://northwind-health.example/licences/proprietaryRequired. A licence URL; use an SPDX licence URL when one applies.
url / creator / datePublishedhttps://data.northwind-health.example/datasets/support-tickets-2025 / Northwind Health / 2026-01-20Required. Where it lives, who made it, when it was published.
citeAsBibTeX @misc entryRecommended by the reference validator. How to cite the dataset.
version1.0.0Recommended. Semantic versioning: MAJOR when existing records change.
distribution[] (cr:FileObject)tickets.jsonl, application/jsonlines, sha256 (placeholder)Required. The files, with format and checksum so a download can be verified.
recordSet[] / field[]tickets: ticket_id, closed_on, channel, category, customer_message, agent_replyThe structure of each record and where each field is read from (jsonPath).
rai:dataCollectionExported from the ticketing system, 2025-01-01 to 2025-12-31How the data was collected.
rai:dataCollectionTypeCustomer feedback dataCollection type, from the RAI spec's recommended values.
rai:dataCollectionTimeframe2025-01-01/2025-12-31Collection period as an ISO 8601 interval (start/end), the form the RAI vocabulary describes.
rai:dataCollectionMissingDataNo-reply tickets excluded; phone calls missingWhat is not in the data and why.
rai:dataPreprocessingProtocolDedupe, de-identify, sample reviewSteps between raw export and training-ready data.
rai:dataAnnotationProtocol / rai:annotationsPerItemAgent-chosen category at closure / 1Where labels came from and how many per record.
rai:personalSensitiveInformationDirect identifiers removed; health context may remainWhat sensitive information is or may be present.
rai:dataBiasesWritten channels onlyKnown biases.
rai:dataLimitations2025 products and policies; not for medical adviceKnown limits and non-recommended uses.
rai:dataUseCasesFine-tuning northwind/triage-assistant; not for medical advice or profilingRecommended and excluded uses.
rai:dataSocialImpactFaster replies; risk of repeating agent mistakesExpected impact on people.
rai:dataReleaseMaintenancePlanStatic snapshot, yearly successorHow the dataset is versioned and retired.

The example file, excerpted

The version declaration, the file with its checksum, two of the six fields, and three RAI properties.

{
  "@type": "sc:Dataset",
  "conformsTo": ["http://mlcommons.org/croissant/1.1", "http://mlcommons.org/croissant/RAI/1.0"],
  "name": "northwind-support-tickets-2025",
  "distribution": [
    {
      "@type": "cr:FileObject",
      "@id": "tickets-jsonl",
      "name": "tickets.jsonl",
      "description": "One JSON object per ticket.",
      "contentUrl": "https://data.northwind-health.example/datasets/support-tickets-2025/tickets.jsonl",
      "encodingFormat": "application/jsonlines",
      "sha256": "f1a5c6949d6413cba9a37c2eda8f05cc1cbbbf1bfd374c6229bce6631a53d244"
    }
  ],
  "recordSet": [
    {
      "@type": "cr:RecordSet",
      "@id": "tickets",
      "key": { "@id": "tickets/ticket_id" },
      "field": [
        {
          "@type": "cr:Field",
          "@id": "tickets/ticket_id",
          "dataType": "sc:Text",
          "source": {
            "fileObject": { "@id": "tickets-jsonl" },
            "extract": { "jsonPath": "$.ticket_id" }
          }
        },
        {
          "@type": "cr:Field",
          "@id": "tickets/customer_message",
          "dataType": "sc:Text",
          "source": {
            "fileObject": { "@id": "tickets-jsonl" },
            "extract": { "jsonPath": "$.customer_message" }
          }
        }
      ]
    }
  ],
  "rai:dataCollectionTimeframe": "2025-01-01/2025-12-31",
  "rai:dataPreprocessingProtocol": [
    "Removed tickets without an agent reply and exact duplicates.",
    "De-identified free text: named-entity detection plus pattern rules removed names, email addresses, phone numbers, postal addresses and account or member numbers.",
    "Manually reviewed a random sample of de-identified tickets for leaks before release."
  ],
  "rai:personalSensitiveInformation": [
    "Direct identifiers removed by de-identification. Free text can still mention health conditions, which is why the dataset is confidential."
  ]
}

Excerpt, 52 lines: conformsTo, the distribution, two of the six fields (without their name and description) and three of the RAI properties; the @context is left out. Keys and list entries not shown are left out; every value shown is exactly as in the full file, which runs to 231 lines pretty-printed.

The complete file, with the full context, all six fields and every RAI property in the table above, is in the AIBOM Template Library (Pro).

How to validate it, and how to vet someone else’s

Run mlcroissant validate --jsonld northwind-support-tickets-2025.croissant.json. It checks the Croissant core: the dataset properties, the files, the record sets and how each field is extracted. It does not check RAI property names, so read those against the vocabulary yourself (see the mismatch above).

When you take a dataset from someone else, fetch its Croissant file before you fine-tune on it. Hugging Face serves one at https://huggingface.co/api/datasets/<id>/croissant; Kaggle and OpenML offer exports. Then check what is missing. The auto-generated file we fetched for zalando-datasets/fashion_mnist in October 2026 declared Croissant 1.0 and carried no rai: properties at all, so the collection, consent and bias questions were still yours to answer.

Where to go next

This guide is part of the AIBOM Library. The same Northwind system in the other formats: CycloneDX ML-BOM and SPDX 3.0 AI and Dataset profiles. 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).

For the dataset fields any AIBOM should carry, see the AIBOM parameters checklist.

Frequently asked questions

What is Croissant metadata?

Croissant is MLCommons’ JSON-LD format for describing machine-learning datasets. It builds on schema.org Dataset and adds the files (distribution, as FileObject or FileSet), the structure of each record (recordSet and field) and how each field is read from the files. The current version is 1.1, published on 29 January 2026.

What is Croissant RAI?

The Responsible AI extension to Croissant, version 1.0 (published 6 March 2024). It adds rai: properties for how data was collected, preprocessed and annotated, what personal or sensitive information it contains, known biases and limitations, intended use cases, social impact and the maintenance plan. A file declares it by listing http://mlcommons.org/croissant/RAI/1.0 in conformsTo.

Is a Croissant file an AIBOM?

No. A Croissant file describes one dataset. In an AIBOM that dataset is one data component. The AIBOM, in CycloneDX or SPDX, also lists the model, its lineage, the software, the run-time services and the signatures. Join the two by the dataset URL and the SHA-256 of its files.

How do I validate a Croissant file?

Install the MLCommons reference library and run mlcroissant validate --jsonld your-file.json. It checks the Croissant core: required properties, the files and the record structure. It does not warn about misspelled or unknown rai: properties, and version 1.1.1 reads two RAI properties under different names from the spec, so check those by hand.

Is de-identified data anonymous?

Not necessarily. De-identification removes direct identifiers such as names, emails and account numbers. Under GDPR Recital 26, data is anonymous only if a person can no longer be identified by any means reasonably likely to be used, and pseudonymised data is still personal data. Free text can identify someone through context, so treat de-identified data as personal data until you have shown otherwise.

Does Hugging Face publish Croissant files?

Yes. Hugging Face embeds Croissant JSON-LD in dataset pages and serves it from https://huggingface.co/api/datasets/<id>/croissant. Kaggle and OpenML offer Croissant exports too. Do not assume RAI fields are present: the auto-generated file we fetched for fashion_mnist in October 2026 declared Croissant 1.0 and had no rai: properties.

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 Croissant RAI file
The full Northwind dataset file, validated with mlcroissant 1.1.1, plus a form that regenerates it for your own dataset. 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