Skip to main content
Private preview. fremforge is in private preview — invited customers only. Content is still subject to change. Request access →
Cosign signing

Cosign image verification

When your customers pull container images from your registries, they want proof the binary came from a trusted build pipeline and nothing has tampered with it since. Cosign (Sigstore) does that with keyless signing — no long-lived signing keys, no key management drama.

fremforge ships a workflow template (cosign-verify-images.yaml) that walks your repo, finds every digest-pinned image reference, runs cosign verify against it, and reports the result back to fremforge. Results land on /<org>/_admin/code-security/images under a new Cosign column.

Why keyless signing

Traditional code signing requires you to manage a private key — store it in HSMs, rotate it, revoke it when leaked. Cosign keyless takes the OIDC token your CI already has, asks Fulcio (Sigstore’s CA) for a short-lived certificate bound to that identity, and records the signing event in Rekor (Sigstore’s transparency log). Total key custody: zero. Audit trail: full.

For a fremforge customer, this means:

  • Your CI signs container images with whatever OIDC identity it’s running as (the FREMFORGE_API_TOKEN is not the signing identity).
  • Verifiers (you, your downstream customer, fremforge) can cryptographically confirm the image came from that identity at that time.
  • Revocation is irrelevant: the cert was only valid for the few seconds it took to sign.

Workflow template

Install via Org admin → Code security → Container images → Install Cosign workflow, or drop the template at .forgejo/workflows/cosign-verify-images.yaml and let fremforge substitute the placeholders.

The template:

  1. Greps every digest-pinned image reference out of your Helm values, Kubernetes manifests, and docker-compose files.
  2. Runs cosign verify against each with permissive identity regexes (any signed image passes).
  3. POSTs verification results to https://frem.sh/_app/api/v1/cosign/verifications as NDJSON.

You can tighten the identity matching to require signatures from specific OIDC issuers — see the next section.

Per-org enforcement

The tenant_security_policies table carries two new columns:

  • require_signed_images: bool — when true, any unsigned image referenced in your repos raises a finding on /<org>/_admin/code-security/images.
  • require_signed_images_issuer_allowlist: text[] — empty means accept any Fulcio-issued signature; populated means only signatures whose OIDC issuer matches one of the listed entries pass.

Use the allowlist when you want to constrain signers to your own SSO (e.g. https://idp.fremverk.com) rather than accepting any keyless signature.

What “signed” actually means here

A signed image carries an OCI signature object alongside the image manifest in the registry. Cosign creates it, Rekor logs it, the verifier checks both. fremforge stores three things per (tenant, image):

  • signed (bool)
  • signer_subject (the OIDC subject — usually a GitHub Actions / Forgejo workload identity)
  • signer_issuer (the IdP that vouched for it)

For an unsigned image, fremforge stores signed=false and a free-text verification_details capturing why cosign rejected.

See also

  • SBOMs — the what’s in this image side.
  • Image scanning — the what’s vulnerable in this image side.