Skip to content

Commit 3258720

Browse files
author
jo.perez
committed
Allow configuring TPM init container security context
## Summary - let the TPM init container run as root so the plugin copy succeeds on root-owned PVCs - add values to control the init container security context, chown behaviour, mount and state paths - update chart docs/version and ensure configmap uses the new helper values ## Testing - helm lint charts/spire
1 parent 0f5bb04 commit 3258720

File tree

8 files changed

+90
-15
lines changed

8 files changed

+90
-15
lines changed

charts/spire/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: spire
33
description: >
44
A Helm chart for deploying the complete Spire stack including: spire-server, spire-agent, spiffe-csi-driver, spiffe-oidc-discovery-provider and spire-controller-manager.
55
type: application
6-
version: 0.27.0
6+
version: 0.27.1
77
appVersion: "1.13.0"
88
keywords: ["spiffe", "spire", "spire-server", "spire-agent", "oidc", "spire-controller-manager"]
99
home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire
@@ -28,7 +28,7 @@ dependencies:
2828
- name: spire-server
2929
condition: spire-server.enabled
3030
repository: file://./charts/spire-server
31-
version: 0.1.0
31+
version: 0.1.1
3232
- name: spire-agent
3333
condition: spire-agent.enabled
3434
repository: file://./charts/spire-agent

charts/spire/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# spire
22

