security: the Helm chart is cosign-signed but the images it pulls are not, and nothing ships an SBOM
Sourced from reviewing TruePPM's release hardening (
~/repos/trueppm-suite/trueppm), re-checked against Visiban's.gitlab-ci.yml.
An inconsistent trust boundary
helm-publish signs the chart, keyless via Sigstore, so an operator can cosign verify the chart they pull. The job comment says so explicitly: "so an operator can cosign verify the chart they pull rather than trusting the registry."
But backend-docker-push, frontend-docker-push, ghcr-push-backend and ghcr-push-frontend sign nothing. grep -riE "sbom|cosign|attestation|provenance|syft" .gitlab-ci.yml matches only inside the helm-publish block.
So the chart is verifiable and the images that chart pulls are not — the artifact carrying almost none of the attack surface is signed, and the two carrying nearly all of it are not. An operator who follows the chart's own verification advice ends up with a verified pointer to unverified images.
Why this is worth doing here specifically
- Visiban publishes to two registries (GitLab +
ghcr.io/visiban/visiban) and mirrors to GitHub. More publication surface, more places a tag can be replaced. - The cosign toolchain is already wired:
helm-publishinstalls a SHA-pinned cosign 2.4.3 and authenticates keyless withSIGSTORE_ID_TOKEN. This is extending an existing, working mechanism to two more artifacts, not introducing one. - #1074 (closed) is making released images verifiable as present. Signing makes them verifiable as ours. The two are complementary and neither substitutes for the other.
Scope
- Generate a CycloneDX SBOM per image with syft at publish time, naming it so
metadata.component.nameis the image rather than a temporary build path (--source-name/--source-version). cosign attest --type cyclonedxthe SBOM to the image digest, not to a tag — a tag can be moved, a digest cannot.cosign verify-attestationin the same job, and assert the SBOM names its own architecture. An attestation step that silently no-ops is the failure mode worth designing against.- Document the verification commands in
docs/administration/, next to wherever the chart verification lands.
Watch out
- Multi-arch. #1084 (closed) is restoring
linux/arm64, so each release has a manifest list with per-arch digests. Attesting only the index, or only amd64, produces a green job and a half-covered release. Attest each platform digest. - Keyless identity is the job. The certificate identity is whatever CI job runs the attest step, so this must never run from a workstation — TruePPM's equivalent script refuses to execute outside CI for exactly that reason.
- Backfill. TruePPM has
scripts/backfill-sbom-attestation.shfor images already published without attestations, run from a manual CI job. Worth porting if 1.2 ships before this lands, so already-released images can be brought up to the same bar without a re-cut.
Out of scope
Signing the source or adding SLSA provenance beyond the SBOM attestation. Those are a larger conversation; this issue is about closing the gap between a signed chart and unsigned images.