Skip to content

Commit 25d612f

Browse files
bpoweliobischof
andauthored
feat: use security contexts and mount configs instead of chown init containers (#223)
* Example to create postgres TLS cert without needing root in k8s The prior example used apk to add openssl and curl, which needed root. This makes the certs in an initContainer (alpine/openssl), then sends to k8s in a separate container (alpine/curl), sharing state through an emptyDir * be less verbose with cert creation (avoid leakage to logs) * chmod secrets in an emptyDir (avoiding need for root to chown to running user) This relies on the fact that an emptyDir is set up with appropriate permissions for whichever userid is running in the pod. The prior solution required running chown/chmod by root in the init container. This obviates the need for root, which is not permitted in many kubernetes installs as a security precaution. Fixes #177 and also fixes #178 (since there is no chown anymore). * directly mount secrets * fsGroup * set defaulMode for secrets to 0440 This makes files user/group readable but not by others. Without this, mode is set to 0644 (rw for user, r for group and others). Also removes an unused emptyDir in debug replicaset --------- Co-authored-by: Elio Bischof <[email protected]>
1 parent 33376c6 commit 25d612f

File tree

8 files changed

+160
-220
lines changed

8 files changed

+160
-220
lines changed

charts/zitadel/Chart.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: zitadel
33
description: A Helm chart for ZITADEL
44
type: application
55
appVersion: "v2.55.0"
6-
version: 8.0.0
6+
version: 8.1.0
77
kubeVersion: ">= 1.21.0-0"
88
icon: https://zitadel.com/zitadel-logo-dark.svg
99
maintainers:

charts/zitadel/templates/_helpers.tpl

+1-23
Original file line numberDiff line numberDiff line change
@@ -67,28 +67,6 @@ Create the name of the service account to use
6767
{{- end }}
6868
{{- end }}
6969

70-
{{/*
71-
Create copy command or empty string
72-
*/}}
73-
{{- define "zitadel.makecpcommand" -}}
74-
{{- if .value -}}
75-
{{ printf "cp -r %s /chowned-secrets/" .path }}
76-
{{- end -}}
77-
{{- end -}}
78-
79-
{{/*
80-
Join copy commands
81-
*/}}
82-
{{- define "zitadel.joincpcommands" -}}
83-
{{- $cmd := "" }}
84-
{{- range .commands -}}
85-
{{- if . -}}
86-
{{- $cmd = printf "%s && %s" ( default "yes" . ) $cmd -}}
87-
{{- end -}}
88-
{{- end -}}
89-
{{ print $cmd }}
90-
{{- end -}}
91-
9270
{{/*
9371
Returns true if the full path is defined and the value at the end of the path is not empty
9472
*/}}
@@ -107,7 +85,7 @@ Returns true if the full path is defined and the value at the end of the path is
10785
{{- end -}}
10886

10987
{{/*
110-
Returns the database config from the secreConfig or else from the configmapConfig
88+
Returns the database config from the secretConfig or else from the configmapConfig
11189
*/}}
11290
{{- define "zitadel.dbconfig.json" -}}
11391
{{- if include "deepCheck" (dict "root" . "path" (splitList "." "Values.zitadel.secretConfig.Database")) -}}

charts/zitadel/templates/debug_replicaset.yaml

+15-31
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ spec:
3737
{{- toYaml .Values.securityContext | nindent 14 }}
3838
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}-debug"
3939
imagePullPolicy: {{ .Values.image.pullPolicy }}
40-
command: [ "/bin/bash", "-c", 'echo "You can now open a shell within this pod by running the following command:"; echo ""; echo "kubectl --namespace {{ .Release.Namespace }} exec -it ${HOSTNAME} -- bash"; echo ""; echo "Check the directories /config and /.secrets for ZITADEL config files"; echo "also check the ZITADEL_ prefixed environment variables"; echo "For zitadel commands that need the masterkey, pass the flag --masterkeyFromEnv"; echo "this pod completes automatically in a day"; echo "Make sure you set zitadel.debug.enabled to false and upgrade the release when you are done"; echo "Also, delete the debug pods replica set by running the following command:"; echo; echo "kubectl --namespace {{ .Release.Namespace }} delete replicaset {{ include "zitadel.fullname" . }}-debug"; sleep 86400' ]
40+
command: [ "/bin/bash", "-c", 'echo "You can now open a shell within this pod by running the following command:"; echo ""; echo "kubectl --namespace {{ .Release.Namespace }} exec -it ${HOSTNAME} -- bash"; echo ""; echo "Check the /config directory and the secret mounts for ZITADEL config files"; echo "also check the ZITADEL_ prefixed environment variables"; echo "For zitadel commands that need the masterkey, pass the flag --masterkeyFromEnv"; echo "this pod completes automatically in a day"; echo "Make sure you set zitadel.debug.enabled to false and upgrade the release when you are done"; echo "Also, delete the debug pods replica set by running the following command:"; echo; echo "kubectl --namespace {{ .Release.Namespace }} delete replicaset {{ include "zitadel.fullname" . }}-debug"; sleep 86400' ]
4141
env:
4242
- name: ZITADEL_MASTERKEY
4343
valueFrom:
@@ -49,60 +49,41 @@ spec:
4949
{{- $dbEnv := get (include "zitadel.dbkey.json" . | fromJson) "env" }}
5050
{{- if (or .Values.zitadel.dbSslCaCrt .Values.zitadel.dbSslCaCrtSecret) }}
5151
- name: ZITADEL_DATABASE_{{ $dbEnv }}_USER_SSL_ROOTCERT
52-
value: /.secrets/db-ssl-ca-crt/ca.crt
52+
value: /db-ssl-ca-crt/ca.crt
5353
{{- end }}
5454
{{- if .Values.zitadel.dbSslUserCrtSecret }}
5555
- name: ZITADEL_DATABASE_{{ $dbEnv }}_USER_SSL_CERT
56-
value: /.secrets/db-ssl-user-crt/tls.crt
56+
value: /db-ssl-user-crt/tls.crt
5757
- name: ZITADEL_DATABASE_{{ $dbEnv }}_USER_SSL_KEY
58-
value: /.secrets/db-ssl-user-crt/tls.key
58+
value: /db-ssl-user-crt/tls.key
5959
{{- end}}
6060
{{- with .Values.env }}
6161
{{- toYaml . | nindent 12 }}
6262
{{- end }}
6363
volumeMounts:
6464
- name: zitadel-config-yaml
6565
mountPath: /config
66-
- name: chowned-secrets
67-
mountPath: /.secrets
68-
{{- if or .Values.zitadel.secretConfig .Values.zitadel.dbSslCaCrt .Values.zitadel.dbSslCaCrtSecret .Values.zitadel.dbSslUserCrtSecret .Values.zitadel.configSecretName }}
69-
initContainers:
70-
- args:
71-
- "{{ include "zitadel.joincpcommands" (dict "commands" (list
72-
(include "zitadel.makecpcommand" (dict "value" .Values.zitadel.secretConfig "path" "/zitadel-secrets-yaml/" ))
73-
(include "zitadel.makecpcommand" (dict "value" .Values.zitadel.configSecretName "path" "/zitadel-secret-config-yaml/" ))
74-
(include "zitadel.makecpcommand" (dict "value" (or .Values.zitadel.dbSslCaCrt .Values.zitadel.dbSslCaCrtSecret) "path" "/db-ssl-ca-crt/" ))
75-
(include "zitadel.makecpcommand" (dict "value" .Values.zitadel.dbSslUserCrtSecret "path" "/db-ssl-user-crt/" ))
76-
)) }} chown -R 1000:1000 /chowned-secrets/ && find /chowned-secrets/ -type f -exec chmod 400 -- {} + "
77-
command:
78-
- sh
79-
- -c
80-
image: "{{ .Values.chownImage.repository }}:{{ .Values.chownImage.tag }}"
81-
imagePullPolicy: {{ .Values.chownImage.pullPolicy }}
82-
name: chown
83-
volumeMounts:
84-
- name: chowned-secrets
85-
mountPath: /chowned-secrets
66+
readOnly: true
8667
{{- if .Values.zitadel.secretConfig }}
8768
- name: zitadel-secrets-yaml
8869
mountPath: /zitadel-secrets-yaml
70+
readOnly: true
8971
{{- end }}
9072
{{- if .Values.zitadel.configSecretName }}
9173
- name: zitadel-secret-config-yaml
9274
mountPath: /zitadel-secret-config-yaml
75+
readOnly: true
9376
{{- end }}
9477
{{- if (or .Values.zitadel.dbSslCaCrt .Values.zitadel.dbSslCaCrtSecret) }}
9578
- name: db-ssl-ca-crt
9679
mountPath: /db-ssl-ca-crt
80+
readOnly: true
9781
{{- end }}
9882
{{- if .Values.zitadel.dbSslUserCrtSecret }}
9983
- name: db-ssl-user-crt
10084
mountPath: /db-ssl-user-crt
85+
readOnly: true
10186
{{- end }}
102-
securityContext:
103-
runAsNonRoot: false
104-
runAsUser: 0
105-
{{- end }}
10687
volumes:
10788
- name: zitadel-config-yaml
10889
configMap:
@@ -111,29 +92,32 @@ spec:
11192
- name: zitadel-secrets-yaml
11293
secret:
11394
secretName: zitadel-secrets-yaml
95+
defaultMode: 0440
11496
{{- end }}
11597
{{- if .Values.zitadel.configSecretName }}
11698
- name: zitadel-secret-config-yaml
11799
secret:
118100
secretName: {{ .Values.zitadel.configSecretName }}
101+
defaultMode: 0440
119102
{{- end }}
120103
{{- if .Values.zitadel.dbSslCaCrt }}
121104
- name: db-ssl-ca-crt
122105
secret:
123106
secretName: db-ssl-ca-crt
107+
defaultMode: 0440
124108
{{- end }}
125109
{{- if .Values.zitadel.dbSslCaCrtSecret }}
126110
- name: db-ssl-ca-crt
127111
secret:
128112
secretName: {{ .Values.zitadel.dbSslCaCrtSecret }}
113+
defaultMode: 0440
129114
{{- end }}
130115
{{- if .Values.zitadel.dbSslUserCrtSecret }}
131116
- name: db-ssl-user-crt
132117
secret:
133118
secretName: {{ .Values.zitadel.dbSslUserCrtSecret }}
119+
defaultMode: 0440
134120
{{- end }}
135-
- name: chowned-secrets
136-
emptyDir: {}
137121
{{- with .Values.nodeSelector }}
138122
nodeSelector:
139123
{{- toYaml . | nindent 8 }}
@@ -146,4 +130,4 @@ spec:
146130
tolerations:
147131
{{- toYaml . | nindent 8 }}
148132
{{- end }}
149-
{{- end }}
133+
{{- end }}

