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.
3.4 KiB
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-serverforlinux|darwin × amd64|arm64 - A
checksums.txtcovering 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.
Related docs
- Architecture — overall system design
- Security posture — operator-facing security guidance
- CI pipeline — what runs on every commit (the release pipeline is the same one)