Image signing and SBOMs¶
AKKO signs every image it publishes to harbor.akko-ai.com/akko/*:2026.04 with cosign (Sigstore project, Apache 2.0, Linux Foundation governance). Each image also carries a CycloneDX 1.5 SBOM attached as an in-toto attestation, generated by syft (Anchore, Apache 2.0).
This page tells operators how to verify that the images running on their cluster are the ones AKKO actually published, and how to feed the SBOMs into their preferred enterprise scanner (Anchore Enterprise, Snyk, JFrog Xray, Dependency-Track, etc.).
The full design rationale lives in ADR-032 (ADR-032).
Verify an image is authentic¶
The AKKO public key lives in the repo at helm/akko/charts/akko-cockpit/files/cosign.pub and is also published in Harbor next to each artefact. Anyone can verify any image without contacting AKKO.
Quick check (one image)¶
# 1. Get the public key (one-shot)
curl -sSfLo cosign.pub \
https://raw.githubusercontent.com/AKKO-p/akko/main/helm/akko/charts/akko-cockpit/files/cosign.pub
# 2. Verify the signature
cosign verify --key cosign.pub harbor.akko-ai.com/akko/cockpit:2026.04
A successful run prints a single JSON object per matching signature with the image digest, the signing identity, and the Rekor inclusion proof. A failure (no signature or wrong key) returns a non-zero exit code and the message Error: no matching signatures.
Verify every image at once¶
for img in cockpit ai-service mlflow airflow trino aden akko-rag \
postgres spark catalog-manager dbt \
mcp-trino mcp-openmetadata docs notebook-slim notebook-full; do
echo "=== $img ==="
cosign verify --key cosign.pub "harbor.akko-ai.com/akko/${img}:2026.04" \
>/dev/null 2>&1 \
&& echo "OK-signed" \
|| echo "FAIL-not-signed"
done
Verify before pulling (admission policy)¶
Sprint 47 ships a Kyverno ClusterPolicy that refuses to schedule any pod whose image references harbor.akko-ai.com/akko/ and lacks a valid signature. Until then, the recommended posture is to run cosign verify in the deploy pipeline (06-trivy.yml already does it on every push to main).
Inspect the SBOM¶
Each signed image carries a CycloneDX 1.5 JSON SBOM as an in-toto attestation. Pull it with:
cosign download attestation harbor.akko-ai.com/akko/cockpit:2026.04 \
| jq -r .payload \
| base64 -d \
| jq '.predicate' > sbom-cockpit.cdx.json
The output is a standard CycloneDX 1.5 document. To list every package quickly:
Forward to an enterprise SBOM scanner¶
CycloneDX is the industry default since 2025. Every commercial SBOM tool ingests it natively.
Anchore Enterprise:
Snyk:
snyk container monitor harbor.akko-ai.com/akko/cockpit:2026.04 \
--sbom=sbom-cockpit.cdx.json \
--org=YOUR_ORG_ID
OWASP Dependency-Track (open source, recommended):
curl -X POST \
-H "X-API-Key: $DT_API_KEY" \
-H "Content-Type: application/vnd.cyclonedx+json" \
--data-binary @sbom-cockpit.cdx.json \
https://your-dependency-track/api/v1/bom
JFrog Xray:
Bulk export: the Woodpecker pipeline 10-image-sign.yml archives every SBOM as akko-sboms-2026.04.tar.gz. Download it from the Woodpecker UI under the latest green build's artefacts tab.
Operator FAQ¶
Can I verify an image offline?¶
Yes. cosign verify --key cosign.pub is fully offline — it does not contact Sigstore, Rekor, or any network service. The public key is the only artefact you need. Air-gapped clusters can also disable the entire signing pipeline by setting the Woodpecker secret AKKO_SIGN_IMAGES=false.
Can I bring my own key?¶
Yes. Override the cosign keypair by replacing helm/akko/charts/akko-cockpit/files/cosign.pub and storing your private key as Secret/akko-cosign-keys in the harbor namespace:
The script bootstraps a new keypair, writes the Secret, and syncs cosign.pub into the chart files. Re-run the Woodpecker pipeline afterwards to re-sign every published image with the new key.
Why CycloneDX and not SPDX?¶
CycloneDX 1.5 is the format every commercial SBOM scanner ingests natively in 2025+. SPDX is a strong second choice (especially for Linux distro audits); cosign supports attaching both side-by-side on the same digest, and we may publish a parallel SPDX attestation in a future sprint. Today the cyclonedx predicate is the only one we emit. See ADR-032 for the trade-off.
What happens if the signing pipeline is down?¶
The 10-image-sign.yml pipeline is best-effort: a Sigstore Fulcio outage or a Harbor blip warns and exits 0 so the build itself does not fail. The cosign-verify gate in 06-trivy.yml is the hard enforcement layer — a missing signature on an image being pushed to main blocks the merge. Operators can also re-run the sign pipeline manually from the Woodpecker UI to re-attempt signing without rebuilding.
How do I rotate the signing key?¶
This generates a new keypair, writes it to Secret/akko-cosign-keys, and updates the public key in the chart. Every existing signature becomes invalid — the next pipeline run will re-sign every image with the new identity. Plan rotations during low-traffic windows: the verify-gate will fail for ~10-15 minutes between key rotation and pipeline completion.
How do I prove provenance to a banking / healthcare auditor?¶
Combine three artefacts:
- Signature —
cosign verify --key cosign.pub <image>. Proves origin. - SBOM —
cosign download attestation <image>. Proves dependency graph. - Pipeline log — Woodpecker UI, build history of
10-image-sign.yml. Proves chain of custody.
The combination satisfies DORA Article 6 (ICT supply-chain integrity), NIS2 Annex II (SBOM for essential entities), and HDS Section 6.7 (provenance verification) when read alongside docs/docs/admin/compliance-matrix.md.
Related¶
- ADR-032 — Image signing + SBOM (ADR-032)
- ADR-022 — CI strategy (ADR-022)
- ADR-029 — Governance over license (ADR-029)
- Compliance matrix
- Audit playbook
- License audit