AI-Generated Code Provenance for License Audits: Recording Which Assistant Produced Each Line
To support a license audit, capture attribution when the code is generated, not afterward. Record the assistant, model and version, interaction context, policy applied and any origin or license signal. Bind that record to commits, and store it as a tamper-evident history. Line-level attribution becomes approximate once developers edit, refactor or squash-merge suggested code, so keep the sequence of events rather than a single label per line.
An implementation sequence
- 1
1. Define the audit questions
Agree the fields, the unit of attribution (line, hunk or file) and the confidence levels you will report.
- 2
2. Choose capture points
Pick at least one point near generation and one at commit time, so each can cross-check the other.
- 3
3. Bind interactions to commits
Write identifiers into commit metadata or notes, and carry them through squash and rebase workflows.
- 4
4. Record origin and license context
Store any public-code match or license filter result, and the policy in force when the output was produced.
- 5
5. Export per release
Summarize provenance for each release, for example in an SBOM or attestation, and keep the underlying records so the summary can be traced.
The attribution data an audit needs
- Assistant identity: which tool produced the suggestion, and the account or user session it ran under.
- Model details: model name, version and access mode, as the assistant reports them.
- Interaction context: timestamp, repository, branch, file and the range of code affected.
- Policy applied: which rules were in force and what action was taken, such as allow, redact or block.
- Origin and license signals: any public-code match, license filter result or similarity finding for the output.
- Mapping: the commit, pull request and build artifact the suggested code later landed in.
Start with the audit questions
Version control records who committed a change. A license audit or due diligence request asks something different: where did this code come from, and what obligations might attach to it. When several AI coding assistants are in use, the commit author field cannot answer which assistant produced a line, which model sat behind it, or what policy applied at the time.
Write the audit questions down before choosing tooling. A workable set: which files or lines were AI-generated, by which assistant and model version, under which policy, whether the output matched known licensed code, and who reviewed it. NIST's generative AI profile is voluntary guidance, not a legal requirement, but its inventory fields are a useful starting checklist. They include provenance information such as source, versioning and timestamps, human oversight roles, and special considerations for intellectual property and licensed works.
NIST's secure development profile for generative AI also makes a point that shapes the design. It does not distinguish between human-written and AI-generated source code, because all code needs evaluation before use. Provenance records supplement code review and license analysis. They do not replace them.
Self-reporting is the weak point to design out. If attribution depends on a developer remembering to tag a suggestion, the record will be incomplete in exactly the cases an auditor probes.
Comparing capture approaches
No single capture point covers every question. The approaches differ in how close they sit to the generation event and in how well they survive later changes to the code. Most teams combine two.
- IDE or assistant-level capture: Closest to the suggestion and shows what was offered and accepted. Coverage depends on what each assistant exposes, and multiple assistants produce inconsistent formats.
- Commit metadata and trailers: Travels with the commit and is easy to query. Relies on a hook or tool writing it, is coarse at commit level, and can be lost in rebases or squash merges if not carried forward.
- Repository-level tagging: Git notes, labels or file-level markers add context without rewriting history. They are easy to separate from the code and need controls to stay trustworthy.
- Capture in the execution path: A single point sees interactions from every assistant routed through it, with a consistent record and the ability to enforce policy before output reaches the developer. It sees only traffic that passes through it, and it does not observe later human edits.
Binding interactions to commits and lines, and where it stops
The interaction record and the commit are created at different times, often by different tools. Binding them means matching the suggestion that was accepted, usually by content fingerprint, file path and time window, to the diff that lands in a commit. Store the fingerprint and the match result, so the link can be re-checked rather than taken on trust.
Be candid about accuracy. Once a developer edits a suggestion, the line is partly AI-generated and partly human. Refactoring can move or reshape code so that fingerprints no longer match. Squash merges collapse many commits into one and discard intermediate history unless the attribution records are carried forward. Agentic tools add further events, since they can create commits and resolve merge conflicts themselves.
The practical response is to record events instead of asserting a final per-line label. Keep the generation event, the acceptance, later modifications and the merge as separate entries, and report line-level attribution with a stated confidence: exact match, modified, or unknown. An auditor can accept an honest approximation with a traceable history more readily than a precise-looking label that cannot be reproduced.
Keeping the evidence durable and defensible
NIST guidance suggests a tamper-proof history of when content is generated, modified or shared. In practice, that means append-only storage, signed or attested records bound to build and release artifacts, and a documented answer to who can write to or alter the record. Free-text developer notes do not meet that bar. Keep low-level records such as interaction logs and source files alongside any summary, so every high-level claim traces to underlying data.
Set retention to cover the period in which a license audit or due diligence request could plausibly arrive, and apply data residency settings that match where the code and prompts are allowed to be stored. Restrict read access, because interaction records can contain proprietary code. Confirm the evidence can be exported in a form an auditor will accept.
Trussed enforces policy in the execution path for coding assistants, so the interaction is governed at runtime, not reviewed after the fact. Its code provenance capability records the origin, license and security context of code and produces audit-ready evidence. It can be deployed self-managed in the customer cloud, with configurable retention and data residency. It does not make claims about model or dataset provenance. Whichever tooling you use, the same questions apply: what is recorded, how it is bound to commits, and how it is protected from alteration.
From suggestion to audit evidence
Capture
Record each generation event with assistant, model, timestamp and policy.
Bind
Link the interaction record to commits and files.
Annotate
Attach origin and license signals to the record.
Retain
Store tamper-evident evidence with defined retention and residency.
Plan attribution evidence before the audit request arrives
Talk through capture points, commit binding and retention for your coding assistants with a Trussed expert.
Talk to an Expert