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.