Verify a Candle release
Every Candle CLI release on https://github.com/candledottv/agentic/releases is built and signed by
that repository’s release.yaml workflow. Nothing else signs releases; there is no long-lived key
to steal. Three checks: the checksum, then two that check the signature and the exact release tag.
1. Checksum
Section titled “1. Checksum”curl -fsSLO https://github.com/candledottv/agentic/releases/download/cli-v0.11.14/SHA256SUMScurl -fsSLO https://github.com/candledottv/agentic/releases/download/cli-v0.11.14/candle-darwin-arm64grep candle-darwin-arm64 SHA256SUMS | shasum -a 256 -c2. Provenance with the GitHub CLI
Section titled “2. Provenance with the GitHub CLI”gh attestation verify candle-darwin-arm64 --repo candledottv/agentic \ --cert-identity https://github.com/candledottv/agentic/.github/workflows/release.yaml@refs/tags/cli-v0.11.14--cert-identity is the signing certificate’s subject: the workflow file and the release tag in
one string. Pinning it exactly pins both, so an attestation the same workflow minted for a
different tag does not verify. Change the tag to the release you downloaded. This is the check
install.sh runs when it verifies with gh. Pass the flag on its own: gh treats its identity
flags (--cert-identity, its regex form and the two signer flags) as mutually exclusive, and the
signer-workflow flag alone would accept any tag’s attestation.
3. The signature with cosign
Section titled “3. The signature with cosign”curl -fsSLO https://github.com/candledottv/agentic/releases/download/cli-v0.11.14/candle-darwin-arm64.sigstore.jsoncosign verify-blob --new-bundle-format --bundle candle-darwin-arm64.sigstore.json \ --certificate-identity https://github.com/candledottv/agentic/.github/workflows/release.yaml@refs/tags/cli-v0.11.14 \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ candle-darwin-arm64A signature proves the file was built by that workflow, from the commit the provenance names, for
that tag. As in check 2, --certificate-identity pins the exact tag: change it to the release you
downloaded. The regex form, --certificate-identity-regexp '^https://github.com/candledottv/agentic/\.github/workflows/release\.yaml@refs/tags/cli-v',
is weaker: it accepts a signature minted for any cli-v tag, so an older signed binary would pass
for a newer download. candle update runs this check in process, pinned to the exact version,
before it replaces the binary; the installer runs it with the exact identity when cosign or gh is
available, and always runs check 1.
--new-bundle-format says “expect a Sigstore bundle”, which is what Candle releases from 0.6.1
onward are signed as. Cosign also reads an older bundle format of its own, so leaving the flag off
would quietly accept a shape that candle verify cannot read. It needs cosign 2.2 or newer. The
one release signed the old way, cli-v0.6.0, verifies with cosign and gh but not with
candle verify; run check 1 or check 2 on it instead.
No cosign or gh to install? If any working candle binary is already on the machine (an older
release, one installed via Homebrew, or one built from source), it carries the same trusted root
compiled in and can run the same check on its own, no network call and nothing else installed:
curl -fsSLO https://github.com/candledottv/agentic/releases/download/cli-v0.11.14/latest.jsoncandle verify candle-darwin-arm64 --bundle candle-darwin-arm64.sigstore.jsonlatest.json sits beside the other assets in every release, so downloading it alongside the
bundle is what lets candle verify resolve the expected identity on its own; pass --identity
instead if you would rather not fetch it (it is required when no latest.json is beside the
bundle). --issuer overrides the expected OIDC issuer, https://token.actions.githubusercontent.com
by default. This is the same call candle update makes in process
before it replaces itself.
Archives
Section titled “Archives”Each release also ships candle-<version>-<os>-<arch>.tar.gz for the four platforms, holding
candle, candle-fido2 and LICENSE; Homebrew installs from these. They are listed in
SHA256SUMS and carry build provenance, but they have no .sigstore.json of their own, so check 1
and check 2 apply to them and check 3 does not. Once unpacked, the candle and candle-fido2
inside are the same files as the signed binaries, and their SHA256SUMS lines match.
The installer script itself
Section titled “The installer script itself”curl -fsSL https://candle.tv/install.sh | bash is the friendly line. The same script is a signed
asset of every release, so you can fetch it pinned to a tag and check it before running it:
curl -fsSLO https://github.com/candledottv/agentic/releases/download/cli-v0.11.14/install.shcurl -fsSLO https://github.com/candledottv/agentic/releases/download/cli-v0.11.14/install.sh.sigstore.jsoncosign verify-blob --new-bundle-format --bundle install.sh.sigstore.json \ --certificate-identity https://github.com/candledottv/agentic/.github/workflows/release.yaml@refs/tags/cli-v0.11.14 \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ install.shbash install.shor from the source tree at the tag: curl -fsSL https://raw.githubusercontent.com/candledottv/agentic/cli-v0.11.14/install.sh.
The script’s SHA-256 for each release is the install.sh line of that release’s SHA256SUMS.
The script refuses to install without a verifier (cosign, or a logged-in gh), and nothing is
installed. On a host where you cannot or do not want to add one, verify on another machine and
carry the files across, as in the next section. CANDLE_INSTALL_ALLOW_UNSIGNED=1 exists as an
explicit opt-out: it installs on the checksum alone, which proves only that the file matches the
list downloaded beside it, and prints the command to verify afterwards.
A host with no verifier
Section titled “A host with no verifier”A bot box, a locked-down server, or anything else with no cosign, no gh and no candle yet. Do
the signature check on a machine you trust, then move the verified files to the host and check
only that they arrived intact.
On the trusted machine, which has cosign, a logged-in gh, or a working candle. Pick the
host’s platform (linux-x64, linux-arm64, darwin-arm64 or darwin-x64), not this machine’s:
tag=cli-v0.11.14asset=candle-linux-x64base=https://github.com/candledottv/agentic/releases/download/$tagcurl -fsSLO $base/$assetcurl -fsSLO $base/$asset.sigstore.jsoncurl -fsSLO $base/SHA256SUMScurl -fsSLO $base/SHA256SUMS.sigstore.jsoncurl -fsSLO $base/latest.jsoncandle verify $asset --bundle $asset.sigstore.json # or check 2 or check 3 abovecandle verify SHA256SUMS --bundle SHA256SUMS.sigstore.jsongrep " $asset\$" SHA256SUMS | shasum -a 256 -cBoth signatures must verify and the checksum must print OK before anything moves. Then copy
the binary, SHA256SUMS and the two bundles to the host:
scp candle-linux-x64 candle-linux-x64.sigstore.json SHA256SUMS SHA256SUMS.sigstore.json bot-box:On the host, check the binary against the line of the SHA256SUMS you verified, then install
it:
grep ' candle-linux-x64$' SHA256SUMS | sha256sum -c # macOS: shasum -a 256 -cmkdir -p ~/.local/bin && install -m 755 candle-linux-x64 ~/.local/bin/candlecandle --versionsha256sum -c must print candle-linux-x64: OK. Anything else means the copy is not the file you
verified: delete it and copy again. Once candle is on the host it is its own verifier:
candle update checks each new release’s signature in process before it replaces itself, and
candle verify checks any other asset, with nothing else installed.
The host does not need candle-fido2 unless a security key will be plugged into it; a bot box
never needs it. If it does, carry candle-fido2-<platform> the same way, verified with its own
.sigstore.json and its SHA256SUMS line, and install it beside candle.
The transparency log
Section titled “The transparency log”Every signature is recorded in Sigstore’s public log (Rekor). To list the entries for a release,
take the SHA-256 of its SHA256SUMS from the release page and run
rekor-cli search --sha <sha256>; a release has exactly one.