Skip to content

chore(k8s): P2-8 doc clarifications + supply-chain pins (busybox digest, action SHAs, compose)#766

Merged
ELares merged 1 commit into
mainfrom
chore/p2-8-hardening
Jul 24, 2026
Merged

chore(k8s): P2-8 doc clarifications + supply-chain pins (busybox digest, action SHAs, compose)#766
ELares merged 1 commit into
mainfrom
chore/p2-8-hardening

Conversation

@ELares

@ELares ELares commented Jul 24, 2026

Copy link
Copy Markdown
Owner

What

Closes P2-8 and the hardening follow-ups earlier reviews logged but never actioned. Completes P2 (P2-1…P2-8).

P2-8 doc clarifications (in values.yaml, where operators actually read them)

  • runAsUser/runAsGroup must match the image's baked-in UID/GID 65532 -- changing them without rebuilding breaks the process's access to its own files (and the PVC).
  • readOnlyRootFilesystem applies to / only -- the writable data PVC and the small /run/ironcache emptyDir (which the init container stamps config into) are by design.
  • The PV reclaim policy comes from the StorageClass, not this chart: use a Retain class in prod (the chart's persistentVolumeClaimRetentionPolicy protects the PVC; the StorageClass protects the PV).
  • volumeClaimTemplate labels/annotations apply at PVC creation only and don't propagate to existing PVCs.

Supply-chain pins

  • initImage.digest (opt-in): when set it wins over tag and renders busybox@sha256:… (the @ form). The verified multi-arch manifest-list digest for busybox:1.36 is documented inline (confirmed an OCI image index carrying amd64 + arm64, so the ARM/k3s story is preserved). Left empty by default deliberately -- an air-gapped cluster pre-loads its own busybox tarball whose digest differs, and a pin would fail the pull. Safe default, hardening available where you control the registry.
  • Actions SHA-pinned across the three chart workflows: cosign-installer (the signing tool -- the trust path, highest-value pin), setup-helm (v4 was a floating major -> pinned to the v4.3.1 commit), kind-action. Every SHA resolved through the GitHub API and dereferenced (annotated tags return a tag object, not the commit), not reconstructed from memory.
  • deploy/compose/* pinned off :latest to ${IRONCACHE_VERSION:-0.1.0}, matching the env interpolation those files already use, so they stay overridable.

Plan

P2-1…P2-8 COMPLETE. The only remaining checklist rows are the two PARTIAL-by-design ones (failover-before-drain, online scale-out) -- automating those is operator charter.

Verified

lint clean; default still renders busybox:1.36 while --set initImage.digest renders the @sha256 form; all 9 value-sets + the raw manifests validate; compose files parse.

…st, action SHAs, compose)

Closes P2-8 and the hardening follow-ups earlier reviews logged but never actioned.

P2-8 doc clarifications (values.yaml, where an operator actually reads them):
  - runAsUser/runAsGroup MUST match the image's baked-in UID/GID 65532; changing them without
    rebuilding the image breaks the process's access to its own files (and the PVC).
  - readOnlyRootFilesystem applies to `/` ONLY -- the writable data PVC and the small
    /run/ironcache emptyDir (which the init container stamps the config into) are BY DESIGN.
  - The PV RECLAIM POLICY comes from the StorageClass, not this chart: use a `Retain` class in
    production (the chart's persistentVolumeClaimRetentionPolicy protects the PVC; the
    StorageClass protects the PV behind it).
  - volumeClaimTemplate labels/annotations apply at PVC CREATION only and do NOT propagate to
    already-created PVCs.

Supply-chain pins:
  - initImage.digest (opt-in): when set it WINS over `tag` and renders `busybox@sha256:...`
    (the `@` form, not `:`). The verified MULTI-ARCH manifest-list digest for busybox:1.36 is
    documented inline (confirmed an OCI image index carrying amd64 + arm64, so the ARM/k3s story
    is preserved). Left EMPTY by default DELIBERATELY: an air-gapped cluster pre-loads its own
    busybox tarball whose digest differs, and a digest pin would then fail the pull -- the
    tunability principle, a safe default with the hardening available where you control the
    registry.
  - Third-party GitHub Actions SHA-pinned across the three chart workflows, matching the
    release-workflow convention: sigstore/cosign-installer (v3.7.0 -- the SIGNING tool, i.e. the
    trust path, so the highest-value pin), azure/setup-helm (v4 was a floating major -> pinned to
    the v4.3.1 commit), helm/kind-action (v1.10.0). Every SHA was resolved through the GitHub API
    and dereferenced (annotated tags return a tag object, not the commit), not reconstructed.
  - deploy/compose/*: pinned off `:latest` to ${IRONCACHE_VERSION:-0.1.0}, matching the env
    interpolation those files already use, so they stay overridable.

Plan: P2-1..P2-8 now COMPLETE; the only remaining checklist rows are the two PARTIAL-BY-DESIGN
ones (failover-before-drain, online scale-out), whose automation is operator charter.

Verified with helm 3.15.4 + kubeconform 0.6.7: lint clean; default still renders busybox:1.36
while --set initImage.digest renders the @sha256 form; all 9 value-sets + the raw manifests
validate; compose files parse.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FfFZ8gkkNhDBASuntB72HR
@ELares
ELares merged commit f6d0ec0 into main Jul 24, 2026
7 checks passed
@ELares
ELares deleted the chore/p2-8-hardening branch July 24, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant