Show HN: CI/Lock – signed evidence of what your CI ran

colek421 pts0 comments

I helped build Witness, donated it to the CNCF/in-toto ecosystem, and worked on the NIST 800-204D pipeline observer guidance. CI/Lock is the next version of that work, and it s Apache 2.0.Here s the gap it closes. In March two supply-chain attacks hit within a week of each other. Someone force-pushed 75 of 76 version tags in aquasecurity/trivy-action, so every pipeline that had pinned to a tag (the thing we all tell people to do) pulled credential-stealing code on its next run. It read secrets out of /proc/ pid /environ and shipped them to a typosquat. A few days later two litellm releases on PyPI carried a stealer in a .pth file, which Python runs on startup. You didn t have to import it. If the package touched the machine, the code already ran.Both attacks had the same shape: CI ran code it had no reason to trust, with credentials it had no reason to hold, and afterward nobody could prove what actually executed. You could read the workflow file. You couldn t prove what ran.Cilock wraps a command and records what really happened: the command, the files it read, the environment, the artifacts it produced. Then it signs that as an in-toto/DSSE attestation. It s a notary standing next to each build step. cilock run -- go build -o app ./... cilock verify ./app -p release.policy.signed -k policy.pub The policy is signed by a person, with their key, and it says what s allowed to ship. One line matters most to me: the agent writing your code this week (Claude Code, Codex, Cursor) can run the build, gather the evidence, and draft the release, but it can t sign the policy, so it can t decide what ships. The agent did it is not provenance.What s changed since I left Witness:Keyless by default. In GitHub Actions it signs off the runner s OIDC token. No login, no stored secret, no long-lived key to leak. You don t stand up Fulcio or a timestamp authority yourself; one flag derives the hosted endpoints. You can also bring your own key and storage, or run fully offline.It records what ran, not what you declared. ptrace by default (portable, no root), plus an eBPF backend that traces at the kernel boundary; it logs which one fired. Every file each process opens lands in the attestation, so a Rego policy can fail the build on the credential-sweep pattern, like a read of /proc/self/environ. Tracing added about 36% to an npm install in our tests.Per-file digests get committed to an RFC 6962 Merkle root, so you get a real inclusion proof per artifact and a 29,000-file npm install doesn t turn into a 10 MB envelope.It speaks Witness in both directions. Anything Witness produced verifies under cilock, and cilock s shared attestors verify back under Witness, so it drops in next to what you already run. There are 50-plus attestors, each its own Go module, so you can build a binary with only the ones you use.What it is not: cilock is forensic, not a runtime IPS. Detection happens after a step runs, so if that step exfiltrates secrets while it executes, the exfiltration already happened. Cilock blocks the release and leaves a tamper-evident record of it. It watches network egress (connect and sendto syscalls, destination, DNS, TLS SNI) but doesn t block traffic inline the way Harden-Runner does. The trace mode is Linux-only and opt-in.Install: go install github.com/aflock-ai/rookery/cilock/cmd/cilock@latest Your first signed build takes about a minute. Code is at github.com/aflock-ai/rookery.I ll be in the thread today. Ask me anything about the attestation format, the keyless trust model, or how it relates to Witness.dev

code cilock build witness file policy

Related Articles