Verifying a Release
Every image published from 3.0.0 onward is signed with Sigstore cosign,
and carries an SPDX software bill of materials and SLSA build provenance. Signing is keyless and happens inside
the GitHub Actions release workflow, so there is no private key anywhere - the signature is tied to the workflow
that built the image.
Two commands cover it. They name 3.0, the minor tag for this line; any tag or digest pointing at a signed
image works the same way.
cosign verify binacle/binacle-net:3.0 \
--certificate-identity-regexp '^https://github\.com/binacle-labs/Binacle\.Net/\.github/workflows/release-docker-image\.yml@refs/heads/main$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
docker buildx imagetools inspect binacle/binacle-net:3.0
Releases before
3.0.0cannot be verified.2.1.1and everything earlier were published before the signing pipeline existed, socosign verifyanswersno signatures foundagainst them. The check has not failed; there is nothing there to check.
π οΈ Install cosign
cosign is a single binary. Install it from the Sigstore docs or download it
from the cosign releases page. docker buildx already ships
with Docker.
Use cosign 2.6.0 or later, or 3.0.1 or later. Sigstore is moving the public transparency log that signatures are recorded in, and older builds cannot read entries in the new one. An out-of-date binary fails the check the same way a tampered image would.
π Why both cosign flags matter
Drop --certificate-identity-regexp and you are only asking whether anyone signed the image. Anyone can:
Sigstore is open to every GitHub account, and a signature on its own says nothing about who made it. The two
flags together are the whole check - the issuer says the identity came from GitHub Actions, and the identity
pattern says it was this repositoryβs release workflow.
The pattern ends @refs/heads/main$. That last part is the branch the release workflow is dispatched on, and
the $ closes the pattern there. Without it the pattern matches anything after the @, so a signature made
from any branch in this repository would pass the check - and pushing a branch is not a release.
The signature covers the image digest, not the tag. So it holds for the 3.0 and latest tags as well as
the exact version tag: whichever one you verify, you are verifying the same artifact.
π§Ύ Reading the attestations
docker buildx imagetools inspect lists what is in the image index: the platform manifests, plus one
attestation manifest per platform holding the SPDX bill of materials and the SLSA provenance.
The bill of materials is the package list - every OS package and .NET assembly in the image, with versions. It is what you feed to a scanner or check a CVE against. The provenance records how the image was built: the workflow, the run, and the source commit it came from.
π What a checked release looks like
So you know the shape of a real answer before you run it yourself:
cosign verify prints the checks it performed - the claims were validated, and the entry was found in the
transparency log - then the certificate it matched. Read that certificate: it names the release workflow and
the branch it ran on, which is what the identity pattern above pins down.
docker buildx imagetools inspect prints the digest the tag resolves to, then the manifests described above.
The image config in the same output shows the container runs as app (1654) rather than root, with
/app/data owned app:app 755 - the writable folder for a mounted database or key ring.
If the attestation manifests are missing, you are not looking at a release image.
π¦ What a pass means, and what it does not
A passing verify proves the image came from this repositoryβs release workflow and has not been altered since. That is a strong claim about origin.
It is not a claim about safety. A signature says nothing about the vulnerabilities in what was signed - a genuine image with a known CVE in it verifies perfectly. For that question, read the bill of materials and scan it.
Contributors with a clone can run
just image verify 3.0.0, which runs four checks against a published image in one go.