Securing Your Supply Chain with Container Image Signing (Cosign)
How I built a reliable WhatsApp AI shopping assistant for Clickmothercare that survives hallucinated products, silent save failures, and multi-agent handoff bugs.
Supply chain attacks have moved from theory to daily reality. If you are blindly pulling images from public registries without verifying their provenance, you are exposed to image spoofing and tampering. Cosign, part of the Sigstore project, provides a developer-friendly mechanism for signing container images and verifying them via OCI registries.
The Challenge: Verifying Image Provenance
Traditional PKI for image signing (like Docker Content Trust) is often complex to manage, requiring offline root keys and extensive operational overhead. We need a streamlined way to embed signatures directly into the registry alongside the image.
The Solution: Keyless Signing with Cosign and GitHub Actions
Cosign supports "keyless" signing by integrating with OpenID Connect (OIDC). Here is a robust GitHub Actions workflow snippet that builds, signs, and pushes an image without ever generating or storing long-lived cryptographic keys.
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}
Pipeline Code Deep Dive
Let's examine the crucial segments of this workflow that ensure cryptographic integrity:
id-token: write: This is the linchpin of keyless signing. It grants the workflow permission to request an OIDC JWT from GitHub, which Sigstore's Fulcio CA uses to issue a short-lived certificate bound to this exact workflow run.DIGEST: ${{ steps.docker_build.outputs.digest }}: We capture the SHA256 digest of the built image. Signing by digest, rather than by mutable tags (likelatest), prevents race conditions where a tag is reassigned between the push and sign steps.cosign sign --yes: Executes the signing process. The--yesflag bypasses the interactive confirmation, essential for automated CI environments.-a "repo=...": These are annotations. We are embedding cryptographic metadata into the signature payload itself. During verification, you can assert not just that the image was signed, but that it was signed by this specific repository's workflow, thwarting attacks where a malicious actor uses their own valid Sigstore certificate to sign a rogue image.ghcr.io/...@${DIGEST}: Targets the immutable digest for the signature upload. The signature is pushed to the OCI registry as an attached artifact.
By integrating this into your CI/CD, you establish an auditable, cryptographically secure chain of custody for every artifact entering your deployment pipeline.
Is your AI agent's infrastructure secure and reliable?
Book a Free 15-Min Technical Audit