diff --git a/charts/retool/Chart.yaml b/charts/retool/Chart.yaml index dbedb80..7d8ed5e 100644 --- a/charts/retool/Chart.yaml +++ b/charts/retool/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: retool description: A Helm chart for Kubernetes type: application -version: 6.11.0 +version: 6.12.0 maintainers: - name: Retool Engineering email: engineering+helm@retool.com diff --git a/charts/retool/templates/configmap_code_executor.yaml b/charts/retool/templates/configmap_code_executor.yaml new file mode 100644 index 0000000..9252af0 --- /dev/null +++ b/charts/retool/templates/configmap_code_executor.yaml @@ -0,0 +1,13 @@ +{{- if include "retool.workflows.enabled" . }} +{{- if and (not .Values.codeExecutor.securityContext) (semverCompare ">=1.33-0" .Capabilities.KubeVersion.Version) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "retool.fullname" . }}-code-executor-seccomp + labels: + {{- include "retool.labels" . | nindent 4 }} +data: + nsjail-seccomp.json: | + {{- .Files.Get "files/nsjail-seccomp.json" | nindent 4 }} +{{- end }} +{{- end }} diff --git a/charts/retool/templates/deployment_code_executor.yaml b/charts/retool/templates/deployment_code_executor.yaml index 6750e61..4ae2fc8 100644 --- a/charts/retool/templates/deployment_code_executor.yaml +++ b/charts/retool/templates/deployment_code_executor.yaml @@ -1,4 +1,18 @@ {{- if include "retool.workflows.enabled" . }} +{{- /* + Workflows are run securely within Code Executor via nsjail sandboxes. Creating + those sandboxes requires the container to have elevated privileges. By default + these privileges are granted by running the container as privileged + (securityContext.privileged: true). On Kubernetes 1.33+ we can instead grant only + what nsjail needs, far more granularly than the privileged flag: a slightly + relaxed version of Docker's default seccomp profile, the NET_ADMIN capability for + network isolation, and an unmasked /proc for process resource monitoring. + $useSecComp selects this less-privileged path when the operator has not pinned a + securityContext and the cluster is >= 1.33; otherwise we fall back to privileged. + To use the more fine-grained privileges, please upgrade your k8s cluster to 1.33 + or higher. +*/ -}} +{{- $useSecComp := and (not .Values.codeExecutor.securityContext) (semverCompare ">=1.33-0" .Capabilities.KubeVersion.Version) -}} apiVersion: apps/v1 kind: Deployment metadata: @@ -23,6 +37,9 @@ spec: template: metadata: annotations: +{{- if $useSecComp }} + checksum/seccomp: {{ .Files.Get "files/nsjail-seccomp.json" | sha256sum }} +{{- end }} {{- if .Values.podAnnotations }} {{ toYaml .Values.podAnnotations | indent 8 }} {{- end }} @@ -44,11 +61,43 @@ spec: {{- if .Values.priorityClassName }} priorityClassName: "{{ .Values.priorityClassName }}" {{- end }} -{{- if .Values.initContainers }} +{{- if $useSecComp }} + hostUsers: false +{{- end }} +{{- if or $useSecComp .Values.initContainers }} initContainers: +{{- if $useSecComp }} + - name: install-seccomp + image: busybox:1.37.0@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + resources: + requests: + cpu: 1m + memory: 4Mi + limits: + cpu: 10m + memory: 16Mi + command: + - /bin/sh + - -c + - | + DEST="/host-seccomp/{{ .Values.codeExecutor.seccompLocalhostProfile }}" + mkdir -p "$(dirname "$DEST")" + cp /seccomp-profile/nsjail-seccomp.json "$DEST" + echo "seccomp profile installed at $DEST" + volumeMounts: + - name: seccomp-profile + mountPath: /seccomp-profile + - name: host-seccomp + mountPath: /host-seccomp +{{- end }} {{- range $key, $value := .Values.initContainers }} - - name: "{{ $key }}" -{{ toYaml $value | indent 8 }} + - name: "{{ $key }}" +{{ toYaml $value | indent 10 }} {{- end }} {{- end }} containers: @@ -56,11 +105,18 @@ spec: image: "{{ .Values.codeExecutor.image.repository }}:{{ include "retool.codeExecutor.image.tag" . }}" imagePullPolicy: {{ .Values.image.pullPolicy }} securityContext: - {{ if .Values.codeExecutor.securityContext }} + {{- if .Values.codeExecutor.securityContext }} {{ toYaml .Values.codeExecutor.securityContext | indent 10 }} - {{ else }} + {{- else if $useSecComp }} + capabilities: + add: ["NET_ADMIN"] + procMount: Unmasked + seccompProfile: + type: Localhost + localhostProfile: {{ .Values.codeExecutor.seccompLocalhostProfile }} + {{- else }} privileged: true - {{ end }} + {{- end }} {{- if .Values.securityContext.extraContainerSecurityContext }} {{ toYaml .Values.securityContext.extraContainerSecurityContext | indent 10 }} {{- end }} @@ -128,6 +184,15 @@ spec: {{ tpl . $ | indent 6 }} {{- end }} volumes: +{{- if $useSecComp }} + - name: seccomp-profile + configMap: + name: {{ template "retool.fullname" . }}-code-executor-seccomp + - name: host-seccomp + hostPath: + path: /var/lib/kubelet/seccomp + type: DirectoryOrCreate +{{- end }} {{- if .Values.codeExecutor.volumes }} {{ toYaml .Values.codeExecutor.volumes | indent 8 }} {{- end }} diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 33f80bb..951d9ec 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -798,11 +798,7 @@ codeExecutor: cpu: 1000m memory: 1024Mi - # code executor uses nsjail to sandbox code execution. nsjail requires privileged container access. - # If your deployment does not support privileged access, you can set `privileged` to false to not - # use nsjail. Without nsjail, all code is run without sandboxing within your deployment. - securityContext: - privileged: true + seccompLocalhostProfile: profiles/nsjail-seccomp.json # JS Executor jsExecutor: diff --git a/values.yaml b/values.yaml index 33f80bb..951d9ec 100644 --- a/values.yaml +++ b/values.yaml @@ -798,11 +798,7 @@ codeExecutor: cpu: 1000m memory: 1024Mi - # code executor uses nsjail to sandbox code execution. nsjail requires privileged container access. - # If your deployment does not support privileged access, you can set `privileged` to false to not - # use nsjail. Without nsjail, all code is run without sandboxing within your deployment. - securityContext: - privileged: true + seccompLocalhostProfile: profiles/nsjail-seccomp.json # JS Executor jsExecutor: