# sigstore/cosign: signing containers and binaries without running a CA

> Cosign stores signatures in the OCI registry next to the image and, by default, gets its signing certificate from Sigstore's Fulcio authority. Here is how the keyless flow works, how to install it, and where it stops being the right tool.

**sigstore/cosign** — Code signing and transparency for containers and binaries

- Repository: https://github.com/sigstore/cosign
- Stars: 6,339 · Forks: 814
- Language: Go
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/sigstore-cosign

## The problem cosign solves: proving an image digest is the one you signed

A container tag is mutable. The README states it plainly: sign images based on their digest (`@sha256:...`) rather than a tag (`:latest`), "because otherwise you might sign something you didn't intend to!" That single sentence is the whole reason the tool exists. If you push an image and later move the tag, a signature over the tag proves nothing about the bytes a cluster will pull.

Cosign's answer is to sign the digest and store the signature in the OCI registry alongside the image. Verifiers then check the signature against the digest they are about to run. The audience is release engineers, platform teams and anyone building admission policy for a Kubernetes cluster, plus maintainers who publish binaries and want a verifiable release artifact. It is a CLI, not a server you host, which matters for adoption cost.

## Keyless signing, Fulcio certificates and the Rekor transparency log

The default path is what the README calls "keyless signing" with the Sigstore public good Fulcio certificate authority and the Rekor transparency log. The mechanism, as the README describes it: cosign generates ephemeral keys, opens a browser for OIDC authentication, and requests a code signing certificate from Fulcio. The subject of that certificate matches the email address you logged in with.

Cosign then stores the signature and the certificate in Rekor and uploads the signature to the OCI registry alongside the image. Nothing long-lived is written to your disk on the signing side, which is why the project describes signatures as "invisible infrastructure".

The consequence is that verification cannot be a bare signature check. Because the certificate is short-lived and bound to an identity, the verifier has to state which identity and which issuer it accepts. That is why `cosign verify` requires `--certificate-identity` and `--certificate-oidc-issuer`. A signature that verifies cryptographically but names an identity you did not expect is not a pass. Cosign also accepts `--certificate-identity-regexp` and `--certificate-oidc-issuer-regexp` when you need to match a set of identities, for example every workflow in an organisation.

The README is explicit that keyless signing is not anonymous. Before continuing, cosign warns that there may be personally identifiable information associated with the signed artifact, including the email address tied to the account you authenticate with, and that this information is stored in public transparency logs and cannot be removed later. That is a design decision, not a bug, and it is the first thing to weigh if your organisation is strict about metadata egress.

## Installing cosign and signing your first image

The README points to the installation docs for Homebrew, Arch, Nix, GitHub Action and Kubernetes installs, and to the GitHub release assets for Linux and macOS binaries. Note the deprecation notice: downloads from the project's GCS bucket were deprecated on July 31, 2023, so release assets are the documented route.

If you have Go 1.22 or newer, the developer installation clones the repository and builds the CLI from source:

```bash
git clone https://github.com/sigstore/cosign
cd cosign
go install ./cmd/cosign
$(go env GOPATH)/bin/cosign
```

The last line runs the binary from your GOPATH so you can confirm it is on the path. The module in `go.mod` is `github.com/sigstore/cosign/v3` and declares `go 1.26.0`, so a source build against the current main line needs a newer toolchain than the README's stated Go 1.22 floor.

For a container-based install, the README gives a Dockerfile that copies the binary out of the published image:

```dockerfile
FROM ghcr.io/sigstore/cosign/cosign:v2.4.1 as cosign-bin

FROM cgr.dev/chainguard/static:latest
COPY --from=cosign-bin /ko-app/cosign /usr/local/bin/cosign
ENTRYPOINT [ "cosign" ]
```

Once you have the binary, signing an image is one command. Substitute your image reference, ideally pinned by digest:

```bash
cosign sign $IMAGE
```

The README shows what follows: cosign prints "Generating ephemeral keys..." and "Retrieving signed certificate...", displays the personally identifiable information warning, and asks you to confirm with `y`. A browser opens to the Sigstore OAuth endpoint. After you authenticate you should see "Successfully verified SCT...", a transparency log entry index, and a line confirming the signature was pushed to the image. Verification then needs the identity and issuer you expect:

```bash
cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
```

If you prefer a plain keypair instead of the Fulcio flow, `cosign verify --key cosign.pub $IMAGE_URI:1h` is the documented form. The README notes this returns `0` if at least one cosign-formatted signature matching the public key is found, and prints any valid payloads to stdout as JSON. Those payloads include the image digest, which is how a detached signature is tied to the right image.

## Where cosign is the wrong tool

Keyless signing depends on the Sigstore public good infrastructure. If your environment cannot reach the Fulcio and Rekor endpoints, or if policy forbids publishing signing metadata to a third party, the default flow is unusable. The README does list alternatives in the same tool: hardware and KMS signing, a cosign-generated encrypted private and public keypair, and bring-your-own PKI. Those shift the trust question back to key custody, which is the problem keyless signing was meant to remove.

