Licensing and Provenance of Training Data
5 min read · updated August 3, 2026
“Where did this row come from?” is a question that is trivial to answer at ingest and close to impossible to answer a year later. The cost of the gap is not academic: it decides whether a dataset can be used, shared, or has to be rebuilt.
Why this stopped being a formality
Four things converged. Model outputs are now derived from training data in ways courts are actively examining, so the copyright status of training data is a live question rather than a settled one. Data-protection law gives individuals rights over their records that you cannot honour if you do not know which rows are theirs — see the right to erasure. Provider terms of service restrict what model outputs may be used to train, which makes the provenance of a generated slice a contractual matter. And the EU AI Act introduces transparency obligations about training data for certain systems.
Each of those turns into the same operational requirement: for any row, you must be able to say where it came from, under what terms, and whether a model was involved in producing it. That is a data-structure problem, and it is only solvable at ingest.
What the licensing audit found
The Data Provenance Initiative (Longpre et al., 2023, arXiv 2310.16787) audited a large collection of widely used text datasets — tracing licences, sources and creators across well over a thousand of them — and reported a systematic problem with the metadata everyone relies on: licence information attached to datasets on popular hosting platforms was frequently missing, and where present was often more permissive than the licence of the underlying source material. A substantial share of the datasets they examined carried no usable licence information at all.
The practical reading is not that these datasets are unusable. It is that the licence tag on an aggregator page is not evidence. It is a field somebody filled in, frequently by a re-packager two hops from the original, and the chain to the original terms is what matters. If your compliance position rests on a tag you did not verify, it rests on nothing.
The same audit makes a second point that is easy to skip past and worth sitting with. Licences are only half of provenance; the other half is the chain — who assembled this from what, and in which order. A dataset that is a re-packaging of a re-packaging can be three hops from the terms that actually govern it, and each hop is an opportunity for a field to be filled in by someone guessing. When the chain is recorded, verifying a licence is a matter of following it to the origin. When it is not, the only honest options are to re-derive the corpus from sources you control or to accept an unquantified risk.
Two adjacent traps worth naming. Licence compounding: a dataset built from five sources inherits the most restrictive of the five, and share-alike terms can propagate to the combined work — so an aggregate labelled permissively may contain a component that is not. And derived data: a dataset generated by prompting a model inherits that provider’s terms, whatever licence the person who uploaded it chose to attach.
The provenance record
Attach this at ingest, per row or per source batch. Retrofitting it is the expensive path, and frequently the impossible one.
{
"row_id": "sup-2026-0041882",
"source": {
"kind": "scraped", // scraped | licensed | user | internal | generated
"name": "docs.example.com",
"url": "https://docs.example.com/billing/refunds",
"retrieved_at": "2026-06-14T09:22:11Z",
"robots_allowed": true, // what robots.txt said AT RETRIEVAL TIME
"terms_snapshot": "s3://prov/terms/example-com-2026-06-14.html"
},
"licence": {
"declared": "CC BY-SA 4.0",
"verified_from": "https://docs.example.com/legal", // NOT the aggregator
"verified_at": "2026-06-14",
"attribution_required": true,
"share_alike": true,
"commercial_use": true
},
"generation": null, // non-null ONLY if a model produced this row
// {"model": "<provider>/<model-id>", "version": "<returned version>",
// "prompt_hash": "sha256:…", "params": {"temperature": 1.0},
// "run_id": "gen-2026-07-02-a", "seed_row_id": "sup-2026-0038114"}
"personal_data": {
"present": true,
"categories": ["email"],
"subject_key": "cust_88213", // the handle a deletion request resolves to
"basis": "legitimate_interest"
},
"transforms": [ // append-only; each step names its code
{"step": "html_extract", "tool": "[email protected]", "at": "2026-06-14"},
{"step": "pii_redact", "tool": "[email protected]", "at": "2026-06-14"},
{"step": "dedupe", "tool": "[email protected]/5", "at": "2026-06-20"}
]
}Four fields in there are the ones people omit and later need. The terms_snapshot, because terms change and “the site said we could” is only defensible with a copy of what it said on the day. The verified_from URL, because it is what separates a checked licence from a copied one. The subject_key, because a deletion request is unanswerable without a join key back to a person. And generation, because six months later nobody remembers which slice was generated, and it is the first thing an auditor asks about.
The questions each source has to answer
Different kinds of source raise entirely different questions, and the common mistake is to apply one checklist to all of them — usually the copyright checklist, which is the wrong instrument for data your own users gave you and an incomplete one for data a model wrote. Work through the row that matches, and record the answers next to the data rather than in a document that will be separated from it.
| Source kind | Description |
|---|---|
| scraped from the web | What did robots.txt say at retrieval time, and did you honour it? What do the site's terms say about automated collection and about machine learning specifically? Is the content itself third-party — a forum post is the poster's, not the platform's? Does the jurisdiction have a text-and-data-mining exception, and did the rightsholder reserve against it? |
| public dataset | What is the licence of the ORIGINAL data, not the aggregator's tag? Was it assembled from other sources with their own terms? Does it carry share-alike obligations that propagate to your combined dataset? Is there an attribution requirement you are silently breaching? |
| purchased or licensed | Does the contract permit model training specifically — many data licences predate the question and are silent, which is not the same as permission. Does it permit the resulting model to be distributed? What happens at termination: do you have to retrain? |
| your own users | What did the terms say when the data was collected, not what they say now? Is training a purpose the user could reasonably have expected? Is there an opt-out, and is it actually joined through to the training pipeline? |
| generated by a model | What do the provider's terms permit the output to be used for, especially for training a competing model? Record the model and version — this is also the field that makes the collapse question answerable, since you cannot check whether a corpus is turning synthetic if nothing marks the synthetic rows. |
Practices that keep it answerable
- Provenance is written at ingest or never. The information exists at the moment of collection and decays immediately. Every retrofit project is more expensive than the original collection.
- Keep the raw artefact. Store the original HTML, PDF or API response alongside the extracted text. Cheap storage, and it is what lets you reprocess without re-collecting, and re-verify without trusting your own extractor.
- Never merge away the source column. The most common way provenance is lost is a join that drops it in the name of a tidier schema. Carry it through every transform.
- Snapshot terms, not just links. A URL to a terms page is a promise that the page will not change. It will.
- Treat generated rows as a first-class source. Same record, same rigour. A dataset where nobody can say which rows a model wrote cannot answer the question in the collapse literature even in principle.
- Make deletion mechanically possible. A subject key on every row, and a documented procedure that resolves it to a set of row ids. Whether deletion also requires retraining is a separate and harder question, but it starts with knowing which rows.