diff --git a/.gitignore b/.gitignore index f494b1b..df53122 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .tool-versions +.claude/ +.idea/ diff --git a/UPGRADE.md b/UPGRADE.md index 1b20d0f..f07cb35 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -225,6 +225,12 @@ Note: The configmap is automatically mounted via `envFrom` when `configmap.enabl - Each entry in `ingresses` list can now have its own `annotations` and `ingressClassName`. +### Per-container `uid` + +- Each entry in the `containers` list now honors its own `uid`, rendered as `runAsUser`/`runAsGroup` on that container. +- The pod-level securityContext (`runAsUser`/`runAsGroup`/`fsGroup`) follows the first `containers` entry's `uid`, falling back to `container.uid` (default `1000`). Single-container charts run as the same uid as before; the only rendered difference is that each container's securityContext now also spells out `runAsUser`/`runAsGroup` (previously only the pod-level securityContext did). +- ⚠️ Previously `uid` on `containers` entries was silently ignored and those pods ran as `1000`. If you set `uid` on `containers` entries and relied on the old `1000` behavior (e.g. volume or file ownership, `fsGroup`-dependent mounts), verify ownership after upgrading. + ### Cloud SQL Proxy v2 features - Prometheus metrics exposed on port 9801 (`/metrics`). diff --git a/charts/common/templates/_helpers.tpl b/charts/common/templates/_helpers.tpl index 5084b2d..d7add49 100644 --- a/charts/common/templates/_helpers.tpl +++ b/charts/common/templates/_helpers.tpl @@ -30,6 +30,10 @@ meta.helm.sh/release-namespace: {{ empty .Release.Namespace| ternary .Release.Na securityContext: allowPrivilegeEscalation: false runAsNonRoot: true + {{- with .uid }} + runAsUser: {{ . }} + runAsGroup: {{ . }} + {{- end }} capabilities: drop: ["ALL"] seccompProfile: diff --git a/charts/common/templates/cron.yaml b/charts/common/templates/cron.yaml index b031fcd..d58c241 100644 --- a/charts/common/templates/cron.yaml +++ b/charts/common/templates/cron.yaml @@ -6,6 +6,7 @@ {{- $releaseName := include "name" . -}} {{- $containers := .Values.containers | default (list .Values.container) -}} +{{- $podUid := (first $containers).uid | default .Values.container.uid -}} {{- $configmap := .Values.configmap -}} {{- $postgres := .Values.postgres -}} {{- $secrets := .Values.secrets -}} @@ -89,10 +90,10 @@ spec: {{- end }} restartPolicy: {{ .Values.cron.restartPolicy | default "OnFailure" }} securityContext: - runAsGroup: {{ .Values.container.uid }} + runAsGroup: {{ $podUid }} runAsNonRoot: true - runAsUser: {{ .Values.container.uid }} - fsGroup: {{ .Values.container.uid }} + runAsUser: {{ $podUid }} + fsGroup: {{ $podUid }} seccompProfile: type: RuntimeDefault {{- end -}} \ No newline at end of file diff --git a/charts/common/templates/deployment.yaml b/charts/common/templates/deployment.yaml index 019c853..f3ae637 100644 --- a/charts/common/templates/deployment.yaml +++ b/charts/common/templates/deployment.yaml @@ -6,6 +6,7 @@ {{- $releaseName := include "name" . -}} {{- $containers := .Values.containers | default (list .Values.container) -}} +{{- $podUid := (first $containers).uid | default .Values.container.uid -}} {{- $configmap := .Values.configmap -}} {{- $postgres := .Values.postgres -}} {{- $secrets := .Values.secrets -}} @@ -129,10 +130,10 @@ spec: {{- end }} restartPolicy: Always securityContext: - runAsGroup: {{ .Values.container.uid }} + runAsGroup: {{ $podUid }} runAsNonRoot: true - runAsUser: {{ .Values.container.uid }} - fsGroup: {{ .Values.container.uid }} + runAsUser: {{ $podUid }} + fsGroup: {{ $podUid }} seccompProfile: type: RuntimeDefault {{- end }} diff --git a/charts/common/tests/cron_test.yaml b/charts/common/tests/cron_test.yaml index 92b6956..ebecbdc 100644 --- a/charts/common/tests/cron_test.yaml +++ b/charts/common/tests/cron_test.yaml @@ -282,4 +282,30 @@ tests: asserts: - equal: path: spec.jobTemplate.spec.template.spec.containers[1].envFrom[0].secretRef.name - value: my-cron-creds \ No newline at end of file + value: my-cron-creds + - it: honors uid per entry in the containers list + set: + containers: + - name: app + uid: 101 + image: img + probes: + enabled: false + - name: sidecar + uid: 2000 + image: img + probes: + enabled: false + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.securityContext.runAsUser + value: 101 + - equal: + path: spec.jobTemplate.spec.template.spec.securityContext.fsGroup + value: 101 + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].securityContext.runAsUser + value: 101 + - equal: + path: spec.jobTemplate.spec.template.spec.containers[1].securityContext.runAsUser + value: 2000 diff --git a/charts/common/tests/deployment_test.yaml b/charts/common/tests/deployment_test.yaml index de06dca..7f2baab 100644 --- a/charts/common/tests/deployment_test.yaml +++ b/charts/common/tests/deployment_test.yaml @@ -366,6 +366,70 @@ tests: - equal: path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation value: false + - it: uses container uid in pod and container security context + set: + container: + uid: 101 + image: img + asserts: + - equal: + path: spec.template.spec.securityContext.runAsUser + value: 101 + - equal: + path: spec.template.spec.securityContext.fsGroup + value: 101 + - equal: + path: spec.template.spec.containers[0].securityContext.runAsUser + value: 101 + - it: honors uid per entry in the containers list + set: + containers: + - name: app + uid: 101 + image: img + probes: + enabled: false + - name: sidecar + uid: 2000 + image: img + probes: + enabled: false + - name: nouid + image: img + probes: + enabled: false + asserts: + - equal: + path: spec.template.spec.securityContext.runAsUser + value: 101 + - equal: + path: spec.template.spec.securityContext.fsGroup + value: 101 + - equal: + path: spec.template.spec.containers[0].securityContext.runAsUser + value: 101 + - equal: + path: spec.template.spec.containers[1].securityContext.runAsUser + value: 2000 + - equal: + path: spec.template.spec.containers[1].securityContext.runAsGroup + value: 2000 + - notExists: + path: spec.template.spec.containers[2].securityContext.runAsUser + - it: defaults pod security context to uid 1000 when containers list sets no uid + set: + containers: + - name: app + image: img + probes: + enabled: false + asserts: + - equal: + path: spec.template.spec.securityContext.runAsUser + value: 1000 + - equal: + path: spec.template.spec.securityContext.fsGroup + value: 1000 - it: has envFrom secrets in all containers set: containers: