Show HN: CI/lock – supply-chain attestation CLI, from the Witness creators

colek421 pts0 comments

The signed record we didn't have in March | CI/lock

Skip to main content<br>I've spent a decade on this problem. I helped build Witness, we donated it to the CNCF and in-toto, and I helped write the reference architecture people point at when they talk about securing the software supply chain. The good news is the rest of the industry is converging on the premise: provenance and attestation are where software trust is heading. The harder part is getting there. So when I tell you the tooling still wasn't good enough, I'm including my own.

In March, two attacks landed within days of each other.

The first hit aquasecurity/trivy-action. An attacker force-pushed 75 of 76 version tags — rewrote the history under tags people had already pinned. If your pipeline referenced one of those tags, and most did, your next run pulled credential-harvesting code. It read secrets out of /proc//environ, encrypted them, and sent them to a typosquat domain. The advice we'd all given — "pin to a tag, don't float on latest" — is exactly what got people hit.

The second was litellm. Two malicious releases on PyPI carried a stealer in a .pth file, which Python executes on interpreter startup. You didn't have to import anything. If the package was ever on the machine, the code already ran.

Two different ecosystems, one shape: CI executed code it had no reason to trust, holding credentials it had no reason to hold, and afterward nobody could produce a signed record of what actually ran. You could read the workflow file. You couldn't prove what executed.

The same gap, now with agents​

If that threat model feels abstract, look at how code gets written this week. An AI agent writes it. The agent edits the workflow. The agent opens the PR and, in plenty of shops, the agent triggers the release. The human in the loop is skimming a diff late at night, or there's no human at all — just another agent reviewing the first one.

I'm not anti-agent. We build with them every day. But "the agent did it" is not provenance, and the permissions you hand an agent are the permissions a poisoned dependency inherits. The fix isn't to slow the agent down. It's to put a gate at the end that the agent cannot open by itself.

What CI/lock actually does​

Wrap any command:

cilock run -- go build -o app ./...

CI/lock records what ran: the command, the inputs it read, the environment, the artifacts it produced. It signs that record — keyless, so there are no long-lived keys to leak — and you get your first signed attestation in about 60 seconds.

Then you gate on it:

cilock verify ./app --policy release.policy

The policy is signed by a human, with their key. It says what's allowed to ship. The agent can do everything else — run the build, gather the evidence, draft the release — but it can't sign the policy, so it can't decide what ships. That line, between "did the work" and "decided what ships," is the whole point.

It's Apache 2.0, and it speaks Witness in both directions, so it drops into what you already have instead of asking you to rip anything out. It runs where your agent already runs: Claude Code, Codex, Cursor.

Built for how we ship now​

The tooling we built to secure the supply chain assumed a human doing the setup by hand, at human speed. An agent is already three commits deep before you've finished reading the docs. CI/lock is what Witness taught me, rebuilt for that: same lineage, with the bug fixes we found auditing the upstream code. What's new is who it's for. The first-class user is your agent.

Point your agent at a goal like "get this build to SLSA Level 3" and it can take you there. CI/lock is the engine: it emits SLSA Provenance and in-toto evidence at every step, signs it, and verifies it against Rego policy you write. The evidence then flows into the TestifySec platform, which maps it onto the frameworks you answer to — FedRAMP, SOC 2, NIST 800-53. A compliance report stops being a project you dread and becomes a read of evidence you already have.

And the part people dread most is already done: you don't stand up Fulcio, a timestamp authority, or any Sigstore plumbing. The platform hosts it. In CI you don't even log in — signing uses your runner's ambient OIDC token, keyless, no secrets. cilock login only matters when you want attestations stored on the platform. No CA to operate, no keys to rotate.

If you're already running Witness​

You don't have to switch tools to get any of this. CI/lock is the in-tree continuation of Witness: anything you produced with Witness verifies under CI/lock unchanged, and CI/lock's shared-format attestations verify back under Witness. Here's what the next iteration adds.

What it doesWitnessCI/lock (in-tree continuation)Attestation formatThe donated in-toto/Witness project and the reference implementation. The DSSE/in-toto format the rest of the ecosystem reads.The same format. Anything Witness produced verifies under CI/lock, with legacy type aliases registered at startup, and CI/lock's...

agent lock witness already code build

Related Articles