Securing Your Supply Chain with Container Image Signing (Cosign)

Container supply chain attacks represent a major security risk today. Deploying container images without verifying their authenticity leaves clusters vulnerable to image spoofing and malicious tampering. Cosign, developed as part of the Sigstore project, allows teams to sign container images and store cryptographic signatures directly within standard OCI registries.
Why Keyless Signing?
Traditional PKI implementations, such as Docker Content Trust, usually present administrative overhead because they require managing offline root keys and maintaining long-term credentials. Cosign simplifies this by offering keyless signing powered by OpenID Connect (OIDC). Instead of generating and protecting permanent key pairs, your CI/CD runner requests temporary identity certificates to automatically sign images during the build process.
GitHub Actions Workflow Example
Below is a continuous integration workflow configuration that builds, signs, and pushes a container image utilizing GitHub's OIDC identity provider:
jobs:
build-and-sign:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write # Required for keyless signing
steps:
- name: Install Cosign
uses: sigstore/cosign-installer@v3
- name: Build and Push id: docker_build uses: docker/build-push-action@v4 with: push: true tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Sign the image env: TAGS: ghcr.io/${{ github.repository }}:${{ github.sha }} DIGEST: ${{ steps.docker_build.outputs.digest }} run: | cosign sign --yes \ -a "repo=${{ github.repository }}" \ -a "workflow=${{ github.workflow }}" \ -a "sha=${{ github.sha }}" \ ghcr.io/${{ github.repository }}@${DIGEST}
Workflow Breakdown
id-token: write: Grants the workflow permission to request an OIDC JWT token from GitHub. Sigstore's Fulcio Certificate Authority uses this token to issue a short-lived signing certificate linked exclusively to this specific workflow run.DIGEST: ${{ steps.docker_build.outputs.digest }}: Retrieves the immutable SHA256 digest of the compiled image. Signing via digest instead of mutable tags (such aslatest) eliminates potential race conditions where a tag might be reassigned between build and signature steps.cosign sign --yes: Executes the signing operation in non-interactive mode, making it suitable for automated CI runners.-a "repo=...": Embeds custom metadata annotations into the signature payload. When enforcing security policies, you can verify that the image originated from your specific repository and pipeline rather than an arbitrary Sigstore user.ghcr.io/...@${DIGEST}: Stores the signature artifact directly within the target OCI registry associated with the image digest.
Adopting this strategy within your CI/CD pipeline ensures that every container image deployed to your environment carries a verifiable, keyless signature.