A few weeks ago, a developer posted a question that has been quietly bothering
everyone who builds with AI:
"I never open-sourced that code. An agent pulled it from somewhere and handed
it out as open source. Whose code is it now? And honestly — when all the code
is written by models anyway, what does 'open source' even mean anymore?"
That question has no clean legal answer yet. But it has a clean technical
prerequisite, and it's the same prerequisite every supply-chain conversation
keeps running into:
Before anyone can argue about who owns a piece of code or where it came from,
you need to be able to prove what existed, when, and in exactly what form —
without trusting the person making the claim.
That's a provenance problem. We just built the smallest end-to-end version of it
we could, anchored a real public code snapshot, and verified the whole chain
ourselves. This article is what we built, why each piece exists, and the three
commands you can run to check it without trusting us at all.
What "proof" actually requires
A screenshot of a timestamp proves nothing. A hash you computed yourself and
show me later proves nothing — I can't tell when you computed it, or whether the
thing I'm looking at now is the thing you hashed.
A claim like "this code existed on September 3rd" only becomes checkable when
four independent layers line up:
- A content-addressed manifest. Every file gets a SHA-256 hash, and the manifest itself is canonicalized before hashing — we use JCS (JSON Canonicalization Scheme, RFC 8785), so the hash is stable across key ordering, whitespace, and language differences. The hash commits to the exact bytes, file by file.
- A signature over that manifest. A key the claimant controls signs the manifest hash — Ed25519 per RFC 8032. This answers "who made this claim", but it is not yet a timestamp: a signature has no notion of when it was made.
- An anchor in a public transparency log. We submit the signed hash to the Sigstore Rekor transparency log (hashedrekord entry). Once it's in the log, it carries an inclusion proof and a log index anyone can query. The log is a append-only, publicly monitored witness — you don't have to trust our server, our clock, or our word.
- A persistent, citable archive. The proof bundle itself (manifest, receipt, anchor record) is deposited with Zenodo and gets a DOI, so it has a permanent identifier independent of our infrastructure.
Each layer answers a different objection. Remove any one and the claim degrades
into "trust me".
The three commands
The tool is a single-file Python CLI (provenance.py), stdlib-only for
networking:
# 1. Generate a local identity key (never leaves your machine)
python provenance.py keygen
# 2. Snapshot a directory -> manifest -> signed receipt -> Rekor anchor -> Zenodo DOI
python provenance.py anchor ./my-project --name my-project
# 3. Independently verify a proof bundle — rehashes everything,
# checks the Ed25519 signature, pulls the Rekor entry, compares all three hashes
python provenance.py verify ./output/my-project-2026-09-03/
verify does not contact any Correctover service. It recomputes the manifest
hash from the files, checks the signature against the embedded public key,
fetches the Rekor entry from the public log, and asserts that the recomputed
hash, the receipt hash, and the on-log hash are all the same value. If any
layer drifts, it fails closed.
The real anchor (you can check it right now)
We didn't run this on a toy. The first snapshot anchored was our own public
open-source package, correctover-scan v1.4.0 (MIT), commit
13a3caa — 8 files.
-
Manifest hash (JCS, SHA-256):
b0366186a5063a091148ffdc6b042d36e8cfa8e2d675e05b6c598e096b3ca75f - Rekor transparency log: index 2694324795 — view in the Sigstore search UI or query the API directly:
curl -s "https://rekor.sigstore.dev/api/v1/log/entries?logIndex=2694324795"
The entry includes an inclusion proof you can verify against the log's
signed tree head.
- Zenodo DOI: 10.5281/zenodo.22266162 — the proof bundle (manifest, receipt, anchor record) is deposited there under CC0.
If you want the shortest possible sanity check without installing anything:
open the Rekor search link, confirm the entry exists; open the DOI, confirm the
bundle is archived; compare the hash printed in both places with the manifest
hash above. Three independent witnesses, one hash.
One honest technical wrinkle
We hit a real interoperability constraint worth documenting, because anyone
replicating this will hit it too:
the public Rekor instance's hashedrekord v0.0.1 type parses detached
signatures as Ed25519ph (prehashed Ed25519), but passes the artifact hash
algorithm (SHA-256) to the verifier — and the Ed25519ph verifier only accepts
SHA-512. So an Ed25519 signature over a SHA-256 artifact hash is rejected
(unsupported hash algorithm: "SHA-256" not in [SHA-512]). This matches how
cosign and sigstore-go handle the default case.
Our resolution: the identity receipt stays Ed25519/RFC 8032 (that's our
signature, our key, our receipt format). The transparency-log anchor uses
ECDSA P-256 over SHA-256 (prehashed, ASN.1 DER) — the Sigstore ecosystem's
default, fully interoperable choice. The anchor record documents both keys and
which one does what. The security properties don't change: the log still
witnesses the exact 32-byte manifest hash at a specific log position, and the
receipt still binds that hash to our identity key.
What this does NOT prove
Boundaries matter more than features here, so let's be explicit about what a
birth certificate like this is and isn't:
- It is evidence of existence and timestamp. A specific set of file hashes, signed by a specific key, was anchored in a public log and archived with a DOI at a specific time.
- It is not a copyright registration, and it is not a legal opinion. A DOI and a log entry don't adjudicate authorship or rights — they just make the "this existed, in this exact form, at this time" part undeniable.
- Hashes prove identity of bytes, not semantics. If someone takes your code, renames everything, reorders the functions, or has an agent rewrite it line by line, every hash changes and the log anchor won't match. Proving "this derived work is substantially the same code" is a semantic similarity problem — a separate layer sitting on top of the anchor, not something a hash can do. Anchoring is the floor; semantic forensics is the next floor up.
Why now
The direction of travel in AI supply chains isn't subtle: SLSA for build
provenance, Sigstore for signing and transparency logs, SCITT for
industry-wide receipt interoperability, and regulators on both sides of the
Atlantic converging on traceable, auditable AI systems. The reference
implementations that exist during standard formation tend to become the
shapes the standards describe.
We're building toward that as an evidence-infrastructure layer for the AI age —
one primitive that serves two sides: runtime assurance (proving what an agent
actually did) and provenance (proving what an AI asset is, whose it is, and
when it existed). The cryptography reuses the same JCS + Ed25519 receipt
machinery that already passed independent third-party SCITT interop testing
(65/65 cases). Our own receipt format is also documented in an individual
Internet-Draft (draft-correctover-ccs)
— note that's an individual submission, not an RFC and not an IETF endorsement.
But you don't need to care about any of that to use the idea. The practical
takeaway is one line:
Anchor early. A transparency log can't retroactively witness something you
didn't anchor. The first party to put a verifiable stake in the ground owns the
timestamp — forever, independently checkable, with no server to trust.
Go check the anchor:
Rekor log index 2694324795
· DOI 10.5281/zenodo.22266162
Top comments (0)