Release signing key rotation (2026-10-27)

Audience: operators who downloaded or mirror a Stella Ops release bundle.

What changed

Verify a re-signed bundle offline

Download the bundle archive and the SHA256SUMS file of the release from get.stella-ops.org, and obtain the release public key over a separate channel: the website key at /keys/cosign.pub above, saved outside the bundle as public-release-signing.pub. Then, with no further network access:

sha256sum --check --ignore-missing SHA256SUMS
tar -xzpf stellaops-bundle-v1.0.0.tar.gz
cd stellaops-bundle-v1.0.0
cmp ../public-release-signing.pub release-signing.pub
sha256sum release-signing.pub   # 6877ef5b7368aa855cff4343fb665b5b16c08ed053bf8c6050a1dd3193d32f0d
cosign verify-blob --insecure-ignore-tlog=true --key ../public-release-signing.pub \
  --signature release-manifest.yaml.sig release-manifest.yaml
python tools/verify-bundle.py --require-signature --require-digests

Use stellaops-bundle-v1.0.0-RC1 for the RC1 bundle. cmp must print nothing and cosign verify-blob must print Verified OK. The bundle verifier then checks every file against the signed manifest and reports every image digest as pinned. The release uses a pinned offline key without a transparency-log entry; --insecure-ignore-tlog=true skips only that online lookup, not the signature check.

To check an image signature, which needs read access to the registry or a mirror of it, use an exact digest from docker-compose.pinned.yml:

cosign verify --insecure-ignore-tlog=true --key ../public-release-signing.pub \
  registry.stella-ops.org/stellaops/<repository>@sha256:<digest>

A bundle whose release-signing.pub has one of the retired key IDs, or whose manifest signature verifies only with a retired key, predates the rotation. Download the current archive and compare it with the table above.