OCI-only chart distribution + admission verification (workstream F) - #85
Merged
Merged
Conversation
Make the signed OCI chart the sole published Helm repo, add opt-in admission-verification examples, and document verify-before-install. BREAKING (chart distribution): the release workflow no longer runs chart-releaser, so the GitHub Pages Helm repo (`helm repo add ballast https://tight-line.github.io/ballast`) receives no new versions. It is frozen, not deleted: the existing gh-pages index.yaml stays in place so already-published versions keep resolving for current users. New installs/upgrades use `helm install oci://ghcr.io/tight-line/charts/ballast`. The OCI chart has been published and cosign-signed since 0.4.9, so only the primary distribution path moves; the artifact is unchanged. release.yml: drop chart-releaser (and its Configure Git step), keep the signed OCI push, and recreate the per-tag GitHub Release with the gh CLI (no third-party action) — auto-generated notes plus the packaged ballast-<version>.tgz as a convenience asset. Idempotent on re-runs. examples/admission/: opt-in Kyverno ClusterPolicy and sigstore policy-controller ClusterImagePolicy that admit only ballast images carrying a valid keyless cosign signature from the release workflow. Fail-closed; the chart does not install them (cluster-operator decision). Verified against current Kyverno (kyverno.io/v1, rule-level failureAction) and policy-controller (policy.sigstore.dev/v1beta1) docs. Docs: README gains "Verifying the release" (cosign verify image + chart before install) and "Older releases" (frozen Pages repo vs OCI, plus the Releases page); install/upgrade commands switch to oci://. SECURITY.md fixes the SBOM verify type (spdxjson -> https://spdx.dev/Document/v2.3), adds provenance + gh attestation verify, and checks the three runtime posture boxes (RBAC, securityContext, admission guidance). AGENTS.md release-flow section updated for the OCI-only pipeline.
nickmarden
force-pushed
the
security/workstream-f-oci-and-verification
branch
from
July 28, 2026 16:56
5049f9c to
77697b8
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Docker Image Builtdocker pull ghcr.io/tight-line/ballast:pr-85-77697b8Helm (values override)image:
repository: ghcr.io/tight-line/ballast
tag: "pr-85-77697b8"Image expires ~15 days after PR closes. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Workstream F — the final supply-chain layer: make the signed OCI chart the primary (and only) published Helm repo, give users a verify-before-install path, and add opt-in admission-time enforcement.
Warning
Breaking change to chart distribution. The GitHub Pages Helm repo (
helm repo add ballast https://tight-line.github.io/ballast) no longer receives new versions. It is frozen, not deleted — the existinggh-pagesindex.yamlstays in place so already-published versions keep resolving for current users. New installs/upgrades usehelm install oci://ghcr.io/tight-line/charts/ballast. The OCI chart has been published and cosign-signed since 0.4.9, so only the primary distribution path moves; the artifact itself is unchanged.F1 — Verify before install (docs)
oci://.--type spdxjson→--type https://spdx.dev/Document/v2.3, since syft emits a versioned predicate type), adds the SLSA-provenance verify + agh attestation verifyalternative, and checks the three Runtime posture boxes (least-privilege RBAC, hardenedsecurityContext, admission guidance).F2 — Admission-time verification (opt-in examples)
New
examples/admission/with policies for both engines that admit onlyghcr.io/tight-line/ballastimages carrying a valid keyless cosign signature from the release workflow:ClusterPolicy(kyverno.io/v1, rule-levelfailureAction: Enforce, fail-closed webhook).ClusterImagePolicy(policy.sigstore.dev/v1beta1, per-namespace opt-in label).Both pin the exact signing identity (
subjectRegExp+ issuer) and use the:*colon-glob (not a bare prefix, which would also match sibling repos). The chart does not install these — admission enforcement is cluster-wide and cluster-critical, so it's a deliberate operator decision, not something a workload chart should impose. Syntax verified against current Kyverno and policy-controller docs.F3 — OCI-only release pipeline
release.yml(release-chartjob):chart-releaser(which published to gh-pages) and itsConfigure Gitstep.ghCLI — no new third-party action (better for the supply-chain story). Auto-generated notes + the packagedballast-<version>.tgzattached as a convenience asset. Idempotent on tag re-runs.Releases are now named for their tag (
v<version>) rather thanballast-<version>.Notes for review
release.ymlcan't be exercised on this PR; thegh releasestep was written defensively (set -euo pipefail, existence check before create).SECURITY.mdis implemented by Trim operator RBAC to least privilege (workstream E) #84 (workstream E). Both are part of the same series and merge into the same release; I put all three runtime-box flips here to keep the checklist edits in one place.Validation
make lint— clean (0 issues)make test-coverage-check— passed (no Go changes on this branch)release.yml— valid YAML; step order and outputs (ref/digest/tgz) wired correctly