Skip to main content
Menu

CI/CD integration

Drop hardened images into your CI/CD with a signature check, an SBOM, and a digest pin. The recipes below are intentionally minimal — adapt them to your runner of choice. They are CI-system-agnostic; the Cosign step is the same shape everywhere.

Forgejo Actions

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install cosign
        run: |
          curl -fsSL -o /usr/local/bin/cosign \
            "$COSIGN_URL/cosign-linux-amd64"
          chmod +x /usr/local/bin/cosign

      - name: Verify base image
        run: |
          cosign verify images.rasid.cc/node:22 \
            --key https://rasid.cc/.well-known/rasid-cosign.pub

      - name: Build app
        run: docker build -t myapp:latest .

The base image is images.rasid.cc/node:22 (specify in your Dockerfile). The pipeline verifies the signature against Rasid’s published key, then builds the app.

GitLab CI

verify-base:
  image: alpine:latest
  stage: verify
  script:
    - apk add --no-cache cosign
    - cosign verify images.rasid.cc/node:22
        --key https://rasid.cc/.well-known/rasid-cosign.pub

Generic shell (Jenkins, Buildkite, CircleCI, Drone, any runner)

#!/usr/bin/env sh
set -eu
cosign verify images.rasid.cc/node:22 \
  --key https://rasid.cc/.well-known/rasid-cosign.pub
docker build -t myapp:latest .

Pin by digest in production

For production deploys, do not use floating tags. Pin to a digest:

FROM images.rasid.cc/node@sha256:a1b2c3...

To pick a digest, list the image manifest:

docker buildx imagetools inspect images.rasid.cc/node:22 --raw | jq -r '.config.digest'

This pin keeps your production deploy reproducible across re-builds and immune to upstream rotation, until you choose to update.

Air-gap

For disconnected environments, see the enterprise tier — we ship OCI bundles with signatures, SBOMs, and attestations packed into a tarball that flows across an air-gap.