cosign: sign & verify by identity
Verify who signed, not just that it is signed.
cosign is the tool that makes signing container images and their evidence routine. Signing answers "is this the artifact we produced, unaltered?" — and doing it well is about binding the signature to a known identity and verifying that identity, not merely producing a signature.
Sign and verify, bound to identity
cosign signs an OCI artifact by its digest and stores the signature alongside it in the registry. Verification is where the security lives: you do not just check that a valid signature exists, you check that it was made by the identity you expect — your release workflow, your team’s key. A cryptographically valid signature from an attacker is still not your signature, so a verification policy that accepts "any signature" provides almost no protection. The mental shift is from "is it signed?" to "is it signed by who should have signed it?".
# Keyless sign in CI (identity comes from the workflow's OIDC token):cosign sign registry.acme.internal/api@sha256:9f2c...# Verify — REQUIRE the expected identity, not merely a signature:cosign verify registry.acme.internal/api@sha256:9f2c... \--certificate-identity="https://github.com/acme/api/.github/workflows/release.yml@refs/heads/main" \--certificate-oidc-issuer="https://token.actions.githubusercontent.com"# A signature bound to any other identity fails this check.
Sign the evidence too
cosign signs more than images: it attaches and signs in-toto attestations — provenance, SBOMs, test results — so the whole evidence set is tamper-evident and travels with the artifact by digest. This is what lets an admission gate later demand "signed by our pipeline AND carrying signed SLSA provenance AND a signed SBOM". Signing is one pillar of trust; it pairs with provenance (how it was built) and SBOMs (what is inside), and none of the three replaces the others.