Protects SPIRE Agent's Chart Against YAML Template Injection (#450)
* protects agent's chart against template injection Signed-off-by: Nico Weisenauer <[email protected]> * removes unnecessary braces and whitespace Signed-off-by: Nico Weisenauer <[email protected]> * Removes int type validation via cast Signed-off-by: Nico Weisenauer <[email protected]> --------- Signed-off-by: Nico Weisenauer <[email protected]>
This commit is contained in:
@@ -75,20 +75,20 @@ Create chart name and version as used by the chart label.
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "spire-agent.labels" -}}
|
||||
helm.sh/chart: {{ include "spire-agent.chart" . }}
|
||||
helm.sh/chart: {{ include "spire-agent.chart" . | quote }}
|
||||
{{ include "spire-agent.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "spire-agent.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "spire-agent.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/name: {{ include "spire-agent.name" . | quote }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name | quote }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
|
||||
@@ -53,7 +53,7 @@ agent:
|
||||
default_svid_name: {{ .Values.sds.defaultSvidName | quote }}
|
||||
default_bundle_name: {{ .Values.sds.defaultBundleName | quote }}
|
||||
default_all_bundles_name: {{ .Values.sds.defaultAllBundlesName | quote }}
|
||||
disable_spiffe_cert_validation: {{ .Values.sds.disableSpiffeCertValidation }}
|
||||
disable_spiffe_cert_validation: {{ eq .Values.sds.disableSpiffeCertValidation true }}
|
||||
{{- end }}
|
||||
|
||||
{{- with .Values.experimental }}
|
||||
@@ -97,7 +97,7 @@ plugins:
|
||||
{{- if eq (.enabled | toString) "true" }}
|
||||
tpm:
|
||||
plugin_cmd: "/tpm/tpm_attestor_agent"
|
||||
plugin_checksum: {{ .plugin.checksum }}
|
||||
plugin_checksum: {{ .plugin.checksum | quote }}
|
||||
plugin_data: {}
|
||||
{{- $nodeAttestorUsed = add1 $nodeAttestorUsed }}
|
||||
{{- end }}
|
||||
@@ -126,9 +126,9 @@ plugins:
|
||||
kubelet_ca_path: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
{{- end }}
|
||||
skip_kubelet_verification: {{ eq .Values.workloadAttestors.k8s.verification.type "skip" }}
|
||||
disable_container_selectors: {{ .Values.workloadAttestors.k8s.disableContainerSelectors }}
|
||||
use_new_container_locator: {{ .Values.workloadAttestors.k8s.useNewContainerLocator }}
|
||||
verbose_container_locator_logs: {{ .Values.workloadAttestors.k8s.verboseContainerLocatorLogs }}
|
||||
disable_container_selectors: {{ eq .Values.workloadAttestors.k8s.disableContainerSelectors true}}
|
||||
use_new_container_locator: {{ eq .Values.workloadAttestors.k8s.useNewContainerLocator true }}
|
||||
verbose_container_locator_logs: {{ eq .Values.workloadAttestors.k8s.verboseContainerLocatorLogs true }}
|
||||
{{- if eq (include "spire-agent.connect-by-hostname" .) "true" }}
|
||||
node_name_env: "MY_NODE_NAME"
|
||||
{{- end }}
|
||||
@@ -168,8 +168,8 @@ telemetry:
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "spire-agent.fullname" . }}{{ $nameSuffix }}
|
||||
namespace: {{ include "spire-agent.namespace" . }}
|
||||
name: {{ printf "%s%s" (include "spire-agent.fullname" .) $nameSuffix | quote }}
|
||||
namespace: {{ include "spire-agent.namespace" . | quote }}
|
||||
{{- with .Values.configMap.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
|
||||
@@ -22,16 +22,16 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: {{ include "spire-agent.fullname" . }}{{ $nameSuffix }}
|
||||
namespace: {{ include "spire-agent.namespace" . }}
|
||||
name: {{ printf "%s%s" (include "spire-agent.fullname" .) $nameSuffix | quote }}
|
||||
namespace: {{ include "spire-agent.namespace" . | quote}}
|
||||
labels:
|
||||
{{- include "spire-agent.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: {{ $name }}
|
||||
app.kubernetes.io/component: {{ $name | quote }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "spire-agent.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: {{ $name }}
|
||||
app.kubernetes.io/component: {{ $name | quote }}
|
||||
{{- with .Values.updateStrategy }}
|
||||
updateStrategy:
|
||||
{{- if not (has .type (list "RollingUpdate" "OnDelete")) }}
|
||||
@@ -47,13 +47,13 @@ spec:
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/default-container: spire-agent
|
||||
checksum/config: {{ $configSum }}
|
||||
checksum/config: {{ $configSum | quote }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "spire-agent.selectorLabels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: {{ $name }}
|
||||
app.kubernetes.io/component: {{ $name | quote }}
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -65,7 +65,7 @@ spec:
|
||||
hostPID: true
|
||||
hostNetwork: true
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
serviceAccountName: {{ include "spire-agent.serviceAccountName" . }}
|
||||
serviceAccountName: {{ include "spire-agent.serviceAccountName" . | quote }}
|
||||
securityContext:
|
||||
{{- toYaml $podSecurityContext | nindent 8 }}
|
||||
{{- include "spire-lib.default_node_priority_class_name" . | nindent 6 }}
|
||||
@@ -79,17 +79,17 @@ spec:
|
||||
securityContext:
|
||||
{{- $mainSecurityContext | toYaml | nindent 12 }}
|
||||
image: {{ template "spire-lib.image" (dict "image" .Values.hostCert.image "global" .Values.global) }}
|
||||
imagePullPolicy: {{ .Values.hostCert.image.pullPolicy }}
|
||||
imagePullPolicy: {{ .Values.hostCert.image.pullPolicy | quote }}
|
||||
command: ["bash", "-xc"]
|
||||
args:
|
||||
- |
|
||||
{{- if ne .Values.workloadAttestors.k8s.verification.hostCert.fileName "" }}
|
||||
openssl x509 -in "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/{{ .Values.workloadAttestors.k8s.verification.hostCert.fileName }}" -out /hostCert/kubelet.crt
|
||||
openssl x509 -in {{ printf "%s/%s" .Values.workloadAttestors.k8s.verification.hostCert.basePath .Values.workloadAttestors.k8s.verification.hostCert.fileName | quote }} -out /hostCert/kubelet.crt
|
||||
{{- else }}
|
||||
if [ -f "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/kubelet-server-current.pem" ]; then
|
||||
openssl x509 -in "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/kubelet-server-current.pem" -out /hostCert/kubelet.crt
|
||||
openssl x509 -in {{ printf "%s/kubelet-server-current.pem" .Values.workloadAttestors.k8s.verification.hostCert.basePath | quote }} -out /hostCert/kubelet.crt
|
||||
elif [ -f "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/kubelet.crt" ]; then
|
||||
openssl x509 -in "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/kubelet.crt" -out /hostCert/kubelet.crt
|
||||
openssl x509 -in {{ printf "%s/kubelet.crt" .Values.workloadAttestors.k8s.verification.hostCert.basePath | quote }} -out /hostCert/kubelet.crt
|
||||
else
|
||||
{{- if eq .Values.workloadAttestors.k8s.verification.type "auto" }}
|
||||
{{- if $cbh }}
|
||||
@@ -150,7 +150,7 @@ spec:
|
||||
readOnly: true
|
||||
- name: kmsg
|
||||
mountPath: /dev/kmsg
|
||||
imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.pubHash.image.pullPolicy }}
|
||||
imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.pubHash.image.pullPolicy | quote }}
|
||||
{{- end }}
|
||||
- name: init-tpm-direct
|
||||
securityContext:
|
||||
@@ -161,16 +161,16 @@ spec:
|
||||
- -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.plugin.path }} /tpm/tpm_attestor_agent
|
||||
cp -a {{ .Values.nodeAttestor.tpmDirect.plugin.path | quote }} /tpm/tpm_attestor_agent
|
||||
volumeMounts:
|
||||
- name: tpm-direct
|
||||
mountPath: /tpm
|
||||
imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.plugin.image.pullPolicy }}
|
||||
imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.plugin.image.pullPolicy | quote }}
|
||||
{{- end }}
|
||||
{{- if gt (len $socketAlternateNames) 0 }}
|
||||
- name: ensure-alternate-names
|
||||
image: {{ template "spire-lib.image" (dict "image" .Values.socketAlternate.image "global" .Values.global) }}
|
||||
imagePullPolicy: {{ .Values.socketAlternate.image.pullPolicy }}
|
||||
imagePullPolicy: {{ .Values.socketAlternate.image.pullPolicy | quote }}
|
||||
command: ["bash", "-xc"]
|
||||
{{- /* 1. Look for symlinks pointing at the wrong place and remove them. 2. Make symlinks that don't exist. 3. If new socket is pointing at an existing symlink, remove old symlink. */}}
|
||||
args:
|
||||
@@ -178,7 +178,7 @@ spec:
|
||||
cd {{ $socketPath | dir }}
|
||||
{{- range $socketAlternateNames }}
|
||||
L=`readlink {{ . }}`
|
||||
[ "x$L" != "x{{ $socketPath | base}}" ] && rm -f {{ . }}
|
||||
[ "x$L" != "x{{ $socketPath | base }}" ] && rm -f {{ . }}
|
||||
[ ! -L {{ . }} ] && ln -s {{ $socketPath | base }} {{ . }}
|
||||
{{- end }}
|
||||
[ -L {{ $socketPath | base }} ] && rm -f {{ $socketPath | base }}
|
||||
@@ -195,12 +195,12 @@ spec:
|
||||
{{- if gt (int (dig "fsGroup" 0 $podSecurityContext)) 0 }}
|
||||
- name: fsgroupfix
|
||||
image: {{ template "spire-lib.image" (dict "image" .Values.fsGroupFix.image "global" .Values.global) }}
|
||||
imagePullPolicy: {{ .Values.fsGroupFix.image.pullPolicy }}
|
||||
imagePullPolicy: {{ .Values.fsGroupFix.image.pullPolicy | quote }}
|
||||
command: ["bash", "-c"]
|
||||
args:
|
||||
- |
|
||||
chown -R {{ $podSecurityContext.runAsUser }}:{{ $podSecurityContext.fsGroup }} {{ $socketPath | dir }} /tmp/spire-agent/private
|
||||
chown -R {{ $podSecurityContext.runAsUser }}:{{ $podSecurityContext.fsGroup }} /var/lib/spire
|
||||
chown -R {{ printf "%v:%v" $podSecurityContext.runAsUser $podSecurityContext.fsGroup | quote }} {{ $socketPath | dir }} /tmp/spire-agent/private
|
||||
chown -R {{ printf "%v:%v" $podSecurityContext.runAsUser $podSecurityContext.fsGroup | quote }} /var/lib/spire
|
||||
resources:
|
||||
{{- toYaml .Values.fsGroupFix.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
@@ -218,9 +218,9 @@ spec:
|
||||
{{- toYaml .Values.initContainers | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
- name: {{ .Chart.Name | quote }}
|
||||
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.image "global" .Values.global) }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
|
||||
args: ["-config", "/opt/spire/conf/agent/agent.conf"]
|
||||
securityContext:
|
||||
{{- $mainSecurityContext | toYaml | nindent 12 }}
|
||||
@@ -314,7 +314,11 @@ spec:
|
||||
{{- if .Values.sockets.admin.mountOnHost }}
|
||||
- name: spire-agent-admin-socket-dir
|
||||
hostPath:
|
||||
path: {{ .Values.sockets.hostBasePath }}/{{ if .Values.upstream }}upstream.csi.spiffe.io{{ else }}csi.spiffe.io{{ end }}/admin
|
||||
{{- if .Values.upstream }}
|
||||
path: {{ printf "%s/upstream.csi.spiffe.io/admin" .Values.sockets.hostBasePath | quote }}
|
||||
{{- else }}
|
||||
path: {{ printf "%s/csi.spiffe.io/admin" .Values.sockets.hostBasePath | quote }}
|
||||
{{- end }}
|
||||
type: DirectoryOrCreate
|
||||
{{- else }}
|
||||
- name: spire-agent-admin-socket-dir
|
||||
@@ -323,7 +327,11 @@ spec:
|
||||
{{- if eq .Values.persistence.type "hostPath" }}
|
||||
- name: spire-agent-persistence
|
||||
hostPath:
|
||||
path: {{ .Values.persistence.hostPath }}/{{ if .Values.upstream }}upstream.csi.spiffe.io{{ else }}csi.spiffe.io{{ end }}
|
||||
{{- if .Values.upstream }}
|
||||
path: {{ printf "%s/upstream.csi.spiffe.io" .Values.persistence.hostPath | quote }}
|
||||
{{- else }}
|
||||
path: {{ printf "%s/csi.spiffe.io" .Values.persistence.hostPath | quote }}
|
||||
{{- end }}
|
||||
type: DirectoryOrCreate
|
||||
{{- else }}
|
||||
- name: spire-agent-persistence
|
||||
@@ -332,7 +340,7 @@ spec:
|
||||
{{- if eq (len .Values.trustBundleURL) 0 }}
|
||||
- name: spire-bundle
|
||||
configMap:
|
||||
name: {{ include "spire-lib.bundle-configmap" . }}{{ $nameSuffix }}
|
||||
name: {{ printf "%s%s" (include "spire-lib.bundle-configmap" .) $nameSuffix | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
|
||||
- name: tpm-direct
|
||||
@@ -364,7 +372,7 @@ spec:
|
||||
emptyDir: {}
|
||||
- name: host-cert
|
||||
hostPath:
|
||||
path: {{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}
|
||||
path: {{ .Values.workloadAttestors.k8s.verification.hostCert.basePath | quote }}
|
||||
{{- end }}
|
||||
{{- if gt (len .Values.extraVolumes) 0 }}
|
||||
{{- toYaml .Values.extraVolumes | nindent 8 }}
|
||||
|
||||
@@ -5,7 +5,7 @@ apiVersion: monitoring.coreos.com/v1
|
||||
kind: PodMonitor
|
||||
metadata:
|
||||
name: {{ include "spire-agent.fullname" . }}
|
||||
namespace: {{ $namespace }}
|
||||
namespace: {{ $namespace | quote }}
|
||||
labels:
|
||||
{{- include "spire-agent.labels" . | nindent 4 }}
|
||||
{{- if ne (len (dig "telemetry" "prometheus" "podMonitor" "labels" (dict) .Values.global)) 0 }}
|
||||
@@ -22,6 +22,6 @@ spec:
|
||||
- port: prom
|
||||
{{- if ne $namespace $podNamespace }}
|
||||
namespaceSelector:
|
||||
kubernetes.io/metadata.name: {{ $podNamespace }}
|
||||
kubernetes.io/metadata.name: {{ $podNamespace | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: {{ include "spire-agent.fullname" . }}
|
||||
name: {{ include "spire-agent.fullname" . | quote }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources:
|
||||
@@ -15,12 +15,12 @@ rules:
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: {{ include "spire-agent.fullname" . }}
|
||||
name: {{ include "spire-agent.fullname" . | quote }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "spire-agent.serviceAccountName" . }}
|
||||
namespace: {{ include "spire-agent.namespace" . }}
|
||||
name: {{ include "spire-agent.serviceAccountName" . | quote }}
|
||||
namespace: {{ include "spire-agent.namespace" . | quote }}
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: {{ include "spire-agent.fullname" . }}
|
||||
name: {{ include "spire-agent.fullname" . | quote }}
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
apiVersion: security.openshift.io/v1
|
||||
kind: SecurityContextConstraints
|
||||
metadata:
|
||||
name: {{ include "spire-agent.fullname" . }}
|
||||
name: {{ include "spire-agent.fullname" . | quote }}
|
||||
readOnlyRootFilesystem: true
|
||||
runAsUser:
|
||||
type: RunAsAny
|
||||
@@ -11,7 +11,7 @@ seLinuxContext:
|
||||
supplementalGroups:
|
||||
type: RunAsAny
|
||||
users:
|
||||
- system:serviceaccount:{{ include "spire-agent.namespace" . }}:{{ include "spire-agent.serviceAccountName" . }}
|
||||
- {{ printf "system:serviceaccount:%s:%s" (include "spire-agent.namespace" .) (include "spire-agent.serviceAccountName" .) | quote }}
|
||||
volumes:
|
||||
- configMap
|
||||
- hostPath
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "spire-agent.serviceAccountName" . }}
|
||||
namespace: {{ include "spire-agent.namespace" . }}
|
||||
name: {{ include "spire-agent.serviceAccountName" . | quote }}
|
||||
namespace: {{ include "spire-agent.namespace" . | quote }}
|
||||
labels:
|
||||
{{- include "spire-agent.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
|
||||
@@ -53,17 +53,17 @@
|
||||
{{- $repo := .image.repository }}
|
||||
{{- $tag := .image.tag | toString }}
|
||||
{{- if eq (substr 0 7 $tag) "sha256:" }}
|
||||
{{- printf "%s/%s@%s" $registry $repo $tag }}
|
||||
{{- printf "%s/%s@%s" $registry $repo $tag | quote }}
|
||||
{{- else if .appVersion }}
|
||||
{{- $appVersion := .appVersion }}
|
||||
{{- if and (hasKey . "ubi") (dig "openshift" false .global) }}
|
||||
{{- $appVersion = printf "ubi-%s" $appVersion }}
|
||||
{{- end }}
|
||||
{{- printf "%s%s:%s" $registry $repo (default $appVersion $tag) }}
|
||||
{{- printf "%s%s:%s" $registry $repo (default $appVersion $tag) | quote }}
|
||||
{{- else if $tag }}
|
||||
{{- printf "%s%s:%s" $registry $repo $tag }}
|
||||
{{- printf "%s%s:%s" $registry $repo $tag | quote }}
|
||||
{{- else }}
|
||||
{{- printf "%s%s" $registry $repo }}
|
||||
{{- printf "%s%s" $registry $repo | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -309,7 +309,7 @@ securityContext - the subbranch of values that contains the securityContext to m
|
||||
|
||||
{{- define "spire-lib.default_node_priority_class_name" }}
|
||||
{{- if .Values.priorityClassName }}
|
||||
priorityClassName: {{ .Values.priorityClassName }}
|
||||
priorityClassName: {{ .Values.priorityClassName | quote }}
|
||||
{{- else if and (dig "spire" "recommendations" "enabled" false .Values.global) (dig "spire" "recommendations" "priorityClassName" true .Values.global) }}
|
||||
priorityClassName: system-node-critical
|
||||
{{- end }}
|
||||
@@ -317,7 +317,7 @@ priorityClassName: system-node-critical
|
||||
|
||||
{{- define "spire-lib.default_cluster_priority_class_name" }}
|
||||
{{- if .Values.priorityClassName }}
|
||||
priorityClassName: {{ .Values.priorityClassName }}
|
||||
priorityClassName: {{ .Values.priorityClassName | quote }}
|
||||
{{- else if and (dig "spire" "recommendations" "enabled" false .Values.global) (dig "spire" "recommendations" "priorityClassName" true .Values.global) }}
|
||||
priorityClassName: system-cluster-critical
|
||||
{{- end }}
|
||||
|
||||
Reference in New Issue
Block a user