Verify the cilock binary
Two verification paths, pick the level of rigor you want. Path 2 is strictly stronger than Path 1. Both use only files published on cilock.dev — no GitHub Releases, no platform login.
🟢 30-second integrity check (Path 1)
For most users. Confirms the bytes you downloaded are the bytes the release pipeline published, using the per-archive SHA-256 sidecar:
# OS: linux|darwin ARCH: amd64|arm64
VERSION=v4.1.3
OS=darwin
ARCH=arm64
ARCHIVE="cilock-${VERSION#v}-${OS}-${ARCH}.tar.gz"
BASE="https://cilock.dev/dl/${VERSION}"
curl -fsSLO "${BASE}/${ARCHIVE}"
curl -fsSLO "${BASE}/${ARCHIVE}.sha256"
# The sidecar also lists the release's attestation files — check the archive's line:
grep " ${ARCHIVE}\$" "${ARCHIVE}.sha256" | shasum -a 256 -c - # or: sha256sum -c -
tar xzf "${ARCHIVE}" cilock && ./cilock version
The install script (curl -fsSL https://cilock.dev/install.sh | bash) performs the same check automatically, against the SHA-256 recorded in the signed /dl/manifest.json.
What this proves: integrity — the archive was not corrupted or swapped in transit. It does not prove who built it; that is Path 2.
An independent, pre-execution cosign verification of install.sh itself is planned but not published yet — install.sh.sig/install.sh.cert do not exist today, so any instructions referencing them will fail. Until they ship, Path 1's trust is TLS to cilock.dev plus the release pipeline's verify-then-upload gate; Path 2 removes even that dependency.
🔴 Full provenance verify (Path 2)
For auditors and anyone who wants proof of who built the binary and how. Every release publishes its evidence beside the binary: the build and source-git DSSE envelopes and the platform-signed release policy. A trusted, release-built cilock checks the whole chain fully offline, anchored on the platform trust roots embedded in the verifier at build time — nothing fetched below acts as a trust anchor:
VERSION=4.1.3
PLAT=darwin-arm64
BASE="https://cilock.dev/dl/v${VERSION}"
curl -fsSLO "${BASE}/cilock-${VERSION}-${PLAT}.tar.gz"
curl -fsSLO "${BASE}/cilock-${VERSION}-${PLAT}.build.att.json"
curl -fsSLO "${BASE}/cilock-${VERSION}-${PLAT}.source-git.att.json"
curl -fsSL "https://cilock.dev/policy/release-policy.json" -o release-policy.json
tar xzf "cilock-${VERSION}-${PLAT}.tar.gz" cilock
# Run the verify with a cilock you ALREADY trust — never ./cilock verifying itself:
TRUSTED_CILOCK=/path/to/a/cilock/you/already/trust # e.g. a prior install
"$TRUSTED_CILOCK" verify ./cilock \
--policy release-policy.json \
--attestations "cilock-${VERSION}-${PLAT}.build.att.json" \
--attestations "cilock-${VERSION}-${PLAT}.source-git.att.json" \
--platform-url ""
What this proves: the policy signature chains to the TestifySec Platform Root CA with a valid RFC 3161 timestamp; the build and source-git envelopes were signed by the release workflow's keyless identity; and the binary you extracted is the exact subject those envelopes attest.
Trust note — provenance verification requires a cilock you already trust. Every input above — binary, policy, envelopes — came from the same origin, and so would the verifier if you ran the fresh download: a compromised origin can ship a cilock that simply reports success, no consistent evidence required. So running the downloaded binary against these files is at most a functional smoke check (it executes, the flags parse) — never an authenticity result. Use a previously installed, trusted cilock as the verifier: a release-built cilock embeds the platform Fulcio + TSA roots and the release policy-signer identity (inspect with cilock version), so trust anchors in your binary and the recipe needs no --policy-* trust flags. If your trusted verifier is a stock or source build with no embedded trust, supply --policy-ca-roots/--policy-timestamp-servers from a channel you trust independently of cilock.dev — feeding it the roots published beside the binary hands the download control of its own trust anchors.
The per-version verification block in /dl/manifest.json is the machine-readable index of every file above.
For the fully air-gapped variant of this flow — including verifying with no network at all after one download — see Verify a release offline.
Troubleshooting
policy signature/TSA verifyfailures — you are probably holding the retiredrelease-v1.policy.jsonfrom an old instruction. The current signed policy is only everhttps://cilock.dev/policy/release-policy.json.no attestations satisfied step— both envelopes are required: the policy declares asource-gitstep and abuildstep.- Checksum mismatch in Path 1 — stop; re-download once, and if it persists do not run the binary.