charts/zitadel/templates/deployment.yaml

+32-47
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ spec:
5050
- /config/zitadel-config-yaml
5151
{{- if .Values.zitadel.secretConfig }}
5252
- --config
53-
- /.secrets/zitadel-secrets-yaml/zitadel-secrets-yaml
53+
- /zitadel-secrets-yaml/zitadel-secrets-yaml
5454
{{- end }}
5555
{{- if and .Values.zitadel.configSecretName .Values.zitadel.configSecretKey }}
5656
- --config
57-
- /.secrets/zitadel-secret-config-yaml/{{ .Values.zitadel.configSecretKey }}
57+
- /zitadel-secret-config-yaml/{{ .Values.zitadel.configSecretKey }}
5858
{{- end }}
5959
- --masterkeyFromEnv
6060
env:
@@ -71,19 +71,19 @@ spec:
7171
{{- $dbEnv := get (include "zitadel.dbkey.json" . | fromJson) "env" }}
7272
{{- if (or .Values.zitadel.dbSslCaCrt .Values.zitadel.dbSslCaCrtSecret) }}
7373
- name: ZITADEL_DATABASE_{{ $dbEnv }}_USER_SSL_ROOTCERT
74-
value: /.secrets/db-ssl-ca-crt/ca.crt
74+
value: /db-ssl-ca-crt/ca.crt
7575
{{- end }}
7676
{{- if .Values.zitadel.dbSslUserCrtSecret }}
7777
- name: ZITADEL_DATABASE_{{ $dbEnv }}_USER_SSL_CERT
78-
value: /.secrets/db-ssl-user-crt/tls.crt
78+
value: /db-ssl-user-crt/tls.crt
7979
- name: ZITADEL_DATABASE_{{ $dbEnv }}_USER_SSL_KEY
80-
value: /.secrets/db-ssl-user-crt/tls.key
80+
value: /db-ssl-user-crt/tls.key
8181
{{- end }}
8282
{{- if .Values.zitadel.serverSslCrtSecret }}
8383
- name: ZITADEL_TLS_CERTPATH
84-
value: /.secrets/server-ssl-crt/tls.crt
84+
value: /server-ssl-crt/tls.crt
8585
- name: ZITADEL_TLS_KEYPATH
86-
value: /.secrets/server-ssl-crt/tls.key
86+
value: /server-ssl-crt/tls.key
8787
{{- end }}
8888
{{- if .Values.zitadel.selfSignedCert.enabled }}
8989
- name: ZITADEL_TLS_CERTPATH
@@ -154,59 +154,43 @@ spec:
154154
volumeMounts:
155155
- name: zitadel-config-yaml
156156
mountPath: /config
157-
- name: chowned-secrets
158-
mountPath: /.secrets
159-
{{- if .Values.zitadel.selfSignedCert.enabled }}
160-
- name: tls
161-
mountPath: /etc/tls
162-
{{- end }}
163-
{{- with .Values.extraVolumeMounts }}
164-
{{- toYaml . | nindent 10 }}
165-
{{- end }}
166-
resources:
167-
{{- toYaml .Values.resources | nindent 14 }}
168-
initContainers:
169-
- args:
170-
- "{{ include "zitadel.joincpcommands" (dict "commands" (list
171-
(include "zitadel.makecpcommand" (dict "value" .Values.zitadel.secretConfig "path" "/zitadel-secrets-yaml/" ))
172-
(include "zitadel.makecpcommand" (dict "value" .Values.zitadel.configSecretName "path" "/zitadel-secret-config-yaml/" ))
173-
(include "zitadel.makecpcommand" (dict "value" (or .Values.zitadel.dbSslCaCrt .Values.zitadel.dbSslCaCrtSecret) "path" "/db-ssl-ca-crt/" ))
174-
(include "zitadel.makecpcommand" (dict "value" .Values.zitadel.dbSslUserCrtSecret "path" "/db-ssl-user-crt/" ))
175-
(include "zitadel.makecpcommand" (dict "value" .Values.zitadel.serverSslCrtSecret "path" "/server-ssl-crt/" ))
176-
)) }} chown -R 1000:1000 /chowned-secrets/ && find /chowned-secrets/ -type f -exec chmod 400 -- {} + "
177-
command:
178-
- sh
179-
- -c
180-
image: "{{ .Values.chownImage.repository }}:{{ .Values.chownImage.tag }}"
181-
imagePullPolicy: {{ .Values.chownImage.pullPolicy }}
182-
name: chown
183-
volumeMounts:
184-
- name: chowned-secrets
185-
mountPath: /chowned-secrets
157+
readOnly: true
186158
{{- if .Values.zitadel.secretConfig }}
187159
- name: zitadel-secrets-yaml
188160
mountPath: /zitadel-secrets-yaml
161+
readOnly: true
189162
{{- end }}
190163
{{- if .Values.zitadel.configSecretName }}
191164
- name: zitadel-secret-config-yaml
192165
mountPath: /zitadel-secret-config-yaml
166+
readOnly: true
193167
{{- end }}
194168
{{- if (or .Values.zitadel.dbSslCaCrt .Values.zitadel.dbSslCaCrtSecret) }}
195169
- name: db-ssl-ca-crt
196170
mountPath: /db-ssl-ca-crt
171+
readOnly: true
197172
{{- end }}
198173
{{- if .Values.zitadel.dbSslUserCrtSecret }}
199174
- name: db-ssl-user-crt
200175
mountPath: /db-ssl-user-crt
176+
readOnly: true
201177
{{- end }}
202178
{{- if .Values.zitadel.serverSslCrtSecret }}
203179
- name: server-ssl-crt
204180
mountPath: /server-ssl-crt
181+
readOnly: true
205182
{{- end }}
206-
securityContext:
207-
runAsNonRoot: false
208-
runAsUser: 0
209-
{{- if .Values.zitadel.selfSignedCert.enabled }}
183+
{{- if .Values.zitadel.selfSignedCert.enabled }}
184+
- name: tls
185+
mountPath: /etc/tls
186+
{{- end }}
187+
{{- with .Values.extraVolumeMounts }}
188+
{{- toYaml . | nindent 10 }}
189+
{{- end }}
190+
resources:
191+
{{- toYaml .Values.resources | nindent 14 }}
192+
{{- if .Values.zitadel.selfSignedCert.enabled }}
193+
initContainers:
210194
- name: generate-self-signed-cert
211195
image: alpine/openssl
212196
env:
@@ -226,11 +210,8 @@ spec:
226210
- "-c"
227211
- "openssl req -nodes -x509 -sha256 -newkey rsa:4096 -keyout /etc/tls/tls.key -out /etc/tls/tls.crt -days 3560 -subj \"/CN=ZITADEL Chart Demo\" -addext \"subjectAltName = DNS:localhost,DNS:${POD_IP},DNS:${POD_NAME}{{- if .Values.zitadel.configmapConfig.ExternalDomain -}},DNS:{{- .Values.zitadel.configmapConfig.ExternalDomain -}}{{- end -}}{{- if .Values.zitadel.selfSignedCert.additionalDnsName -}},DNS:{{- .Values.zitadel.selfSignedCert.additionalDnsName -}}{{- end -}}\""
228212
securityContext:
229-
readOnlyRootFilesystem: true
230-
runAsNonRoot: true
231-
privileged: false
232-
runAsUser: 1000
233-
{{- end }}
213+
{{- toYaml .Values.securityContext | nindent 12 }}
214+
{{- end }}
234215
volumes:
235216
- name: zitadel-config-yaml
236217
configMap:
@@ -239,34 +220,38 @@ spec:
239220
- name: zitadel-secrets-yaml
240221
secret:
241222
secretName: zitadel-secrets-yaml
223+
defaultMode: 0440
242224
{{- end }}
243225
{{- if .Values.zitadel.configSecretName }}
244226
- name: zitadel-secret-config-yaml
245227
secret:
246228
secretName: {{ .Values.zitadel.configSecretName }}
229+
defaultMode: 0440
247230
{{- end }}
248231
{{- if .Values.zitadel.dbSslCaCrt }}
249232
- name: db-ssl-ca-crt
250233
secret:
251234
secretName: db-ssl-ca-crt
235+
defaultMode: 0440
252236
{{- end }}
253237
{{- if .Values.zitadel.dbSslCaCrtSecret }}
254238
- name: db-ssl-ca-crt
255239
secret:
256240
secretName: {{ .Values.zitadel.dbSslCaCrtSecret }}
241+
defaultMode: 0440
257242
{{- end }}
258243
{{- if .Values.zitadel.dbSslUserCrtSecret }}
259244
- name: db-ssl-user-crt
260245
secret:
261246
secretName: {{ .Values.zitadel.dbSslUserCrtSecret }}
247+
defaultMode: 0440
262248
{{- end }}
263249
{{- if .Values.zitadel.serverSslCrtSecret }}
264250
- name: server-ssl-crt
265251
secret:
266252
secretName: {{ .Values.zitadel.serverSslCrtSecret }}
253+
defaultMode: 0440
267254
{{- end }}
268-
- name: chowned-secrets
269-
emptyDir: {}
270255
{{- if .Values.zitadel.selfSignedCert.enabled }}
271256
- name: tls
272257
emptyDir: {}

0 commit comments

Comments
 (0)