Files
certctl/docs/reference/release-verification.md
shankar0123 426760d737 docs: Phase 13 — README rewrite to 250-line target
Per Phase 1 audit at cowork/docs-overhaul-phase-1-audit-2026-05-04/.
README went from 457 lines to a target of 250 (operator decision in
Phase 1 conversation). Focus shifts from feature-catalog + landing-page
duplicate to "developer cloning the repo needs orientation + quickstart
+ entry points to docs."

What stayed:
  - Logo + title + badges (~15 lines)
  - Elevator paragraph + 47-day cliff context (3 paragraphs, compressed)
  - Active-maintenance callout
  - Documentation table — restructured from 22 entries linking to flat
    docs/ to ~6 audience-organized rows linking through the new
    docs/README.md navigation index
  - Screenshots grid (4 tiles)
  - "What it does" — compressed from 33 lines of prose to 8 capability
    bullets, each linking to the canonical doc
  - Architecture paragraph — compressed to one paragraph linking to
    docs/reference/architecture.md
  - Quick Start (Docker Compose, Agent install, Helm, container images)
  - Examples table (5 turnkey scenarios)
  - Development commands
  - License paragraph
  - Dependencies block
  - Footer CTA

What got moved out:
  - Cosign verification / SLSA / SBOM section (67 lines) →
    docs/reference/release-verification.md (NEW). README links to it
    in a 3-line "Verifying a release" section.

What got removed entirely:
  - "Why certctl" + "Architecture" + "Security-first" + "Key design
    decisions" prose walls — duplicated landing page + architecture.md +
    security.md content. README no longer wades through 11 dense
    paragraphs.
  - "Supported Integrations" 4 sub-tables (Issuers / Targets / Protocols
    / Standards / Notifiers, ~80 lines of dense per-row marketing
    copy) — content lives at docs/reference/connectors/index.md and
    docs/reference/protocols/. README mentions counts ("12 issuers, 15
    targets, 6 notifiers") with a single link.
  - "Roadmap" section entirely — V1 + V2 history rotted fastest of any
    section; replaced with implicit "see Releases + Issues for active
    work" via the existing footer CTA.
  - "What It Does" 10-subsection wall (33 lines) — replaced with the
    8-bullet capability list, each linking to its canonical doc.
  - CLI section (20 lines of inline command examples) — links to the
    contributor docs.
  - MCP Server section (30 lines of setup) — links to docs/reference/mcp.md.

New surface added:
  - docs/reference/release-verification.md — moved cosign/SLSA/SBOM
    procedure with one expanded "Why this matters" paragraph
    explaining the keyless OIDC trust anchor.

Every docs/ link in the new README verified to resolve to an existing
file. Cross-references from other docs / certctl.io to the deleted
sections (if any) need follow-up Phase 11 sweeps.
2026-05-05 03:26:05 +00:00

3.4 KiB
Raw Permalink Blame History

Release Verification

Last reviewed: 2026-05-05

certctl ships signed, attested release artefacts on every v* tag. This guide covers verifying those signatures and attestations before deploying.

What gets signed

Every v* tag publishes:

  • Binaries: certctl-agent, certctl-server, certctl-cli, certctl-mcp-server for linux|darwin × amd64|arm64
  • A checksums.txt covering every binary
  • Per-binary SPDX-JSON SBOMs
  • Cosign signatures (keyless OIDC, signing identity = the release workflow on a signed tag)
  • SLSA Level 3 provenance

Container images on ghcr.io/certctl-io/certctl-{server,agent} are built with docker/build-push-action provenance: mode=max + sbom: true and additionally signed with Cosign at the image digest.

Verification procedure

1. Verify SHA-256 checksums

sha256sum -c checksums.txt

2. Verify the Cosign signature on checksums.txt

cosign verify-blob \
  --bundle checksums.txt.sigstore.json \
  --certificate-identity-regexp '^https://github\.com/certctl-io/certctl/\.github/workflows/release\.yml@refs/tags/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  checksums.txt

Every individual binary ships with its own .sigstore.json bundle (unified Sigstore bundle containing signature, certificate chain, and Rekor inclusion proof). Swap checksums.txt for any binary name and point --bundle at the matching <binary>.sigstore.json to verify it directly.

3. Verify SLSA Level 3 provenance on a binary

slsa-verifier verify-artifact \
  --provenance-path multiple.intoto.jsonl \
  --source-uri github.com/certctl-io/certctl \
  --source-tag v2.1.0 \
  certctl-agent-linux-amd64

Replace v2.1.0 with the tag you're verifying.

4. Verify a container image signature and its SBOM / provenance attestations

IMAGE=ghcr.io/certctl-io/certctl-server:v2.1.0

cosign verify \
  --certificate-identity-regexp '^https://github\.com/certctl-io/certctl/\.github/workflows/release\.yml@refs/tags/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  "$IMAGE"

# SBOM attestation (SPDX-JSON, emitted by docker/build-push-action)
cosign verify-attestation --type spdxjson \
  --certificate-identity-regexp '^https://github\.com/certctl-io/certctl/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  "$IMAGE"

# SLSA provenance attestation (docker/build-push-action `provenance: mode=max`)
cosign verify-attestation --type slsaprovenance \
  --certificate-identity-regexp '^https://github\.com/certctl-io/certctl/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  "$IMAGE"

Why this matters

The keyless OIDC signing identity is https://github.com/certctl-io/certctl/.github/workflows/release.yml@refs/tags/<tag>. That regex anchor is what lets you trust the binary you're holding came from the certctl-io repo's release workflow on a signed tag, not from a fork or a malicious push.

If any of the verification commands above fail or produce unexpected output, do not deploy the artefact. File a security report per the security policy.