feat(seal-check): enumeration label contract + storage-assertions test hook (RFC-0003 §8.2–8.4)#378
Open
LukasWodka wants to merge 2 commits into
Open
feat(seal-check): enumeration label contract + storage-assertions test hook (RFC-0003 §8.2–8.4)#378LukasWodka wants to merge 2 commits into
LukasWodka wants to merge 2 commits into
Conversation
…0003 S8.2 / backend#1184) Establish the seal-check enumeration contract and fill the storage gap in the chart conformance suite: - Label every conformance helm-test Job (and its pods) with tracebloc.io/seal-check="true" + tracebloc.io/seal-check-name=<check> -- the contract the tracebloc CLI consumes (cli#393). Applied to the existing egress-enforcement probe and backend-reachability check via a new tracebloc.sealCheckLabels helper. - New storage-assertions helm-test Job (sealCheck.storageAssertions.*, default on, fully nil-guarded for --reuse-values upgrades): release PVCs Bound on the expected StorageClass; in dynamic-PVC mode (hostPath.enabled=false) no release PVC backed by an unmanaged hostPath PV -- catches the RFC-0003 D3/D4 leftover-PV claimRef capture. k3s local-path node-local paths tolerated and reported (Option C); clusterScope=false degrades the PV scan to a name check with an explicit WARNING, never silently. - Least-privilege SA/RBAC as negative-weight test hooks (PVC read in the namespace; PV read only when clusterScope allows a ClusterRole). - docs/SEAL-CHECK.md: label contract, coverage today, UNSEALED philosophy, per-substrate coverage view, and the k3d/k3s NetworkPolicy egress verification runbook (documented honestly as not yet executed). - 20 new helm-unittest cases; 287/287 pass, helm lint --strict clean on all four platform values, check-drift clean. Part of tracebloc/backend#1184 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
bugbot run |
Contributor
Author
|
bugbot run |
LukasWodka
requested review from
saqlainsyed007
and removed request for
aptracebloc
July 23, 2026 06:24
… WARNING after legacy FAIL Two Bugbot findings on the storage-assertions check (PR #378): - The pv-hostpath allowlist matched entries with a bare "$prefix"* glob, and the default /opt/local-path-provisioner entry carries no trailing slash, so sibling trees like /opt/local-path-provisioner-evil/... were accepted as node-local and could pass the storage seal. Entries are now normalized (trailing slash stripped) and matched on whole path segments: a prefix admits exactly itself or paths under it, never siblings. The default entry in values.yaml / template dig fallback / schema / docs is normalized to the trailing-slash style; either entry style now behaves identically. - With clusterScope=false (no PV read), a claim captured by a chart legacy hostPath PV printed FAIL and then still printed the PARTIAL verification WARNING claiming the claim was "verified not bound" to a legacy PV. The WARNING is now suppressed for a claim whose legacy-name check just FAILed - the FAIL alone is the honest verdict there; claims that pass the name check keep the WARNING unchanged. Validated: helm lint --strict on the 4 CI platform values; helm template (near-default / node-local / flag off / sealCheck: null); helm unittest 289/289 (2 new cases pin both guards); sh -n + shellcheck on the rendered script; mocked-kubectl runs covering sibling-path FAIL (both entry styles), exact-prefix-root OK, legacy FAIL without WARNING, no-legacy WARNING x3, unmanaged-tree FAIL, PV-read-error FAIL. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8c37038. Configure here.
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.
Summary
Chart half of the RFC-0003 D12 seal check (§8.2–8.4): establishes the seal-check enumeration contract and fills the storage-assertions gap, without touching
scripts/(installer work stays with #368).1. The enumeration contract (consumed by tracebloc/cli#393)
Every runnable conformance check is a
helm.sh/hook: testJob carrying, on the Job and its pod template:tracebloc.io/seal-check"true"tracebloc.io/seal-check-nameegress-enforcement|backend-reachability|storage-assertionsEnumerate without running:
helm get hooks <release>. While running:kubectl get jobs,pods -l tracebloc.io/seal-check=true. Label keys + existing names are public API (never renamed; new checks = new names). Auxiliary hook resources (the new SA/RBAC) deliberately do not carry the labels — only runnable checks are enumerable. Applied to the existing egress-enforcement probe + backend-reachability check via a newtracebloc.sealCheckLabelshelper.2. New check:
storage-assertions(sealCheck.storageAssertions.*, default on)kubectl-image test-hook Job (same
alpine/k8s:1.30.5the image-refresh CronJob uses) asserting from in-cluster:client-pvc/client-logs-pvc/mysql-pvcexist and areBound(bounded wait, default 120s, forWaitForFirstConsumer+ first-install pulls)tracebloc.storageClassName)hostPath.enabled=false, only) — no release PVC backed by an unmanaged hostPath PV. Catches the RFC-0003 D3/D4 leftover-PVclaimRefcapture (a stale<release>-{data,logs,mysql}-pvgrabs the claim even in dynamic mode). k3s local-path node-local paths (nodeLocalPathPrefixes, default/var/lib/rancher/+/opt/local-path-provisioner) are tolerated and reported — they live inside the cluster node and die with it (Option C); host-visibility of those paths is a cluster-creation fact verified at install level. In hostPath mode the sub-check SKIPs (declared model).RBAC: dedicated least-privilege SA as negative-weight test hooks — PVC get/list in the namespace; PV get/list only when
clusterScopeallows a ClusterRole. WithclusterScope=falsethe PV scan degrades to the name/claimRef check and prints an explicit WARNING naming what was not verified.UNSEALED philosophy (documented in
docs/SEAL-CHECK.md): a guarantee that cannot be verified fails loudly — never silently claimed sealed. Disabling a check is a values-visible declaration, not a runtime fallback.3. Docs
docs/SEAL-CHECK.md— contract, coverage today, philosophy, per-substrate coverage table (chart-side input to the RFC §8.3 matrix), and the k3d/k3s NetworkPolicy egress verification runbook (§8.4) using the existing enforcement probe — documented honestly as not yet executed; the k3d cell stays "verification run pending" until a run is recorded. Cross-linked fromdocs/SECURITY.md§7.Compatibility
default dict/dig) —helm upgrade --reuse-valuesfrom releases predatingsealCheckrenders identically (unit-tested withsealCheck: null).hostPath.enabled, verifies whichever model the install declares.Test plan
helm lint --strictPASS on all 4 platform values (aks / bm / eks / oc)helm templateclean: 4 CI platforms + near-default values + node-local values (hostPath.enabled=false,local-pathclass) + flag off + nilsealCheck/ nilstorageAssertionshelm unittest: 287/287 (20 new cases: rendering gates, hook annotations, label contract on Job+pod, RBAC split underclusterScope, env baking, PSA-restricted fields, image pin, nil-block survival)sh -n+shellcheckclean; exercised with a mocked kubectl across 9 scenarios (happy dynamic / node-local PV / unmanaged hostPath / legacy-PV capture / wrong class / PV read error / namespace-scoped partial / hostPath mode / never-Bound) — verdicts as designedscripts/tests/check-drift.sh: no drift (run only, not modified)Deliberately left for follow-ups (tracked in backend#1184)
~/.traceblochost-tree check — not observable in-cluster; CLI/installer offboard-verify lineage (cli#389)helm template --set hostPath=nullcrashes on develop too (shared-images-pvc.yamlunguarded deref) — orthogonal to this PRPart of tracebloc/backend#1184
🤖 Generated with Claude Code
Note
Low Risk
Changes are confined to optional
helm testhooks and docs; install/upgrade paths are unchanged. The storage check may create cluster-scoped PV read RBAC only whenclusterScope=true, matching existing chart RBAC patterns.Overview
Introduces the seal-check conformance suite for
helm test: a stable label contract so tooling (e.g. tracebloc CLI) can enumerate checks without hardcoding job names, plus a new storage-assertions hook and documentation.A shared
tracebloc.sealCheckLabelshelper appliestracebloc.io/seal-check/tracebloc.io/seal-check-nameon hook Jobs and pod templates foregress-enforcement,backend-reachability, and the newstorage-assertionscheck. Auxiliary RBAC for storage is intentionally not labelled.storage-assertions (default on via
sealCheck.storageAssertions) is a kubectl-based test hook that asserts release PVCs are Bound, on the expected StorageClass, and—in dynamic PVC mode—are not backed by unmanaged hostPath (with legacy chart PV name detection, node-local path allowlists, and degraded PV inspection whenclusterScope=false). It ships least-privilege test-hook SA/RBAC and follows the “unverified ⇒ fail loudly” philosophy documented indocs/SEAL-CHECK.md, with a cross-link fromdocs/SECURITY.md.Reviewed by Cursor Bugbot for commit 8c37038. Bugbot is set up for automated code reviews on this repo. Configure here.