3-
![Version: 0.27.0](https://img.shields.io/badge/Version-0.27.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.13.0](https://img.shields.io/badge/AppVersion-1.13.0-informational?style=flat-square)
3+
![Version: 0.27.1](https://img.shields.io/badge/Version-0.27.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.13.0](https://img.shields.io/badge/AppVersion-1.13.0-informational?style=flat-square)
44
[![Development Phase](https://github.com/spiffe/spiffe/blob/main/.img/maturity/dev.svg)](https://github.com/spiffe/spiffe/blob/main/MATURITY.md#development)
55

66
A Helm chart for deploying the complete Spire stack including: spire-server, spire-agent, spiffe-csi-driver, spiffe-oidc-discovery-provider and spire-controller-manager.
@@ -262,7 +262,7 @@ Now you can interact with the Spire agent socket from your own application. The
262262
| file://./charts/spiffe-oidc-discovery-provider | spiffe-oidc-discovery-provider | 0.1.0 |
263263
| file://./charts/spire-agent | spire-agent | 0.1.0 |
264264
| file://./charts/spire-agent | upstream-spire-agent(spire-agent) | 0.1.0 |
265-
| file://./charts/spire-server | spire-server | 0.1.0 |
265+
| file://./charts/spire-server | spire-server | 0.1.1 |
266266
| file://./charts/tornjak-frontend | tornjak-frontend | 0.1.0 |
267267

268268
<!-- The parameters section is generated using helm-docs.sh and should not be edited by hand. -->

charts/spire/charts/spire-server/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: v2
22
name: spire-server
33
description: A Helm chart to install the SPIRE server.
44
type: application
5-
version: 0.1.0
5+
version: 0.1.1
66
appVersion: "1.13.0"
77
keywords: ["spiffe", "spire-server", "spire-controller-manager"]
88
home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire

charts/spire/charts/spire-server/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# spire-server
22

3-
![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.7.2](https://img.shields.io/badge/AppVersion-1.7.2-informational?style=flat-square)
3+
![Version: 0.1.1](https://img.shields.io/badge/Version-0.1.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.13.0](https://img.shields.io/badge/AppVersion-1.13.0-informational?style=flat-square)
44

55
A Helm chart to install the SPIRE server.
66

@@ -402,6 +402,11 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
402402
| `nodeAttestor.tpmDirect.image.tag` | Overrides the image tag | `v1.9.0` |
403403
| `nodeAttestor.tpmDirect.checksum` | The sha256 checksum of the plugin binary | `46d0caad8c25a027dd11c93e18b58a8bc6fbd9f1fe2e36fa2a0dd440986de4dc` |
404404
| `nodeAttestor.tpmDirect.pluginPath` | The filename in the container of the plugin | `/app/tpm_attestor_server` |
405+
| `nodeAttestor.tpmDirect.mountPath` | Mount path where the TPM plugin binary will be staged for the main container | `/tpm` |
406+
| `nodeAttestor.tpmDirect.pluginDestinationPath` | Override the destination path of the plugin inside the mount path | `""` |
407+
| `nodeAttestor.tpmDirect.stateDir` | Directory (within spire-data) used to hold TPM plugin state (certs, hashes) | `/run/spire/data/tpm-direct` |
408+
| `nodeAttestor.tpmDirect.chownAfterCopy` | Chown TPM state directory to match pod security context after files are staged | `true` |
409+
| `nodeAttestor.tpmDirect.initSecurityContext` | Security context overrides for the TPM init container | `{}` |
405410
| `nodeAttestor.tpmDirect.cas` | A dictionary of TPM CA PEM or DER files that are allowed to connect. | `{}` |
406411
| `nodeAttestor.tpmDirect.hashes` | A list of TPM hashes that are allowed to connect. | `[]` |
407412
| `nodeAttestor.awsIID.enabled` | Enable the aws_iid node attestor | `false` |

charts/spire/charts/spire-server/templates/_helpers.tpl

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,56 @@ Create the name of the service account to use
286286
{{- $config | toYaml }}
287287
{{- end }}
288288

289+
{{- define "spire-server.tpm-direct-mount-path" -}}
290+
{{- $mountPath := default "/tpm" .Values.nodeAttestor.tpmDirect.mountPath -}}
291+
{{- if not (hasPrefix "/" $mountPath) }}
292+
{{- fail "nodeAttestor.tpmDirect.mountPath must be an absolute path" }}
293+
{{- end }}
294+
{{- $mountPath -}}
295+
{{- end }}
296+
297+
{{- define "spire-server.tpm-direct-state-dir" -}}
298+
{{- $stateDir := default "/run/spire/data/tpm-direct" .Values.nodeAttestor.tpmDirect.stateDir -}}
299+
{{- if not (hasPrefix "/" $stateDir) }}
300+
{{- fail "nodeAttestor.tpmDirect.stateDir must be an absolute path" }}
301+
{{- end }}
302+
{{- $stateDir -}}
303+
{{- end }}
304+
305+
{{- define "spire-server.tpm-direct-plugin-destination" -}}
306+
{{- $mountPath := (include "spire-server.tpm-direct-mount-path" . | trim) -}}
307+
{{- $mountPath = trimSuffix "/" $mountPath -}}
308+
{{- $defaultTarget := printf "%s/%s" $mountPath "tpm_attestor_server" -}}
309+
{{- $dest := default $defaultTarget .Values.nodeAttestor.tpmDirect.pluginDestinationPath -}}
310+
{{- if not (hasPrefix "/" $dest) }}
311+
{{- fail "nodeAttestor.tpmDirect.pluginDestinationPath must be an absolute path" }}
312+
{{- end }}
313+
{{- $dest -}}
314+
{{- end }}
315+
316+
{{- define "spire-server.tpm-direct-init-security-context" -}}
317+
{{- $defaults := dict "runAsUser" 0 "runAsGroup" 0 "allowPrivilegeEscalation" false }}
318+
{{- $overrides := deepCopy (default (dict) .Values.nodeAttestor.tpmDirect.initSecurityContext) }}
319+
{{- $merged := mergeOverwrite (deepCopy $defaults) $overrides }}
320+
{{- if hasKey $merged "runAsUser" }}
321+
{{- $_ := set $merged "runAsUser" (int (index $merged "runAsUser")) }}
322+
{{- end }}
323+
{{- if hasKey $merged "runAsGroup" }}
324+
{{- $_ := set $merged "runAsGroup" (int (index $merged "runAsGroup")) }}
325+
{{- end }}
326+
{{- if hasKey $merged "supplementalGroups" }}
327+
{{- $supGroups := list }}
328+
{{- range $merged.supplementalGroups }}
329+
{{- $supGroups = append $supGroups (int .) }}
330+
{{- end }}
331+
{{- $_ := set $merged "supplementalGroups" $supGroups }}
332+
{{- end }}
333+
{{- if not (hasKey $merged "seccompProfile") }}
334+
{{- $_ := set $merged "seccompProfile" (dict "type" "RuntimeDefault") }}
335+
{{- end }}
336+
{{- toYaml $merged }}
337+
{{- end }}
338+
289339
{{- define "spire-server.upstream-spire-address" }}
290340
{{- if ne (len (dig "spire" "upstreamSpireAddress" "" .Values.global)) 0 }}
291341
{{- print .Values.global.spire.upstreamSpireAddress }}

charts/spire/charts/spire-server/templates/configmap.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,18 +213,18 @@ plugins:
213213
{{- with .Values.nodeAttestor.tpmDirect }}
214214
{{- if eq (.enabled | toString) "true" }}
215215
tpm:
216-
plugin_cmd: "/tpm/tpm_attestor_server"
216+
plugin_cmd: "{{ include "spire-server.tpm-direct-plugin-destination" $ | trim }}"
217217
plugin_checksum: {{ .checksum }}
218218
plugin_data:
219219
{{- if ne (len .cas) 0 }}
220220
ca_path: /tpm-direct-cas
221221
{{- else }}
222-
ca_path: /run/spire/data/tpm-direct/certs
222+
ca_path: {{ printf "%s/certs" (include "spire-server.tpm-direct-state-dir" $ | trim) }}
223223
{{- end }}
224224
{{- if ne (len .hashes) 0 }}
225225
hash_path: /tmp-direct-hashes
226226
{{- else }}
227-
hash_path: /run/spire/data/tpm-direct/hashes
227+
hash_path: {{ printf "%s/hashes" (include "spire-server.tpm-direct-state-dir" $ | trim) }}
228228
{{- end }}
229229
{{- end }}
230230
{{- end }}

charts/spire/charts/spire-server/templates/server-resource.yaml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,21 +157,30 @@ spec:
157157
imagePullPolicy: {{ .Values.credentialComposer.cel.image.pullPolicy }}
158158
{{- end }}
159159
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
160+
{{- $tpmPluginDst := (include "spire-server.tpm-direct-plugin-destination" . | trim) }}
161+
{{- $tpmMountPath := (include "spire-server.tpm-direct-mount-path" . | trim) }}
162+
{{- $tpmStateDir := (include "spire-server.tpm-direct-state-dir" . | trim) }}
163+
{{- $runAsUser := (dig "runAsUser" nil $podSecurityContext) }}
164+
{{- $runAsGroup := (dig "runAsGroup" nil $podSecurityContext) | default $runAsUser }}
165+
{{- $tpmInitChown := (and $runAsUser (dig "chownAfterCopy" true .Values.nodeAttestor.tpmDirect)) }}
160166
- name: init-tpm-direct
161167
securityContext:
162-
{{- include "spire-lib.securitycontext" . | nindent 12 }}
168+
{{- include "spire-server.tpm-direct-init-security-context" . | nindent 12 }}
163169
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.nodeAttestor.tpmDirect.image "global" .Values.global) }}
164170
command:
165171
- sh
166172
- -ec
167173
- |
168174
# SPIRE must be able to fork the plugin directly within its container. Copy the plugin into a volume that can be mounted where SPIRE can execute it.
169-
cp -a {{ .Values.nodeAttestor.tpmDirect.pluginPath }} /tpm/tpm_attestor_server
170-
mkdir -p /run/spire/data/tpm-direct/certs
171-
mkdir -p /run/spire/data/tpm-direct/hashes
175+
cp {{ .Values.nodeAttestor.tpmDirect.pluginPath }} {{ $tpmPluginDst }}
176+
mkdir -p {{ $tpmStateDir }}/certs
177+
mkdir -p {{ $tpmStateDir }}/hashes
178+
{{- if $tpmInitChown }}
179+
chown -R {{ $runAsUser }}:{{ $runAsGroup }} {{ $tpmStateDir }}
180+
{{- end }}
172181
volumeMounts:
173182
- name: tpm-direct
174-
mountPath: /tpm
183+
mountPath: {{ $tpmMountPath }}
175184
- name: spire-data
176185
mountPath: /run/spire/data
177186
imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.image.pullPolicy }}
@@ -343,8 +352,9 @@ spec:
343352
readOnly: true
344353
{{- end }}
345354
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
355+
{{- $tpmMountPath := (include "spire-server.tpm-direct-mount-path" . | trim) }}
346356
- name: tpm-direct
347-
mountPath: /tpm
357+
mountPath: {{ $tpmMountPath }}
348358
readOnly: true
349359
{{- if ne (len .Values.nodeAttestor.tpmDirect.cas) 0 }}
350360
- name: tpm-direct-cas

charts/spire/charts/spire-server/values.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,16 @@ nodeAttestor:
991991
checksum: 46d0caad8c25a027dd11c93e18b58a8bc6fbd9f1fe2e36fa2a0dd440986de4dc
992992
## @param nodeAttestor.tpmDirect.pluginPath The filename in the container of the plugin
993993
pluginPath: /app/tpm_attestor_server
994+
## @param nodeAttestor.tpmDirect.mountPath Mount path where the TPM plugin binary will be staged for the main container
995+
mountPath: /tpm
996+
## @param nodeAttestor.tpmDirect.pluginDestinationPath Override the destination path of the plugin inside the mount path
997+
pluginDestinationPath: ""
998+
## @param nodeAttestor.tpmDirect.stateDir Directory (within spire-data) used to hold TPM plugin state (certs, hashes)
999+
stateDir: /run/spire/data/tpm-direct
1000+
## @param nodeAttestor.tpmDirect.chownAfterCopy Chown TPM state directory to match pod security context after files are staged
1001+
chownAfterCopy: true
1002+
## @param nodeAttestor.tpmDirect.initSecurityContext Security context overrides for the TPM init container
1003+
initSecurityContext: {}
9941004
## @param nodeAttestor.tpmDirect.cas A dictionary of TPM CA PEM or DER files that are allowed to connect.
9951005
cas: {}
9961006
## @param nodeAttestor.tpmDirect.hashes A list of TPM hashes that are allowed to connect.

0 commit comments

Comments
 (0)