diff --git a/charts/spire/Chart.yaml b/charts/spire/Chart.yaml index c93113bfe..e6f5a79c6 100644 --- a/charts/spire/Chart.yaml +++ b/charts/spire/Chart.yaml @@ -3,7 +3,7 @@ name: spire description: > 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. type: application -version: 0.27.0 +version: 0.27.1 appVersion: "1.13.0" keywords: ["spiffe", "spire", "spire-server", "spire-agent", "oidc", "spire-controller-manager"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire @@ -28,7 +28,7 @@ dependencies: - name: spire-server condition: spire-server.enabled repository: file://./charts/spire-server - version: 0.1.0 + version: 0.1.1 - name: spire-agent condition: spire-agent.enabled repository: file://./charts/spire-agent diff --git a/charts/spire/README.md b/charts/spire/README.md index 7ac9a111c..7ae0be384 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -1,6 +1,6 @@ # spire -![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) +![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) [![Development Phase](https://github.com/spiffe/spiffe/blob/main/.img/maturity/dev.svg)](https://github.com/spiffe/spiffe/blob/main/MATURITY.md#development) 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 | file://./charts/spiffe-oidc-discovery-provider | spiffe-oidc-discovery-provider | 0.1.0 | | file://./charts/spire-agent | spire-agent | 0.1.0 | | file://./charts/spire-agent | upstream-spire-agent(spire-agent) | 0.1.0 | -| file://./charts/spire-server | spire-server | 0.1.0 | +| file://./charts/spire-server | spire-server | 0.1.1 | | file://./charts/tornjak-frontend | tornjak-frontend | 0.1.0 | diff --git a/charts/spire/charts/spire-server/Chart.yaml b/charts/spire/charts/spire-server/Chart.yaml index 7aa04a7d9..fb924e0a8 100644 --- a/charts/spire/charts/spire-server/Chart.yaml +++ b/charts/spire/charts/spire-server/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: spire-server description: A Helm chart to install the SPIRE server. type: application -version: 0.1.0 +version: 0.1.1 appVersion: "1.13.0" keywords: ["spiffe", "spire-server", "spire-controller-manager"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index d94390ea2..f3ee31339 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -1,6 +1,6 @@ # spire-server -![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) +![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) A Helm chart to install the SPIRE server. @@ -402,6 +402,11 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr | `nodeAttestor.tpmDirect.image.tag` | Overrides the image tag | `v1.9.0` | | `nodeAttestor.tpmDirect.checksum` | The sha256 checksum of the plugin binary | `46d0caad8c25a027dd11c93e18b58a8bc6fbd9f1fe2e36fa2a0dd440986de4dc` | | `nodeAttestor.tpmDirect.pluginPath` | The filename in the container of the plugin | `/app/tpm_attestor_server` | +| `nodeAttestor.tpmDirect.mountPath` | Mount path where the TPM plugin binary will be staged for the main container | `/tpm` | +| `nodeAttestor.tpmDirect.pluginDestinationPath` | Override the destination path of the plugin inside the mount path | `""` | +| `nodeAttestor.tpmDirect.stateDir` | Directory (within spire-data) used to hold TPM plugin state (certs, hashes) | `/run/spire/data/tpm-direct` | +| `nodeAttestor.tpmDirect.chownAfterCopy` | Chown TPM state directory to match pod security context after files are staged | `true` | +| `nodeAttestor.tpmDirect.initSecurityContext` | Security context overrides for the TPM init container | `{}` | | `nodeAttestor.tpmDirect.cas` | A dictionary of TPM CA PEM or DER files that are allowed to connect. | `{}` | | `nodeAttestor.tpmDirect.hashes` | A list of TPM hashes that are allowed to connect. | `[]` | | `nodeAttestor.awsIID.enabled` | Enable the aws_iid node attestor | `false` | diff --git a/charts/spire/charts/spire-server/templates/_helpers.tpl b/charts/spire/charts/spire-server/templates/_helpers.tpl index f590dd6c0..7a682b9da 100644 --- a/charts/spire/charts/spire-server/templates/_helpers.tpl +++ b/charts/spire/charts/spire-server/templates/_helpers.tpl @@ -286,6 +286,56 @@ Create the name of the service account to use {{- $config | toYaml }} {{- end }} +{{- define "spire-server.tpm-direct-mount-path" -}} +{{- $mountPath := default "/tpm" .Values.nodeAttestor.tpmDirect.mountPath -}} +{{- if not (hasPrefix "/" $mountPath) }} +{{- fail "nodeAttestor.tpmDirect.mountPath must be an absolute path" }} +{{- end }} +{{- $mountPath -}} +{{- end }} + +{{- define "spire-server.tpm-direct-state-dir" -}} +{{- $stateDir := default "/run/spire/data/tpm-direct" .Values.nodeAttestor.tpmDirect.stateDir -}} +{{- if not (hasPrefix "/" $stateDir) }} +{{- fail "nodeAttestor.tpmDirect.stateDir must be an absolute path" }} +{{- end }} +{{- $stateDir -}} +{{- end }} + +{{- define "spire-server.tpm-direct-plugin-destination" -}} +{{- $mountPath := (include "spire-server.tpm-direct-mount-path" . | trim) -}} +{{- $mountPath = trimSuffix "/" $mountPath -}} +{{- $defaultTarget := printf "%s/%s" $mountPath "tpm_attestor_server" -}} +{{- $dest := default $defaultTarget .Values.nodeAttestor.tpmDirect.pluginDestinationPath -}} +{{- if not (hasPrefix "/" $dest) }} +{{- fail "nodeAttestor.tpmDirect.pluginDestinationPath must be an absolute path" }} +{{- end }} +{{- $dest -}} +{{- end }} + +{{- define "spire-server.tpm-direct-init-security-context" -}} +{{- $defaults := dict "runAsUser" 0 "runAsGroup" 0 "allowPrivilegeEscalation" false }} +{{- $overrides := deepCopy (default (dict) .Values.nodeAttestor.tpmDirect.initSecurityContext) }} +{{- $merged := mergeOverwrite (deepCopy $defaults) $overrides }} +{{- if hasKey $merged "runAsUser" }} +{{- $_ := set $merged "runAsUser" (int (index $merged "runAsUser")) }} +{{- end }} +{{- if hasKey $merged "runAsGroup" }} +{{- $_ := set $merged "runAsGroup" (int (index $merged "runAsGroup")) }} +{{- end }} +{{- if hasKey $merged "supplementalGroups" }} +{{- $supGroups := list }} +{{- range $merged.supplementalGroups }} +{{- $supGroups = append $supGroups (int .) }} +{{- end }} +{{- $_ := set $merged "supplementalGroups" $supGroups }} +{{- end }} +{{- if not (hasKey $merged "seccompProfile") }} +{{- $_ := set $merged "seccompProfile" (dict "type" "RuntimeDefault") }} +{{- end }} +{{- toYaml $merged }} +{{- end }} + {{- define "spire-server.upstream-spire-address" }} {{- if ne (len (dig "spire" "upstreamSpireAddress" "" .Values.global)) 0 }} {{- print .Values.global.spire.upstreamSpireAddress }} diff --git a/charts/spire/charts/spire-server/templates/configmap.yaml b/charts/spire/charts/spire-server/templates/configmap.yaml index 77966d765..43d34aa1d 100644 --- a/charts/spire/charts/spire-server/templates/configmap.yaml +++ b/charts/spire/charts/spire-server/templates/configmap.yaml @@ -213,18 +213,18 @@ plugins: {{- with .Values.nodeAttestor.tpmDirect }} {{- if eq (.enabled | toString) "true" }} tpm: - plugin_cmd: "/tpm/tpm_attestor_server" + plugin_cmd: "{{ include "spire-server.tpm-direct-plugin-destination" $ | trim }}" plugin_checksum: {{ .checksum }} plugin_data: {{- if ne (len .cas) 0 }} ca_path: /tpm-direct-cas {{- else }} - ca_path: /run/spire/data/tpm-direct/certs + ca_path: {{ printf "%s/certs" (include "spire-server.tpm-direct-state-dir" $ | trim) }} {{- end }} {{- if ne (len .hashes) 0 }} hash_path: /tmp-direct-hashes {{- else }} - hash_path: /run/spire/data/tpm-direct/hashes + hash_path: {{ printf "%s/hashes" (include "spire-server.tpm-direct-state-dir" $ | trim) }} {{- end }} {{- end }} {{- end }} diff --git a/charts/spire/charts/spire-server/templates/server-resource.yaml b/charts/spire/charts/spire-server/templates/server-resource.yaml index f790eff16..14282e3a9 100644 --- a/charts/spire/charts/spire-server/templates/server-resource.yaml +++ b/charts/spire/charts/spire-server/templates/server-resource.yaml @@ -157,21 +157,30 @@ spec: imagePullPolicy: {{ .Values.credentialComposer.cel.image.pullPolicy }} {{- end }} {{- if .Values.nodeAttestor.tpmDirect.enabled }} + {{- $tpmPluginDst := (include "spire-server.tpm-direct-plugin-destination" . | trim) }} + {{- $tpmMountPath := (include "spire-server.tpm-direct-mount-path" . | trim) }} + {{- $tpmStateDir := (include "spire-server.tpm-direct-state-dir" . | trim) }} + {{- $runAsUser := (dig "runAsUser" nil $podSecurityContext) }} + {{- $runAsGroup := (dig "runAsGroup" nil $podSecurityContext) | default $runAsUser }} + {{- $tpmInitChown := (and $runAsUser (dig "chownAfterCopy" true .Values.nodeAttestor.tpmDirect)) }} - name: init-tpm-direct securityContext: - {{- include "spire-lib.securitycontext" . | nindent 12 }} + {{- include "spire-server.tpm-direct-init-security-context" . | nindent 12 }} image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.nodeAttestor.tpmDirect.image "global" .Values.global) }} command: - sh - -ec - | # 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. - cp -a {{ .Values.nodeAttestor.tpmDirect.pluginPath }} /tpm/tpm_attestor_server - mkdir -p /run/spire/data/tpm-direct/certs - mkdir -p /run/spire/data/tpm-direct/hashes + cp {{ .Values.nodeAttestor.tpmDirect.pluginPath }} {{ $tpmPluginDst }} + mkdir -p {{ $tpmStateDir }}/certs + mkdir -p {{ $tpmStateDir }}/hashes + {{- if $tpmInitChown }} + chown -R {{ $runAsUser }}:{{ $runAsGroup }} {{ $tpmStateDir }} + {{- end }} volumeMounts: - name: tpm-direct - mountPath: /tpm + mountPath: {{ $tpmMountPath }} - name: spire-data mountPath: /run/spire/data imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.image.pullPolicy }} @@ -343,8 +352,9 @@ spec: readOnly: true {{- end }} {{- if .Values.nodeAttestor.tpmDirect.enabled }} + {{- $tpmMountPath := (include "spire-server.tpm-direct-mount-path" . | trim) }} - name: tpm-direct - mountPath: /tpm + mountPath: {{ $tpmMountPath }} readOnly: true {{- if ne (len .Values.nodeAttestor.tpmDirect.cas) 0 }} - name: tpm-direct-cas diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index 60456ab6f..abd9814cc 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -991,6 +991,16 @@ nodeAttestor: checksum: 46d0caad8c25a027dd11c93e18b58a8bc6fbd9f1fe2e36fa2a0dd440986de4dc ## @param nodeAttestor.tpmDirect.pluginPath The filename in the container of the plugin pluginPath: /app/tpm_attestor_server + ## @param nodeAttestor.tpmDirect.mountPath Mount path where the TPM plugin binary will be staged for the main container + mountPath: /tpm + ## @param nodeAttestor.tpmDirect.pluginDestinationPath Override the destination path of the plugin inside the mount path + pluginDestinationPath: "" + ## @param nodeAttestor.tpmDirect.stateDir Directory (within spire-data) used to hold TPM plugin state (certs, hashes) + stateDir: /run/spire/data/tpm-direct + ## @param nodeAttestor.tpmDirect.chownAfterCopy Chown TPM state directory to match pod security context after files are staged + chownAfterCopy: true + ## @param nodeAttestor.tpmDirect.initSecurityContext Security context overrides for the TPM init container + initSecurityContext: {} ## @param nodeAttestor.tpmDirect.cas A dictionary of TPM CA PEM or DER files that are allowed to connect. cas: {} ## @param nodeAttestor.tpmDirect.hashes A list of TPM hashes that are allowed to connect.