feat(chart): PodSecurity 'restricted'-compatible securityContext on workloads#152
Open
kamir wants to merge 2 commits into
Open
feat(chart): PodSecurity 'restricted'-compatible securityContext on workloads#152kamir wants to merge 2 commits into
kamir wants to merge 2 commits into
Conversation
PLAN-06 iter-7 E-10 / BUG-0009. The operator, console, and proxy
container images already run as USER 10001 (Dockerfile-baked, every
*.Dockerfile under deploy/docker/) but the chart templates did not
declare the four PSA-restricted requirements, so deployments warned
under `pod-security.kubernetes.io/audit: restricted`.
Templates extended:
* operator-deployment.yaml: pod-level + container-level
securityContext blocks wired to .Values.operator.podSecurityContext
and .Values.operator.containerSecurityContext.
* console-deployment.yaml: same shape under .Values.console.*.
* proxy-deployment.yaml: same shape under .Values.proxy.*.
values.yaml defaults (all three components):
* podSecurityContext: runAsNonRoot=true, runAsUser=10001,
runAsGroup=10001, fsGroup=10001, seccompProfile=RuntimeDefault.
* containerSecurityContext: allowPrivilegeEscalation=false,
readOnlyRootFilesystem=true, capabilities.drop=[ALL].
Result, verified against the bp-001 umbrella with helm template:
admission emits the operator + console + proxy pod specs cleanly
under PSA `restricted` (zero warnings). The brokers themselves are
operator-reconciled, not chart-templated; broker hardening is a
follow-up that touches the operator binary, not this chart.
Chart bump 0.4.0 -> 0.4.1.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…FS, conformance gate
Extend the PSA-restricted securityContext work so the chart is uniformly
hardened and the posture cannot regress unnoticed.
mcp-deployment.yaml: add the same pod + container securityContext blocks
the operator, console, and proxy already carry, wired to
.Values.mcp.podSecurityContext / .Values.mcp.containerSecurityContext.
The mcp image bakes USER 10001 (deploy/docker/mcp.Dockerfile), so the
restricted defaults are correct for the shipped image. This closes the
fourth-Deployment gap: before this, three of four chart Deployments were
hardened.
proxy-deployment.yaml: mount a writable emptyDir at /tmp. The LFS verify
path (cmd/proxy/lfs_http.go, os.CreateTemp("", ...)) writes to /tmp; with
readOnlyRootFilesystem: true the root FS is read-only, so the verify
returns HTTP 500 when KAFSCALE_PROXY_LFS_ENABLED=true. The emptyDir lets
the restricted default and LFS coexist. proxy keeps fsGroup (it owns the
volume); operator/console/mcp drop fsGroup since they mount no volumes.
values.yaml: add the mcp securityContext defaults; remove dead fsGroup on
operator/console; note that runAsUser/runAsGroup pin the Dockerfile-baked
USER 10001 and must change in lockstep with it; document the override path
for root-running custom images (set <component>.podSecurityContext.runAsNonRoot=false).
test/chart/psa-restricted_test.sh + make test-chart-psa: a helm-only
conformance gate (no plugins, no cluster, follows the test/chart pattern)
that renders every chart Deployment with all workloads enabled and asserts
the five restricted controls on each: runAsNonRoot true,
allowPrivilegeEscalation false, capabilities.drop includes ALL,
seccompProfile RuntimeDefault, and a non-root runAsUser. It fails if a new
Deployment is added without the blocks (verified: removing the mcp blocks
makes it fail; restoring makes it pass).
Chart 0.4.1 -> 0.4.2.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What
Add PodSecurity
restricted-compatiblesecurityContextblocks (pod + container) to every chart-templated Deployment, so the chart deploys into namespaces that enforce the Pod Security Admissionrestrictedprofile without per-workload patching. Each Deployment carries:runAsNonRoot: true,runAsUser/runAsGroup: 10001,seccompProfile: RuntimeDefaultallowPrivilegeEscalation: false,readOnlyRootFilesystem: true,capabilities.drop: [ALL]All values are overridable via
values.yamlor--set <component>.podSecurityContext.<key>=<value>.Why
Lets the chart deploy into
restrictedPSA namespaces with zero admission warnings and no per-workload patching.Coverage: all four Deployments
The chart templates four Deployments (operator, proxy, console, mcp). All four are now hardened. The
mcpDeployment was previously missing the blocks; this revision adds them (templates/mcp-deployment.yaml, wired to.Values.mcp.podSecurityContext/.Values.mcp.containerSecurityContext). The mcp image bakesUSER 10001(deploy/docker/mcp.Dockerfile), so the restricted defaults match the shipped image.LFS coexistence: writable /tmp on the proxy
With
readOnlyRootFilesystem: truethe root filesystem is read-only. The proxy LFS verify path (cmd/proxy/lfs_http.go,os.CreateTemp("", ...)) writes a temp file to/tmp, so it returns HTTP 500 (temp_storage_failed) whenKAFSCALE_PROXY_LFS_ENABLED=true. The proxy Deployment now mounts a writableemptyDirat/tmp, so the restricted default and LFS coexist.readOnlyRootFilesystemstaystrue. The proxy keepsfsGroup(it owns the volume); operator, console, and mcp dropfsGroupsince they mount no volumes.Test: conformance gate
test/chart/psa-restricted_test.sh, wired asmake test-chart-psa, follows the existingtest/chartpattern (helm only, no plugins, no cluster). It renders every chart Deployment with all workloads enabled and asserts the five restricted controls on each (operator, proxy, console, mcp x runAsNonRoot true, allowPrivilegeEscalation false, capabilities.drop includes ALL, seccompProfile RuntimeDefault, non-root runAsUser). This gate fails automatically if a future Deployment is added without the blocks. Verified: removing the mcp blocks makes the gate fail; restoring makes it pass.helm lintandhelm templateof all four Deployments are clean.UID pin and overrides
runAsUser/runAsGroup: 10001pin the Dockerfile-bakedUSER 10001of the shipped images and must change in lockstep with that image USER; a values comment records this. PSArestricteditself only requiresrunAsNonRoot, not a specific UID. If you overrideimage.repositorywith a root-running image, set<component>.podSecurityContext.runAsNonRoot=false.Scope
The brokers and etcd are operator-reconciled (label
app=kafscale-broker), not chart-templated, so they are intentionally out of scope for this chart-level change and tracked separately. Default render is unchanged in shape; the hardening defaults are safe for the shipped images and fully overridable.Part of a small series upstreaming deployment-hardening deltas we currently carry. Chart
0.4.1->0.4.2.