diff --git a/charts/flagsmith/templates/_helpers.tpl b/charts/flagsmith/templates/_helpers.tpl index 7a0c046..fd0f385 100644 --- a/charts/flagsmith/templates/_helpers.tpl +++ b/charts/flagsmith/templates/_helpers.tpl @@ -364,3 +364,17 @@ key: {{ default "django-secret-key" .Values.api.secretKeyFromExistingSecret.key name: {{ include "flagsmith.sse.authenticationTokenSecretName" . }} key: {{ default "sse-authentication-token" .Values.sse.authenticationTokenFromExistingSecret.key }} {{- end }} + +{{/* +Security context: chart defaults with user values merged on top (user wins). +Usage: (dict "component" .Values.api "key" "securityContext"|"podSecurityContext") +*/}} +{{- define "flagsmith.mergedSecurityContext" -}} +{{- $defaultKey := printf "default%s" (.key | title) -}} +{{- $ctx := index .component .key | default dict | deepCopy -}} +{{- $defaults := index .component $defaultKey | default dict -}} +{{- if $defaults.enabled -}} +{{- $ctx = $ctx | merge (omit $defaults "enabled") -}} +{{- end -}} +{{- toYaml $ctx -}} +{{- end -}} diff --git a/charts/flagsmith/templates/deployment-api.yaml b/charts/flagsmith/templates/deployment-api.yaml index df0a431..0e79012 100644 --- a/charts/flagsmith/templates/deployment-api.yaml +++ b/charts/flagsmith/templates/deployment-api.yaml @@ -62,12 +62,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - securityContext: - {{- $securityContext := .Values.api.podSecurityContext | default (dict) | deepCopy }} - {{- if .Values.api.defaultPodSecurityContext.enabled }} - {{- $securityContext = $securityContext | merge (omit .Values.api.defaultPodSecurityContext "enabled") }} - {{- end }} - {{- toYaml $securityContext | nindent 8 }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.api "key" "podSecurityContext") | nindent 8 }} {{- if .Values.api.terminationGracePeriodSeconds }} terminationGracePeriodSeconds: {{ .Values.api.terminationGracePeriodSeconds }} {{- end }} @@ -81,6 +76,7 @@ spec: imagePullPolicy: {{ .Values.api.image.imagePullPolicy | default .Values.global.image.imagePullPolicy }} args: ["migrate"] env: {{ include (print $.Template.BasePath "/_api_environment.yaml") . | nindent 8 }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.api "key" "securityContext") | nindent 10 }} volumeMounts: {{ toYaml .Values.api.volumeMounts | nindent 10 }} {{- end }} {{- if .Values.api.bootstrap.enabled }} @@ -104,6 +100,7 @@ spec: - name: PROJECT_NAME value: {{ .Values.api.bootstrap.projectName }} {{- end }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.api "key" "securityContext") | nindent 10 }} volumeMounts: {{ toYaml .Values.api.volumeMounts | nindent 10 }} {{- end }} {{- with .Values.api.extraInitContainers }} @@ -165,6 +162,7 @@ spec: lifecycle: {{- toYaml . | nindent 10 }} {{- end }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.api "key" "securityContext") | nindent 10 }} resources: {{ toYaml .Values.api.resources | indent 10 }} volumeMounts: {{ toYaml .Values.api.volumeMounts | nindent 10 }} diff --git a/charts/flagsmith/templates/deployment-frontend.yaml b/charts/flagsmith/templates/deployment-frontend.yaml index a6ddf71..a6e0251 100644 --- a/charts/flagsmith/templates/deployment-frontend.yaml +++ b/charts/flagsmith/templates/deployment-frontend.yaml @@ -59,12 +59,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - securityContext: - {{- $securityContext := .Values.frontend.podSecurityContext | default (dict) | deepCopy }} - {{- if .Values.frontend.defaultPodSecurityContext.enabled }} - {{- $securityContext = $securityContext | merge (omit .Values.frontend.defaultPodSecurityContext "enabled") }} - {{- end }} - {{- toYaml $securityContext | nindent 8 }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.frontend "key" "podSecurityContext") | nindent 8 }} {{- if .Values.frontend.terminationGracePeriodSeconds }} terminationGracePeriodSeconds: {{ .Values.frontend.terminationGracePeriodSeconds }} {{- end }} @@ -106,6 +101,7 @@ spec: lifecycle: {{- toYaml . | nindent 10 }} {{- end }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.frontend "key" "securityContext") | nindent 10 }} resources: {{ toYaml .Values.frontend.resources | indent 10 }} volumeMounts: diff --git a/charts/flagsmith/templates/deployment-sse.yaml b/charts/flagsmith/templates/deployment-sse.yaml index 8f211ac..e18c42a 100644 --- a/charts/flagsmith/templates/deployment-sse.yaml +++ b/charts/flagsmith/templates/deployment-sse.yaml @@ -56,12 +56,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - securityContext: - {{- $securityContext := .Values.sse.podSecurityContext | default (dict) | deepCopy }} - {{- if .Values.sse.defaultPodSecurityContext.enabled }} - {{- $securityContext = $securityContext | merge (omit .Values.sse.defaultPodSecurityContext "enabled") }} - {{- end }} - {{- toYaml $securityContext | nindent 8 }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.sse "key" "podSecurityContext") | nindent 8 }} {{- if .Values.sse.terminationGracePeriodSeconds }} terminationGracePeriodSeconds: {{ .Values.sse.terminationGracePeriodSeconds }} {{- end }} @@ -104,6 +99,7 @@ spec: lifecycle: {{- toYaml . | nindent 10 }} {{- end }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.sse "key" "securityContext") | nindent 10 }} resources: {{ toYaml .Values.sse.resources | indent 10 }} volumeMounts: diff --git a/charts/flagsmith/templates/deployment-task-processor.yaml b/charts/flagsmith/templates/deployment-task-processor.yaml index f1086e1..ce4f0e2 100644 --- a/charts/flagsmith/templates/deployment-task-processor.yaml +++ b/charts/flagsmith/templates/deployment-task-processor.yaml @@ -60,12 +60,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - securityContext: - {{- $securityContext := .Values.taskProcessor.podSecurityContext | default (dict) | deepCopy }} - {{- if .Values.taskProcessor.defaultPodSecurityContext.enabled }} - {{- $securityContext = $securityContext | merge (omit .Values.taskProcessor.defaultPodSecurityContext "enabled") }} - {{- end }} - {{- toYaml $securityContext | nindent 8 }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.taskProcessor "key" "podSecurityContext") | nindent 8 }} {{- if .Values.taskProcessor.terminationGracePeriodSeconds }} terminationGracePeriodSeconds: {{ .Values.taskProcessor.terminationGracePeriodSeconds }} {{- end }} @@ -134,6 +129,7 @@ spec: lifecycle: {{- toYaml . | nindent 10 }} {{- end }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.taskProcessor "key" "securityContext") | nindent 10 }} resources: {{ toYaml .Values.taskProcessor.resources | indent 10 }} volumeMounts: diff --git a/charts/flagsmith/templates/jobs-migrate-analytics-data.yaml b/charts/flagsmith/templates/jobs-migrate-analytics-data.yaml index 6733c1e..6214d61 100644 --- a/charts/flagsmith/templates/jobs-migrate-analytics-data.yaml +++ b/charts/flagsmith/templates/jobs-migrate-analytics-data.yaml @@ -23,6 +23,7 @@ spec: {{- if .Values.jobs.migrateDb.shareProcessNamespace }} {{- end }} shareProcessNamespace: true + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.jobs.migrateAnalyticsData "key" "podSecurityContext") | nindent 8 }} containers: - name: migrate-analytics-data image: {{ .Values.api.image.repository }}:{{ .Values.api.image.tag | default .Chart.AppVersion }} @@ -30,6 +31,7 @@ spec: {{- if .Values.jobs.migrateAnalyticsData.args }} args: {{ toYaml .Values.jobs.migrateAnalyticsData.args | nindent 8 }} {{- end }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.jobs.migrateAnalyticsData "key" "securityContext") | nindent 10 }} env: {{ include (print $.Template.BasePath "/_api_environment.yaml") . | nindent 8 }} {{- with .Values.jobs.migrateDb.extraContainers }} {{ if typeIs "string" . }} diff --git a/charts/flagsmith/templates/jobs-migrate-db.yaml b/charts/flagsmith/templates/jobs-migrate-db.yaml index 4515511..55083b7 100644 --- a/charts/flagsmith/templates/jobs-migrate-db.yaml +++ b/charts/flagsmith/templates/jobs-migrate-db.yaml @@ -48,12 +48,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - securityContext: - {{- $securityContext := .Values.jobs.migrateDb.podSecurityContext | default (dict) | deepCopy }} - {{- if .Values.jobs.migrateDb.defaultPodSecurityContext.enabled }} - {{- $securityContext = $securityContext | merge (omit .Values.jobs.migrateDb.defaultPodSecurityContext "enabled") }} - {{- end }} - {{- toYaml $securityContext | nindent 8 }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.jobs.migrateDb "key" "podSecurityContext") | nindent 8 }} {{- if .Values.jobs.migrateDb.serviceAccountName }} serviceAccountName: {{ .Values.jobs.migrateDb.serviceAccountName }} {{- end }} @@ -72,6 +67,7 @@ spec: {{- else }} args: ["migrate"] {{- end }} + securityContext: {{- include "flagsmith.mergedSecurityContext" (dict "component" .Values.jobs.migrateDb "key" "securityContext") | nindent 10 }} env: {{- include (print $.Template.BasePath "/_api_environment.yaml") . | nindent 8 }} {{- if and .Values.jobs.migrateDb.databaseUrl .Values.jobs.migrateDb.databaseUrl.fromExistingSecret.enabled }} diff --git a/charts/flagsmith/values.yaml b/charts/flagsmith/values.yaml index bad51b8..ab5f2b0 100644 --- a/charts/flagsmith/values.yaml +++ b/charts/flagsmith/values.yaml @@ -94,6 +94,15 @@ api: # runAsNonRoot: true # TODO: enable this, conditional on tag semver # runAsUser: 1000 # runAsGroup: 1000 + # Applies to the flagsmith-api container, the migrate-db init container, + # and the bootstrap init container (all run the same image). + securityContext: {} + defaultSecurityContext: + enabled: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL livenessProbe: # path is the API path to be used for health checks. Used if exec is not set. path: /health/liveness/ @@ -188,6 +197,13 @@ frontend: # runAsNonRoot: true # TODO: enable this, conditional on tag semver # runAsUser: 1000 # runAsGroup: 1000 + securityContext: {} + defaultSecurityContext: + enabled: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL livenessProbe: failureThreshold: 20 initialDelaySeconds: 20 @@ -271,6 +287,13 @@ taskProcessor: # runAsNonRoot: true # TODO: enable this, conditional on tag semver # runAsUser: 1000 # runAsGroup: 1000 + securityContext: {} + defaultSecurityContext: + enabled: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL extraInitContainers: [] extraContainers: [] extraEnv: {} @@ -427,6 +450,13 @@ sse: # runAsNonRoot: true # TODO: enable this, conditional on tag semver # runAsUser: 1000 # runAsGroup: 1000 + securityContext: {} + defaultSecurityContext: + enabled: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL livenessProbe: path: /health/liveness/ failureThreshold: 5 @@ -591,9 +621,17 @@ jobs: annotations: {} ttlSecondsAfterFinished: 3600 restartPolicy: OnFailure + podSecurityContext: {} defaultPodSecurityContext: enabled: true # runAsNonRoot: true + securityContext: {} + defaultSecurityContext: + enabled: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL extraContainers: [] extraVolumes: [] command: [] @@ -615,6 +653,17 @@ jobs: # itself (`metadata.annotations`). See `jobs.migrateDb.annotations` # for typical use cases (Helm hooks, ArgoCD sync waves, etc.). annotations: {} + podSecurityContext: {} + defaultPodSecurityContext: + enabled: true + # runAsNonRoot: true + securityContext: {} + defaultSecurityContext: + enabled: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL args: [] extraContainers: [] extraVolumes: []