How to Tag Commits Authored by Claude Code for License Audit Trails
Apply a fixed set of git commit trailers to every Claude Code change, using Claude Code attribution settings and a commit-msg hook. Verify them in CI and on the server. Treat the result as a record that AI was involved, not as proof of license context. Tags applied by convention can be omitted or edited, so audit-ready evidence has to be recorded at runtime, independent of developer behavior.
Rollout checklist for platform teams
- Publish and version one trailer schema for all repositories
- Set Claude Code attribution centrally and confirm local overrides are blocked or detected
- Use a hook to write tool and version values rather than relying on typed input
- Enforce trailer checks in CI and, where available, in a server-side pre-receive hook
- Preserve trailers in squash merge templates and restrict who can edit verification rules
- Document in the audit narrative which questions tags answer and which need runtime evidence
What a commit tag can and cannot establish
A license or IP review of AI-assisted code usually asks four things: which code came from an AI coding assistant, under what configuration it was produced, what license context applied to that code, and who reviewed it. Repository history is the first place auditors look, so teams want the answer visible in the commit.
Commit metadata can realistically answer some of these. It can state that Claude Code was involved, name the tool and version, and name the human who reviewed and merged the change. It cannot establish the origin or license context of the code itself. A trailer is a text assertion written at commit time. It says what someone or something claimed, not what the code resembles or what license terms attach to it.
Keeping that boundary clear from the start prevents the most common failure in these programs: presenting a tagging convention to an auditor as if it were a license control.
Apply a consistent trailer set
Git commit trailers are key-value lines at the end of a commit message, and git can read and write them with git interpret-trailers. They are the right container because they are plain text, survive in history, and are easy to parse in CI.
Define one schema and version it in a shared repository so that every team uses the same keys. A minimal set is below. Keep it small, because every extra field is another field that will be omitted or mistyped.
For application, do not rely on developers or on the assistant remembering to type trailers. Enable whichever Claude Code attribution setting your version provides for co-author lines, and distribute it through the central configuration mechanism your organization already uses for developer tooling. Then confirm that a developer cannot silently override it in a local or project-level file. Where Claude Code hooks are available, use one to append the trailers deterministically at commit time, so the values come from a script rather than from model output.
Add a commit-msg hook on the developer machine that checks the schema and rejects malformed trailers early. This improves consistency, but it is a convenience, not a control, because local hooks run only where they are installed.
- AI-Assisted: claude-code, set whenever Claude Code authored or modified the change
- AI-Tool-Version: the tool version in use at commit time
- AI-Config-Ref: an identifier for the configuration or policy set that applied
- Reviewed-By: the human who reviewed the change before merge
- Evidence-Ref: an optional pointer to separately stored records for this change
Verify in CI and on the server
Verification is where a convention becomes something closer to a control. Run a CI job on every pull request that walks the commits in the range, parses trailers, and fails when a required key is missing or malformed. Where your git host supports server-side pre-receive hooks, enforce the same check there so that a push cannot skip CI. Where it does not, use protected branches and required status checks so the CI job gates merges.
Know the bypass routes before you rely on any of this. Local hooks are skipped with a flag or by never being installed. Trailers can be removed or rewritten by amending or rebasing before push. Squash merges can drop trailers from individual commits unless the merge message template preserves them. A developer can type a false trailer, or leave one off a commit that contains pasted assistant output. A check can only validate what is present. It cannot detect AI-authored code that carries no tag.
Signed commits help in one narrow way. The signature covers the commit message, so a trailer edited after signing is detectable. It does not show that the trailer was true when written.
NIST guidance on code signing offers a useful control pattern here. It advises identifying who may submit code, maintaining and periodically reviewing that list, and separating administration of the signing system from the role of the submitter. Applied to tagging, that means the people who commit code should not be able to change the verification rules that check their own tags.
Which audit questions commit tags cover
Map each audit question to what trailers can support and what must come from somewhere else. This keeps the audit narrative accurate.
- Was an AI assistant involved?: Partly covered. A verified trailer records involvement for tagged commits. Untagged AI-authored changes remain invisible.
- Which tool and version?: Covered if the value is written by a hook rather than typed by hand.
- Who reviewed it?: Covered when Reviewed-By is cross-checked against merge approvals on the git host.
- What configuration applied?: Only by reference. A config identifier points to a record held elsewhere.
- What was the origin and license context of the code?: Not covered. Commit text does not describe the code's origin or the licenses attached to it.
- Can the record be shown to be untampered and complete?: Weakly covered. Server-side checks and signatures help, but omission cannot be detected.
Why runtime evidence is stronger than convention
Every mechanism above depends on a developer or a script acting correctly at the edge of the workflow. Evidence that is recorded by the system doing the work, at the moment the work happens, does not. That is the difference between a tag applied by convention and a record produced at runtime.
License review also needs component-level clarity. NIST's own submission rules for code, for example, call for a license statement and a clear relation between licenses and components, and for review of generative AI outputs that are used. A trailer on a commit can point toward that information but cannot supply it.
Trussed addresses this layer. It enforces policy in the execution path of coding assistants, with actions such as allow, redact, block, rate limit and escalate for human approval, applied to individual interactions and tool calls. Its code provenance capability records the origin, licence and security context of code. The audit-ready evidence is generated by enforcement itself, so it is enforced at runtime, not reviewed after the fact, and does not rely on a developer remembering a trailer. Commit hashes then work as a simple join key between repository history and that separately held evidence.
The commit tags in this guide remain useful. They make AI involvement visible to anyone reading history. The runtime layer supplies the license context and completeness that tags cannot.
From commit tag to audit evidence
Apply
Attribution settings and hooks add a standard trailer set.
Verify
CI and server-side checks reject missing or malformed tags.
Scope
Tags show AI involvement, not license context.
Evidence
Runtime enforcement and code provenance supply what tags cannot.
Close the gap between tags and evidence
Commit trailers show that AI was involved. Talk to our team about enforcing policy in the execution path of coding assistants and capturing code provenance as audit-ready evidence.
Talk to an Expert