Skip to content

Quickstart

A key-free, copy-paste walkthrough: sign a first-party image, verify it offline, and render an admission policy. It uses a local registry so you can run it end to end on one machine.

Prerequisites

  • Go 1.26+ (make build), or a released gapsign binary
  • A container registry. For this walkthrough, a local one:
    $ docker run -d -p 5000:5000 --name reg registry:2
    

1. Generate a signing key

$ gapsign keygen
wrote ~/.config/gapsign/cosign.key (private, 0600) and ~/.config/gapsign/cosign.pub (public)
distribute the .pub to verifiers via GitOps; never commit the .key

The public key is the trust anchor you distribute; the private key stays local (mode 0600) and is never committed.

2. Sign a first-party image

$ docker pull -q alpine:3.19 && docker tag alpine:3.19 localhost:5000/app:v1 && docker push -q localhost:5000/app:v1

$ gapsign sign -key ~/.config/gapsign/cosign.key -insecure localhost:5000/app:v1
signed localhost:5000/app@sha256:7dc2e94a...
  signature: localhost:5000/app@sha256:8cbed0e3...

gapsign resolves the tag to an immutable digest, signs the digest, and pushes the signature as an OCI artifact next to the image.

3. Verify offline (fail-closed)

$ gapsign verify -pub ~/.config/gapsign/cosign.pub -insecure localhost:5000/app:v1
verified localhost:5000/app@sha256:7dc2e94a...

An unsigned image, a wrong key, or a signature for a different digest all exit non-zero — gapsign fails closed. The signature is also verifiable by stock cosign (cosign verify --key cosign.pub --insecure-ignore-tlog ...).

4. Render an admission policy

$ cat > policy.yaml <<'EOF'
policies:
  - match: "localhost:5000/*"
    signer: ci
    require: signed
EOF
$ cat > config.yaml <<EOF
backend: cosign-key
signer_name: ci
policy: $PWD/policy.yaml
trust:
  ci:
    public_key: $HOME/.config/gapsign/cosign.pub
EOF

$ gapsign policy render -config config.yaml -o kyverno-policy.yaml
wrote kyverno-policy.yaml

kyverno-policy.yaml is a fail-closed Kyverno ClusterPolicy — apply it via GitOps. It verifies signatures against the embedded public key, offline, and blocks unsigned images on the matched repositories. See Admission enforcement.

Next