There is a second boundary. Cosign signs artifacts and stores signatures; it does not decide whether an image should run. The README describes verification commands and their exit behaviour, not an admission controller. Turning a passing `cosign verify` into a cluster policy is work you do elsewhere.

A third point is project direction. The README states that future cosign development will focus on the next major release based on sigstore-go, and that maintainers will focus feature development within sigstore-go. It also says PRs which significantly modify or break the API will not be accepted, and that large non-breaking PRs are lower priority than PRs in sigstore-go. Cosign 2.x is described as a stable release that will continue to receive periodic feature updates and bug fixes. Read that as a signal about where new work lands, not as an abandonment notice: the repository is not archived and the last push was on 2026-09-21.

## How cosign differs from Notary, attest and a plain GPG signature

The closest comparison in the container world is Notary, which grew out of The Update Framework and the Docker Content Trust model. Notary's approach centres on a trusted collection with delegated signing keys and a server-side trust data repository; cosign's approach is to put the signature in the same OCI registry as the image, so there is no separate trust server to operate for storage. That is a real architectural difference: fewer moving parts for the publisher, but it also means the registry you already trust becomes part of your verification path.

Against a plain GPG signature over a tarball, cosign's difference is the identity model. A GPG signature says a key signed bytes; the key-to-person mapping is your problem. The keyless flow binds the certificate subject to an OIDC identity and records the signing event in a transparency log, so a verifier can check who signed and when. The cost is the dependency on Fulcio and Rekor described above.

Attestation is a different axis rather than a competitor. Cosign handles signatures and, per the README, supports in-toto style flows through its dependency set; signing an image says the digest is the one you approved, while an attestation says something about how it was built. Teams often need both, and conflating them leads to verification policies that check the wrong thing.

## Version lines, licence and what an upgrade actually costs

Two release lines are visible in the recent releases: v3.1.3 and v2.6.5, both dated 2026-08-06, with v3.1.2 before them on 2026-07-17. The repository also carries a VERSIONING.md file at the top level, which is where the project documents its own policy rather than in the README. If you are pinning cosign in CI, pin a specific release and read that file before assuming a v2 to v3 jump is mechanical.

Licensing is Apache-2.0. The repository includes LICENSE and COPYRIGHT.txt, and the Dockerfile and Makefile carry the standard Apache header. Apache-2.0 permits commercial use and modification and includes a patent grant; it also requires that you preserve notices and state changes. It does not, on its own, settle questions about the Sigstore public good services you interact with at runtime. That is a policy question for your organisation, not a licence question.

The upgrade cost that is easy to miss is not the binary, it is the verification side. If you move between major lines or adopt the sigstore-go based release, the flags your verifiers pass and the identities they pin are the part that breaks pipelines. Keep the `--certificate-identity` and `--certificate-oidc-issuer` values in configuration you can review, not hardcoded in a shell script.

## Conclusion

Adopt cosign if you publish OCI images or release binaries and want a signature that lives in the registry next to the artifact, with keyless signing as the default path. Do not adopt it if your policy forbids any artifact metadata leaving your infrastructure, since keyless signing writes to public transparency logs and the README says that information cannot be removed later. Before rolling it out, verify which cosign release your platform packages ship (v3.1.3 and v2.6.5 are separate lines), and confirm the exact --certificate-identity and --certificate-oidc-issuer values your verifiers will pin, because a verification without them does not establish who signed.

## FAQ

### How do I install cosign on Linux or macOS?

The README directs Linux and macOS users to the GitHub release assets, and points to the installation docs for Homebrew, Arch, Nix, GitHub Action and Kubernetes installs. Downloads of releases from the project's GCS bucket were deprecated on July 31, 2023, so use the release assets instead.

### How do I use cosign to sign a container image?

Run cosign sign with the image reference, ideally pinned by digest rather than a tag. Cosign generates ephemeral keys, opens a browser for OIDC authentication, requests a certificate from Fulcio, writes the signature and certificate to Rekor, and pushes the signature to the OCI registry alongside the image.

### How do I install cosign on Windows?

The README does not give Windows-specific steps. It points to the installation docs for Homebrew, Arch, Nix, GitHub Action and Kubernetes installs, and to the GitHub release assets for Linux and macOS binaries, so check those sources for a supported Windows path.

### How do I install cosign on Ubuntu?

The README does not list an Ubuntu-specific package. It points to the installation docs for Homebrew, Arch, Nix, GitHub Action and Kubernetes installs, and to the GitHub release assets for Linux and macOS binaries, which is the documented route for Linux distributions.

### How do I install cosign?

For Homebrew, Arch, Nix, GitHub Action and Kubernetes installs the README points to the installation docs; for Linux and macOS binaries it points to the GitHub release assets. With Go 1.22 or newer you can also clone the repository and run go install ./cmd/cosign.

## Sources

- [Issues](https://github.com/sigstore/cosign/issues)
- [License: Apache-2.0](https://github.com/sigstore/cosign/blob/main/LICENSE)
- [README](https://github.com/sigstore/cosign/blob/main/README.md)
- [Releases](https://github.com/sigstore/cosign/releases)
- [sigstore/cosign on GitHub](https://github.com/sigstore/cosign)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sigstore-cosign
