From 99d45769f3b8858b120842bce4db205564bdd003 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Thu, 17 Sep 2026 17:03:47 +0200 Subject: [PATCH 1/2] fix(security): supply the C-0211 baseline context to longhorn-manager and the driver deployer Post-render fsGroupChangePolicy OnRootMismatch and an empty container seLinuxOptions onto the longhorn-manager DaemonSet and the longhorn-driver-deployer Deployment, the two remaining workloads the Longhorn chart renders. The CSI sidecars, csi-plugin and engine-image workloads are created by longhorn-manager at runtime and are out of reach. Part of #3239 Co-Authored-By: Claude Opus 5 (1M context) --- .../controllers/longhorn/helm-release.yaml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/k8s/providers/hetzner/infrastructure/controllers/longhorn/helm-release.yaml b/k8s/providers/hetzner/infrastructure/controllers/longhorn/helm-release.yaml index 71acf67b8..59a687b8d 100644 --- a/k8s/providers/hetzner/infrastructure/controllers/longhorn/helm-release.yaml +++ b/k8s/providers/hetzner/infrastructure/controllers/longhorn/helm-release.yaml @@ -221,3 +221,55 @@ spec: - ALL seccompProfile: type: RuntimeDefault + # C-0211 baseline context (#3239) for the two other workloads this chart + # renders. longhorn-system is excluded from add-security-context and the + # chart exposes no securityContext value for either, so both fields are + # post-rendered here. Neither pod sets an fsGroup, so OnRootMismatch changes + # no volume ownership; it only declares the policy. The empty seLinuxOptions + # object leaves SELinux type and MCS selection to the runtime, which still + # assigns the privileged longhorn-manager container its privileged label. + # + # The CSI sidecar Deployments, the longhorn-csi-plugin DaemonSet and the + # engine-image DaemonSets are created by longhorn-manager at runtime, not by + # this chart, so no postRenderer can reach them. + - target: + kind: DaemonSet + name: longhorn-manager + patch: | + apiVersion: apps/v1 + kind: DaemonSet + metadata: + name: longhorn-manager + spec: + template: + spec: + securityContext: + fsGroupChangePolicy: OnRootMismatch + containers: + - name: longhorn-manager + securityContext: + seLinuxOptions: {} + - name: pre-pull-share-manager-image + securityContext: + seLinuxOptions: {} + - target: + kind: Deployment + name: longhorn-driver-deployer + patch: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: longhorn-driver-deployer + spec: + template: + spec: + securityContext: + fsGroupChangePolicy: OnRootMismatch + initContainers: + - name: wait-longhorn-manager + securityContext: + seLinuxOptions: {} + containers: + - name: longhorn-driver-deployer + securityContext: + seLinuxOptions: {} From ebdba74470ace1128305a986b5da1044d51c58ac Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Thu, 17 Sep 2026 17:24:26 +0200 Subject: [PATCH 2/2] fix(security): re-approve the authorization fingerprint for the Longhorn C-0211 context Conservation against main aebd44e4: identical 573 identities and byte-identical grant documents across all five overlays. Part of #3239 Co-Authored-By: Claude Opus 5 (1M context) --- scripts/validate-eks-ci-role-policy/main.go | 35 +++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/scripts/validate-eks-ci-role-policy/main.go b/scripts/validate-eks-ci-role-policy/main.go index b2d4ecb50..780b79999 100644 --- a/scripts/validate-eks-ci-role-policy/main.go +++ b/scripts/validate-eks-ci-role-policy/main.go @@ -2544,7 +2544,38 @@ const ( // digest is claimed. // // Previous aggregate: 5cfb6c88467d2590bfc7cbbd969667146db1cac42cf8ac05069f8b970bae52fe. -const expectedRenderedSurfaceSHA = "a98548ac8a079e0572d117894e650b65891a0350843bd14088cc8c33cd319634" +// +// That kubescape change established aggregate: +// +// a98548ac8a079e0572d117894e650b65891a0350843bd14088cc8c33cd319634 +// +// Moved again by the C-0211 baseline context for the Longhorn workloads +// (#3239), derived on main aebd44e4, whose approved aggregate is a98548ac +// above. The longhorn HelmRelease gains two post-renderer patches adding +// fsGroupChangePolicy: OnRootMismatch and an empty container seLinuxOptions +// object to the longhorn-manager DaemonSet and the longhorn-driver-deployer +// Deployment. A HelmRelease is a controller-RBAC emitter, so this moves the +// aggregate even though nothing is granted. +// +// CONSERVATION: rendering all five authorization overlays on this branch and on +// main aebd44e4 yields 573 identities per side with an identical sorted identity +// list. Only the controllers overlay differs, by 41 added lines, all inside the +// longhorn HelmRelease postRenderers. The 94 grant-bearing ClusterRole, Role, +// ClusterRoleBinding, RoleBinding and ServiceAccount documents hash +// byte-identically on both sides; appending one synthetic ClusterRole to the +// branch render changes that hash, so the identical result is a finding rather +// than a blind read. No identity, binding, ServiceAccount, verb, wildcard, AWS +// identity or permission changes. +// +// RENDERER PROVENANCE: the value below was read from CI's own failure on job +// 105260655356 for head 66951b8 (the merge of this branch into main aebd44e4), +// which renders under the approved SHA256-verified kubectl v1.36.2; the job's +// single failing test was this unapproved aggregate. This host's kubectl +// renderer is unapproved, so it was used only for the conservation comparison +// and no local digest is claimed. +// +// Previous aggregate: a98548ac8a079e0572d117894e650b65891a0350843bd14088cc8c33cd319634. +const expectedRenderedSurfaceSHA = "1ef7baab087081f6145391fe81e52d5ec712edec311e6c56009318509faa8d46" // previousRenderedSurfaceSHA is the aggregate the approval above supersedes, in // machine-readable form. It is the base the approval was computed against. @@ -2557,7 +2588,7 @@ const expectedRenderedSurfaceSHA = "a98548ac8a079e0572d117894e650b65891a0350843b // review as a plausible-looking constant. A change that does not move the // surface leaves both constants untouched. Reverting a re-approval is itself a // re-approval: restore the older aggregate and record the current one here. -const previousRenderedSurfaceSHA = "5cfb6c88467d2590bfc7cbbd969667146db1cac42cf8ac05069f8b970bae52fe" +const previousRenderedSurfaceSHA = "a98548ac8a079e0572d117894e650b65891a0350843bd14088cc8c33cd319634" // authorizationOverlayPaths lists every independently reconciled production // layer where an object can grant privileges to the aws/aws service account.