weebo-forgejo

Verify a release

Check the cosign signatures, SBOM and provenance of the images, the chart and the CRD bundle before you deploy them.

Every release is built and published on GitHub Actions by weebo-operator-kit's reusable publish.yml workflow (called by this repository's), and signed keylessly with cosign: there is no long-lived key; each signature carries a certificate that names the workflow and the tag that produced it, recorded in the public Rekor transparency log.

You need cosign 2.x or later.

The identity to expect

FieldValue
OIDC issuerhttps://token.actions.githubusercontent.com
Identityhttps://github.com/batleforc/weebo-operator-kit/.github/workflows/publish.yml@refs/tags/vA.B.C (the kit's workflow, at the kit release this one uses)
Repositorybatleforc/weebo-forgejo (the certificate's GitHub Workflow Repository)

The signing workflow is the kit's, so the identity names the kit; the repository it ran for is checked separately (--certificate-github-workflow-repository).

export COSIGN_ID='^https://github.com/batleforc/weebo-operator-kit/\.github/workflows/publish\.yml@refs/tags/v.*$'
export COSIGN_ISSUER=https://token.actions.githubusercontent.com
export COSIGN_REPO=batleforc/weebo-forgejo

Images

IMAGE=ghcr.io/batleforc/weebo-forgejo-operator:vX.Y.Z   # or vX.Y.Z-static
cosign verify "$IMAGE" \
  --certificate-identity-regexp "$COSIGN_ID" \
  --certificate-github-workflow-repository "$COSIGN_REPO" \
  --certificate-oidc-issuer "$COSIGN_ISSUER"

Verification succeeds for the multi-arch index and each platform image. Then pin what you verified by digest:

DIGEST=$(docker buildx imagetools inspect "$IMAGE" --format '{{json .Manifest}}' | jq -r .digest)
helm upgrade --install weebo-forgejo oci://ghcr.io/batleforc/charts/weebo-forgejo \
  --version X.Y.Z -n weebo-forgejo --set image.digest="$DIGEST"

To enforce signatures at admission, use a policy engine (Sigstore policy-controller, Kyverno verifyImages, …) with the same identity and issuer.

SBOM and provenance

Both are BuildKit attestations attached to the image index:

# SPDX SBOM of the amd64 image
docker buildx imagetools inspect "$IMAGE" --format '{{json (index .SBOM "linux/amd64").SPDX}}'
# SLSA provenance (mode=max: build args, sources, steps)
docker buildx imagetools inspect "$IMAGE" --format '{{json (index .Provenance "linux/amd64").SLSA}}'

Helm chart

The chart is an OCI artifact signed the same way:

cosign verify ghcr.io/batleforc/charts/weebo-forgejo:X.Y.Z \
  --certificate-identity-regexp "$COSIGN_ID" \
  --certificate-github-workflow-repository "$COSIGN_REPO" \
  --certificate-oidc-issuer "$COSIGN_ISSUER"

Note the chart tag has no v prefix.

CRD bundle

weebo-forgejo-crds.yaml on the GitHub Release comes with its Sigstore bundle:

cosign verify-blob weebo-forgejo-crds.yaml \
  --bundle weebo-forgejo-crds.yaml.sigstore.json \
  --certificate-identity-regexp "$COSIGN_ID" \
  --certificate-github-workflow-repository "$COSIGN_REPO" \
  --certificate-oidc-issuer "$COSIGN_ISSUER"

What the pipeline checks before signing

  • The chart version and appVersion (and the Cargo workspace version) equal the tag.
  • The kind end-to-end suite passes on the tagged code, both images, including an upgrade from the previous release.
  • Each image is scanned by trivy (no HIGH/CRITICAL) and smoke-run, before the push for amd64 and on the pushed digest for every platform.

Only then are the image, the chart and the CRD bundle signed and the GitHub Release created.

Next

Migrate an existing Forgejo.

On this page