From 2f18bebc447dd0f5828c6941375fa4f178eea894 Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 10:11:03 -0500 Subject: [PATCH 01/16] feat: Add SCC and PSS management --- helm-charts/falcon-image-analyzer/Chart.yaml | 2 +- helm-charts/falcon-image-analyzer/README.md | 68 +++++++++- .../templates/_helpers.tpl | 11 ++ .../templates/cluster-role-read-access.yaml | 10 ++ .../templates/daemonset.yaml | 3 + .../templates/deployment.yaml | 3 + .../templates/namespace_labels.yaml | 77 +++++++++++ .../falcon-image-analyzer/templates/scc.yaml | 50 +++++++ .../tests/test-cluster-permissions.yaml | 17 +++ .../tests/test-image-analyzer-running.yaml | 32 ++++- .../templates/tests/test-openshift.yaml | 83 ++++++++++++ .../falcon-image-analyzer/values.schema.json | 35 +++++ helm-charts/falcon-image-analyzer/values.yaml | 27 ++++ helm-charts/falcon-kac/Chart.yaml | 2 +- helm-charts/falcon-kac/README.md | 52 +++++--- helm-charts/falcon-kac/templates/_helpers.tpl | 11 ++ .../falcon-kac/templates/clusterrole.yaml | 12 +- .../templates/deployment_webhook.yaml | 3 + helm-charts/falcon-kac/templates/scc.yaml | 50 +++++++ .../tests/test-cluster-permissions.yaml | 17 +++ .../templates/tests/test-kac-running.yaml | 11 +- .../templates/tests/test-openshift.yaml | 82 ++++++++++++ helm-charts/falcon-kac/values.schema.json | 26 ++++ helm-charts/falcon-kac/values.yaml | 18 +++ helm-charts/falcon-platform/Chart.lock | 10 +- helm-charts/falcon-platform/Chart.yaml | 8 +- helm-charts/falcon-sensor/Chart.yaml | 2 +- helm-charts/falcon-sensor/README.md | 122 +++++++++++++++++ .../falcon-sensor/templates/_helpers.tpl | 20 +++ .../falcon-sensor/templates/clusterrole.yaml | 10 ++ .../falcon-sensor/templates/daemonset.yaml | 4 + .../templates/namespace_labels.yaml | 77 +++++++++++ .../falcon-sensor/templates/node_cleanup.yaml | 3 + helm-charts/falcon-sensor/templates/scc.yaml | 51 +++++++ .../falcon-sensor/templates/scc_cleanup.yaml | 124 ++++++++++++++++++ .../tests/test-cluster-permissions.yaml | 17 +++ .../tests/test-ds-sensor-running.yaml | 21 ++- .../templates/tests/test-openshift.yaml | 79 +++++++++++ .../tests/test-sidecar-sensor-running.yaml | 7 +- helm-charts/falcon-sensor/values.schema.json | 26 ++++ helm-charts/falcon-sensor/values.yaml | 22 ++++ 41 files changed, 1263 insertions(+), 42 deletions(-) create mode 100644 helm-charts/falcon-image-analyzer/templates/namespace_labels.yaml create mode 100644 helm-charts/falcon-image-analyzer/templates/scc.yaml create mode 100644 helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml create mode 100644 helm-charts/falcon-kac/templates/scc.yaml create mode 100644 helm-charts/falcon-kac/templates/tests/test-openshift.yaml create mode 100644 helm-charts/falcon-sensor/templates/namespace_labels.yaml create mode 100644 helm-charts/falcon-sensor/templates/scc.yaml create mode 100644 helm-charts/falcon-sensor/templates/scc_cleanup.yaml create mode 100644 helm-charts/falcon-sensor/templates/tests/test-openshift.yaml diff --git a/helm-charts/falcon-image-analyzer/Chart.yaml b/helm-charts/falcon-image-analyzer/Chart.yaml index a4f77006..982afd62 100644 --- a/helm-charts/falcon-image-analyzer/Chart.yaml +++ b/helm-charts/falcon-image-analyzer/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.1.20 +version: 1.1.21-openshift.rc.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm-charts/falcon-image-analyzer/README.md b/helm-charts/falcon-image-analyzer/README.md index abe06653..c31a54b8 100644 --- a/helm-charts/falcon-image-analyzer/README.md +++ b/helm-charts/falcon-image-analyzer/README.md @@ -19,6 +19,7 @@ more. - [Installing using Helm Chart](#install-using-helm-chart) - [Deployment considerations](#deployment-considerations) - [Pod Security Standards](#pod-security-standards) + - [OpenShift Compatibility](#openshift-compatibility) - [Temp Mounts](#temp-volume-mount) - [IAM Roles](#aws-iam-roles-for-service-accounts) - [Authentication for Private Registries](#authentication-for-private-registries) @@ -40,7 +41,6 @@ The Falcon Image Analyzer Helm chart has been tested to deploy on the following * Azure Kubernetes Service (AKS) * Google Kubernetes Engine (GKE) * SUSE Rancher K3s -* Red Hat OpenShift Kubernetes ## Helm Chart Support for Falcon Image Analyzer Versions @@ -113,6 +113,10 @@ The following tables list the Falcon sensor configurable parameters and their de | `log.output` optional ( available Helm Chart v >= 1.1.7 & falcon-imageanalyzer >= 1.0.12) | Set the value to for log output terminal. `2=stderr` and `1=stdout` | 2 ( stderr ) | | `hostNetwork` optional ( available Helm Chart v >= 1.1.11) | Set the value to `true` to use the hostNetwork instead of pod network | `false` | | `dnsPolicy` optional ( available Helm Chart v >= 1.1.11) | Set the value to any supported value from https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | `` no value implies `Default` | +| `openshift.enabled` optional | Enable OpenShift compatibility mode. Creates a SecurityContextConstraints resource sized to the active workload mode (DaemonSet or Deployment). | `false` | +| `openshift.createSCC` optional | Create the SCC resource. Set to `false` to manage the SCC outside of Helm. | `true` | +| `openshift.sccName` optional | Name of the SCC to create or use. If empty, defaults to the release fullname. | `""` | +| `pss.manageNamespace` optional | Allow Helm to manage the install namespace PSS labels (`privileged`). Independent of OpenShift — can be enabled on any cluster running Kubernetes 1.25+. | `false` | | ~~`scanStats.enabled`~~ optional (**Deprecated in 1.1.17+** . available Helm Chart v >= 1.1.8 & falcon-imageanalyzer >= 1.0.13) | Set `enabled` to true for agent to send scan error and stats to cloud | `true` | | `crowdstrikeConfig.clusterName` optional | Cluster name | None | | `crowdstrikeConfig.enableDebug` optional | Set to `true` for debug level log verbosity. | false | @@ -298,17 +302,67 @@ For a successful deployment, you will want to ensure that: ### Pod Security Standards -Starting with Kubernetes 1.25, Pod Security Standards will be enforced. Setting the appropriate Pod Security Standards policy needs to be performed by adding a label to the namespace. Run the following command, and replace `my-existing-namespace` with the namespace that you have installed the falcon sensors, for example: `falcon-image-analyzer`. +Starting with Kubernetes 1.25, Pod Security Standards (PSS) are enforced via the Pod Security Admission (PSA) controller. Falcon Image Analyzer requires `privileged` PSS labels on its namespace because it accesses the container runtime socket (DaemonSet mode) or runs as root (Deployment mode). + +Set `pss.manageNamespace: true` to have Helm apply the required labels automatically as part of install and upgrade: + ``` -kubectl label --overwrite ns my-existing-namespace \ - pod-security.kubernetes.io/enforce=privileged +helm upgrade --install imageanalyzer crowdstrike/falcon-image-analyzer \ + --create-namespace -n falcon-image-analyzer \ + --set pss.manageNamespace=true ``` -If you want to silence the warning and change the auditing level for the Pod Security Standard, add the following labels: +To apply the labels manually instead: +``` +kubectl label --overwrite ns falcon-image-analyzer \ + pod-security.kubernetes.io/enforce=privileged \ + pod-security.kubernetes.io/warn=privileged \ + pod-security.kubernetes.io/audit=privileged ``` -kubectl label ns --overwrite my-existing-namespace pod-security.kubernetes.io/audit=privileged -kubectl label ns --overwrite my-existing-namespace pod-security.kubernetes.io/warn=privileged + +### OpenShift Compatibility + +> **Note:** OpenShift is **not a recommended** configuration for this Helm chart. The +> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) +> is the recommended installation method for OpenShift clusters. + +#### Security Context Constraints + +The required privileges differ depending on which workload mode is enabled: + +- **DaemonSet mode** (`daemonset.enabled: true`): Requires a privileged SCC to access the container runtime socket + (`/run/containerd/containerd.sock`, `/run/crio/crio.sock`, etc.) and, for CRI-O, additional hostPath mounts. +- **Deployment mode** (`deployment.enabled: true`): Requires only permission to run as root (UID 0) with all + capabilities dropped. No host access is needed. + +Set `openshift.enabled: true` to have the chart create the appropriate SCC automatically. The SCC grants only the +minimum permissions required for the active workload mode. The SCC is managed as a standard Helm release resource and +will be created on install and removed on uninstall. + +**DaemonSet mode on OpenShift:** ``` +helm upgrade --install -f /path/to/config_values.yaml \ + --create-namespace -n falcon-image-analyzer imageanalyzer crowdstrike/falcon-image-analyzer \ + --set openshift.enabled=true +``` + +**Deployment mode on OpenShift:** +``` +helm upgrade --install -f /path/to/config_values.yaml \ + --create-namespace -n falcon-image-analyzer imageanalyzer crowdstrike/falcon-image-analyzer \ + --set openshift.enabled=true +``` + +To manage the SCC outside of Helm, set `openshift.createSCC: false` and apply a SCC that grants the permissions +described above to the IAR service account. + +#### OpenShift Values + +| Parameter | Description | Default | +|:----------------------|:---------------------------------------------------------------------------------------------------------------------------|:----------------------| +| `openshift.enabled` | Enable OpenShift compatibility mode | `false` | +| `openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the workload the required privileges for the active workload mode | `true` | +| `openshift.sccName` | Name of the SCC to create or use. If empty, defaults to the release fullname | `""` (auto-generated) | ### Temp Volume Mount In order to perform image scan, IAR will pull the image and un-compress it for traversal through layers and image config and manifest. diff --git a/helm-charts/falcon-image-analyzer/templates/_helpers.tpl b/helm-charts/falcon-image-analyzer/templates/_helpers.tpl index 218a220d..5f20297f 100644 --- a/helm-charts/falcon-image-analyzer/templates/_helpers.tpl +++ b/helm-charts/falcon-image-analyzer/templates/_helpers.tpl @@ -265,3 +265,14 @@ Get container registry config json from global value if it exists {{- .Values.image.registryConfigJSON | default "" -}} {{- end -}} {{- end -}} + +{{/* +OpenShift SCC name. Uses openshift.sccName if set, otherwise defaults to the fullname. +*/}} +{{- define "falcon-image-analyzer.sccName" -}} +{{- if .Values.openshift.sccName -}} +{{- .Values.openshift.sccName -}} +{{- else -}} +{{- include "falcon-image-analyzer.fullname" . -}} +{{- end -}} +{{- end -}} diff --git a/helm-charts/falcon-image-analyzer/templates/cluster-role-read-access.yaml b/helm-charts/falcon-image-analyzer/templates/cluster-role-read-access.yaml index 0cd2237a..c380cbca 100644 --- a/helm-charts/falcon-image-analyzer/templates/cluster-role-read-access.yaml +++ b/helm-charts/falcon-image-analyzer/templates/cluster-role-read-access.yaml @@ -17,3 +17,13 @@ rules: - get - watch - list +{{- if and .Values.openshift.enabled (not .Values.openshift.createSCC) .Values.openshift.sccName }} + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - {{ include "falcon-image-analyzer.sccName" . }} + verbs: + - use +{{- end }} diff --git a/helm-charts/falcon-image-analyzer/templates/daemonset.yaml b/helm-charts/falcon-image-analyzer/templates/daemonset.yaml index 67ed8157..043c427f 100644 --- a/helm-charts/falcon-image-analyzer/templates/daemonset.yaml +++ b/helm-charts/falcon-image-analyzer/templates/daemonset.yaml @@ -49,6 +49,9 @@ spec: metadata: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled + {{- if and .Values.openshift.enabled .Values.openshift.createSCC }} + openshift.io/scc: {{ include "falcon-image-analyzer.sccName" . }} + {{- end }} {{- with .Values.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} diff --git a/helm-charts/falcon-image-analyzer/templates/deployment.yaml b/helm-charts/falcon-image-analyzer/templates/deployment.yaml index d9ae9fa3..d0b86e08 100644 --- a/helm-charts/falcon-image-analyzer/templates/deployment.yaml +++ b/helm-charts/falcon-image-analyzer/templates/deployment.yaml @@ -50,6 +50,9 @@ spec: metadata: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled + {{- if and .Values.openshift.enabled .Values.openshift.createSCC }} + openshift.io/scc: {{ include "falcon-image-analyzer.sccName" . }} + {{- end }} {{- with .Values.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} diff --git a/helm-charts/falcon-image-analyzer/templates/namespace_labels.yaml b/helm-charts/falcon-image-analyzer/templates/namespace_labels.yaml new file mode 100644 index 00000000..7598d04d --- /dev/null +++ b/helm-charts/falcon-image-analyzer/templates/namespace_labels.yaml @@ -0,0 +1,77 @@ +{{- if .Values.pss.manageNamespace }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "falcon-image-analyzer.fullname" . }}-ns-labeler + namespace: {{ include "falcon-image-analyzer.namespace" . }} + labels: + {{- include "falcon-image-analyzer.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-10" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "falcon-image-analyzer.fullname" . }}-ns-labeler + labels: + {{- include "falcon-image-analyzer.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-10" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +rules: + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "falcon-image-analyzer.fullname" . }}-ns-labeler + labels: + {{- include "falcon-image-analyzer.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-10" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +subjects: + - kind: ServiceAccount + name: {{ include "falcon-image-analyzer.fullname" . }}-ns-labeler + namespace: {{ include "falcon-image-analyzer.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ include "falcon-image-analyzer.fullname" . }}-ns-labeler + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "falcon-image-analyzer.fullname" . }}-ns-labeler + namespace: {{ include "falcon-image-analyzer.namespace" . }} + labels: + {{- include "falcon-image-analyzer.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + template: + spec: + serviceAccountName: {{ include "falcon-image-analyzer.fullname" . }}-ns-labeler + restartPolicy: OnFailure + containers: + - name: kubectl + image: docker.io/bitnami/kubectl + command: + - kubectl + - label + - namespace + - {{ include "falcon-image-analyzer.namespace" . }} + - "pod-security.kubernetes.io/enforce=privileged" + - "pod-security.kubernetes.io/warn=privileged" + - "pod-security.kubernetes.io/audit=privileged" + - "--overwrite" +{{- end }} diff --git a/helm-charts/falcon-image-analyzer/templates/scc.yaml b/helm-charts/falcon-image-analyzer/templates/scc.yaml new file mode 100644 index 00000000..9587b68c --- /dev/null +++ b/helm-charts/falcon-image-analyzer/templates/scc.yaml @@ -0,0 +1,50 @@ +{{- if and .Values.openshift.enabled .Values.openshift.createSCC }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ include "falcon-image-analyzer.sccName" . }} + labels: + {{- include "falcon-image-analyzer.labels" . | nindent 4 }} + annotations: + kubernetes.io/description: >- + {{- if .Values.daemonset.enabled }} + Grants the Falcon Image Analyzer DaemonSet the privileges required to + access the container runtime socket on each node for image scanning. + {{- else }} + Grants the Falcon Image Analyzer Deployment permission to run as root + (UID 0) for image analysis. No host access is granted. + {{- end }} +allowHostDirVolumePlugin: {{ or .Values.daemonset.enabled .Values.azure.enabled }} +allowHostIPC: false +allowHostNetwork: {{ .Values.hostNetwork | default false }} +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: {{ .Values.daemonset.enabled }} +allowPrivilegedContainer: {{ .Values.daemonset.enabled }} +allowedCapabilities: [] +defaultAddCapabilities: [] +fsGroup: + type: RunAsAny +readOnlyRootFilesystem: false +requiredDropCapabilities: [] +runAsUser: + type: RunAsAny +seLinuxContext: + type: RunAsAny +seccompProfiles: + - runtime/default +supplementalGroups: + type: RunAsAny +users: + - system:serviceaccount:{{ include "falcon-image-analyzer.namespace" . }}:{{ .Values.serviceAccount.name | default (include "falcon-image-analyzer.fullname" .) }} +groups: [] +volumes: + - configMap + - downwardAPI + - emptyDir + - projected + - secret + {{- if or .Values.daemonset.enabled .Values.azure.enabled }} + - hostPath + {{- end }} +{{- end }} diff --git a/helm-charts/falcon-image-analyzer/templates/tests/test-cluster-permissions.yaml b/helm-charts/falcon-image-analyzer/templates/tests/test-cluster-permissions.yaml index 3e5a562a..8f5416fd 100644 --- a/helm-charts/falcon-image-analyzer/templates/tests/test-cluster-permissions.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/test-cluster-permissions.yaml @@ -34,6 +34,7 @@ rules: verbs: - get - list + - watch - apiGroups: - rbac.authorization.k8s.io resources: @@ -42,6 +43,22 @@ rules: verbs: - get - list +{{- if .Values.openshift.enabled }} +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + verbs: + - get +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - {{ include "falcon-image-analyzer.sccName" . }} + verbs: + - use +{{- end }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml b/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml index f06707a7..362cc022 100644 --- a/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml @@ -16,6 +16,7 @@ spec: containers: - name: kubectl image: docker.io/bitnami/kubectl + imagePullPolicy: IfNotPresent command: - /bin/sh - -c @@ -23,7 +24,18 @@ spec: FAILED=0 echo "--- Waiting for pods to initialize ---" - sleep 10 + {{- if .Values.daemonset.enabled }} + kubectl rollout status daemonset \ + "{{ include "falcon-image-analyzer.fullname" . }}" \ + -n "{{ include "falcon-image-analyzer.namespace" . }}" \ + --timeout=300s + {{- else }} + kubectl wait deployment \ + "{{ include "falcon-image-analyzer.fullname" . }}" \ + -n "{{ include "falcon-image-analyzer.namespace" . }}" \ + --for=condition=Available \ + --timeout=300s + {{- end }} echo "--- Checking all Image Analyzer pods are running ---" KUBECMD=$(kubectl get pods -n "{{ include "falcon-image-analyzer.namespace" . }}" \ @@ -141,7 +153,7 @@ spec: echo "--- Checking pod annotations ---" PODS=$(kubectl get pods -n "{{ include "falcon-image-analyzer.namespace" . }}" \ -l "app.kubernetes.io/name={{ include "falcon-image-analyzer.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" \ - -o json 2>&1 | jq -r '.items[] | select(.metadata.annotations["helm.sh/hook"] == null) | .metadata.name') + -o json 2>/dev/null | jq -r '.items[] | select(.metadata.annotations["helm.sh/hook"] == null) | .metadata.name') if [ -z "${PODS}" ]; then echo "[FAIL]: No Image Analyzer pods found" FAILED=1 @@ -159,6 +171,22 @@ spec: done fi + {{- if .Values.pss.manageNamespace }} + echo "--- Checking PSS namespace labels ---" + NS_NAME="{{ include "falcon-image-analyzer.namespace" . }}" + for LABEL in "pod-security.kubernetes.io/enforce=privileged" "pod-security.kubernetes.io/warn=privileged" "pod-security.kubernetes.io/audit=privileged"; do + KEY="${LABEL%%=*}" + VALUE="${LABEL##*=}" + ACTUAL=$(kubectl get namespace "${NS_NAME}" -o json 2>&1 | jq -r --arg key "${KEY}" '.metadata.labels[$key] // ""') + if [ "${ACTUAL}" != "${VALUE}" ]; then + echo "[FAIL]: Namespace '${NS_NAME}' label '${KEY}' is '${ACTUAL}', expected '${VALUE}'" + FAILED=1 + else + echo "[OK]: Namespace '${NS_NAME}' has label '${KEY}=${VALUE}'" + fi + done + {{- end }} + echo "--- Checking service ---" SVC_NAME="{{ include "falcon-image-analyzer.iarAgentService" . }}" if ! kubectl get service "${SVC_NAME}" -n "{{ include "falcon-image-analyzer.namespace" . }}" > /dev/null 2>&1; then diff --git a/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml b/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml new file mode 100644 index 00000000..7b1ed088 --- /dev/null +++ b/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml @@ -0,0 +1,83 @@ +{{- if and .Values.testing.enabled .Values.openshift.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "falcon-image-analyzer.fullname" . }}-test-openshift" + namespace: {{ include "falcon-image-analyzer.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "falcon-image-analyzer.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: test + helm.sh/chart: {{ include "falcon-image-analyzer.chart" . }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: kubectl + image: docker.io/bitnami/kubectl + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - | + FAILED=0 + + {{- if .Values.openshift.createSCC }} + echo "--- Checking SCC exists ---" + if ! kubectl get scc "{{ include "falcon-image-analyzer.sccName" . }}" > /dev/null 2>&1; then + echo "[FAIL]: SCC '{{ include "falcon-image-analyzer.sccName" . }}' not found" + FAILED=1 + else + echo "[OK]: SCC '{{ include "falcon-image-analyzer.sccName" . }}' exists" + fi + + echo "--- Checking service account is bound to SCC ---" + SA_ENTRY="system:serviceaccount:{{ include "falcon-image-analyzer.namespace" . }}:{{ .Values.serviceAccount.name | default (include "falcon-image-analyzer.fullname" .) }}" + SCC_USERS=$(kubectl get scc "{{ include "falcon-image-analyzer.sccName" . }}" -o jsonpath="{.users}" 2>&1) + if ! echo "${SCC_USERS}" | grep -q "${SA_ENTRY}"; then + echo "[FAIL]: Service account '${SA_ENTRY}' is not bound to SCC" + echo "${SCC_USERS}" + FAILED=1 + else + echo "[OK]: Service account is bound to SCC" + fi + {{- end }} + + echo "--- Checking {{ if .Values.daemonset.enabled }}DaemonSet{{ else }}Deployment{{ end }} pods have openshift.io/scc annotation ---" + sleep 10 + PODS=$(kubectl get pods -n "{{ include "falcon-image-analyzer.namespace" . }}" \ + -l "app.kubernetes.io/name={{ include "falcon-image-analyzer.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" \ + -o jsonpath="{.items[*].metadata.name}" 2>&1) + if [ -z "${PODS}" ]; then + echo "[FAIL]: No image analyzer pods found" + FAILED=1 + else + for POD in ${PODS}; do + SCC_ANNOTATION=$(kubectl get pod "${POD}" \ + -n "{{ include "falcon-image-analyzer.namespace" . }}" \ + -o jsonpath="{.metadata.annotations.openshift\.io/scc}" 2>&1) + if [ -z "${SCC_ANNOTATION}" ]; then + echo "[FAIL]: Pod '${POD}' is missing openshift.io/scc annotation" + FAILED=1 + else + echo "[OK]: Pod '${POD}' is using SCC '${SCC_ANNOTATION}'" + fi + done + fi + + if [ "${FAILED}" -eq 1 ]; then + exit 1 + fi + exit 0 + securityContext: + runAsNonRoot: true + runAsUser: 1000 + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + serviceAccountName: {{ include "falcon-image-analyzer.fullname" . }}-test-sa + restartPolicy: Never +{{- end }} diff --git a/helm-charts/falcon-image-analyzer/values.schema.json b/helm-charts/falcon-image-analyzer/values.schema.json index cd0e08b2..03086490 100644 --- a/helm-charts/falcon-image-analyzer/values.schema.json +++ b/helm-charts/falcon-image-analyzer/values.schema.json @@ -237,6 +237,41 @@ } } } + }, + "openshift": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "createSCC": { + "type": "boolean", + "default": true + }, + "sccName": { + "type": "string", + "default": "" + } + } + }, + "pss": { + "type": "object", + "properties": { + "manageNamespace": { + "type": "boolean", + "default": false + } + } + }, + "testing": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + } + } } }, "oneOf": [ diff --git a/helm-charts/falcon-image-analyzer/values.yaml b/helm-charts/falcon-image-analyzer/values.yaml index 69b8c97e..6571223d 100644 --- a/helm-charts/falcon-image-analyzer/values.yaml +++ b/helm-charts/falcon-image-analyzer/values.yaml @@ -125,6 +125,29 @@ exclusions: # NOTE That setting this to true will also set the dnsPolicy: "ClusterFirstWithHostNet" hostNetwork: false +# OpenShift configuration. +# NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator +# (https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) is the +# recommended installation method for OpenShift clusters. +openshift: + # Set to true to enable OpenShift compatibility mode. + enabled: false + # Set to true to create a SecurityContextConstraints (SCC) resource granting the + # workload the privileges it requires. In DaemonSet mode this includes privileged + # access and hostPath volumes; in Deployment mode only runAsUser:0 is required. + createSCC: true + # Name of the SCC to create or use. If empty, defaults to the release fullname. + # Set createSCC: false and provide a name here to reference an existing SCC. + sccName: "" + +# Pod Security Standards (PSS) namespace labeling. +# PSS management is optional and independent of OpenShift. It can be enabled on any cluster. +# When enabled, Helm manages the install namespace and applies the labels required for the +# appropriate Pod Security Standard. +pss: + # Set to true to allow Helm to manage the install namespace PSS labels. + manageNamespace: false + # Define ImageAnalyzer POD DNS Policy, defaults to "ClusterFirstWithHostNet" when hostNetwork = true dnsPolicy: @@ -230,3 +253,7 @@ global: containerRegistry: pullSecret: "" configJSON: "" + +# Deploys the test suite during install for testing purposes. +testing: + enabled: false diff --git a/helm-charts/falcon-kac/Chart.yaml b/helm-charts/falcon-kac/Chart.yaml index fdeac40f..3a7956a9 100644 --- a/helm-charts/falcon-kac/Chart.yaml +++ b/helm-charts/falcon-kac/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.6.0 +version: 1.7.0-openshift.rc.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm-charts/falcon-kac/README.md b/helm-charts/falcon-kac/README.md index bd340de3..83a55f44 100644 --- a/helm-charts/falcon-kac/README.md +++ b/helm-charts/falcon-kac/README.md @@ -35,7 +35,6 @@ The Falcon Kubernetes Admission Controller has been deployed and tested on these - Amazon Elastic Kubernetes Service (EKS) - Google Kubernetes Engine (GKE) - Microsoft Azure Kubernetes Service (AKS) -- Red Hat OpenShift Container Platform 4.6 and later ## Helm Chart Support for Falcon Admission Controller Versions @@ -146,22 +145,41 @@ CID checksum, and then click **Copy your Customer ID checksum to the clipboard** --set image.registryConfigJSON=$IMAGE_PULL_TOKEN ``` -- Verify that the Falcon KAC deployment is ready and the corresponding pod has a Running status: +## OpenShift Compatibility - ``` - kubectl get deployments,pods -n falcon-kac - NAME READY UP-TO-DATE AVAILABLE AGE - falcon-kac 1/1 1 1 7d2h +> **Note:** OpenShift is **not a recommended** configuration for this Helm chart. The +> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) +> is the recommended installation method for OpenShift clusters. - NAME READY STATUS RESTARTS AGE - falcon-kac-7cc7dd57fc-pvzzf 2/2 Running 0 7d2h - ``` -- Verify that the Falcon KAC has an AID: - ``` - kubectl exec deployment/falcon-kac -n falcon-kac -c falcon-ac -- falconctl -g --aid - ``` - **Tip**: An AID is assigned to the Falcon KAC when it communicates with the Falcon cloud. If the Falcon KAC has an AID - that is not all zeros, it is installed and running properly. +In the default configuration, all containers run as non-root with no privilege escalation and no host access, which +satisfies the built-in `restricted-v2` SCC without any additional configuration. + +### Security Context Constraints + +If `hostNetwork` must be enabled (required when a custom CNI prevents control plane nodes from communicating directly +with pods), a custom SCC that permits host network access is required. The chart can create this SCC automatically: + +``` +helm install falcon-kac crowdstrike/falcon-kac \ + -n falcon-kac --create-namespace \ + --set falcon.cid=$FALCON_CID \ + --set image.repository=$KAC_IMAGE_REPO \ + --set image.tag=$KAC_IMAGE_TAG \ + --set hostNetwork=true \ + --set openshift.enabled=true +``` + +The SCC is managed as a standard Helm release resource and will be created on install and removed on uninstall. + +To use an existing SCC instead, set `openshift.createSCC=false` and bind the service account manually before installing. + +### OpenShift Values + +| Parameter | Description | Default | +|:-----------------------|:--------------------------------------------------------------------------------------------------------------------|:-------------------------------| +| `openshift.enabled` | Enable OpenShift compatibility mode | `false` | +| `openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the Deployment service account host network access | `true` | +| `openshift.sccName` | Name of the SCC to create or use. If empty, defaults to the release fullname | `""` (auto-generated) | ## Update Falcon KAC @@ -232,3 +250,7 @@ The following tables lists the Falcon KAC configurable parameters and their defa | `falconSecret.secretName` | Existing k8s secret name to inject sensitive Falcon values.
The secret must be under the same namespace as the KAC deployment. | None (Existing secret must include `FALCONCTL_OPT_CID`) | | `clusterName` | Manually set cluster name for self-hosted Kubernetes clusters where auto-discovery fails (e.g., MicroK8s). Displayed as hostname in Host Management UI. | None (auto-discovery used) | | `falconImageAnalyzerNamespace` | Falcon Image Analyzer namespace | falcon-image-analyzer | +| `hostNetwork` | Enable host network mode. Required when a custom CNI prevents control plane to pod communication. | `false` | +| `openshift.enabled` | Enable OpenShift compatibility mode. When `hostNetwork` is also `true`, creates an SCC granting host network access. | `false` | +| `openshift.createSCC` | Create a SecurityContextConstraints resource. Only has effect when `openshift.enabled` and `hostNetwork` are both `true`. | `true` | +| `openshift.sccName` | Name of the SCC to create or use. If empty, defaults to the release fullname. | `""` | diff --git a/helm-charts/falcon-kac/templates/_helpers.tpl b/helm-charts/falcon-kac/templates/_helpers.tpl index 930e97e4..19a6efd5 100644 --- a/helm-charts/falcon-kac/templates/_helpers.tpl +++ b/helm-charts/falcon-kac/templates/_helpers.tpl @@ -231,3 +231,14 @@ Get container registry config json from global value if it exists {{- .Values.image.registryConfigJSON | default "" -}} {{- end -}} {{- end -}} + +{{/* +OpenShift SCC name. Uses openshift.sccName if set, otherwise defaults to the fullname. +*/}} +{{- define "falcon-kac.sccName" -}} +{{- if .Values.openshift.sccName -}} +{{- .Values.openshift.sccName -}} +{{- else -}} +{{- include "falcon-kac.fullname" . -}} +{{- end -}} +{{- end -}} diff --git a/helm-charts/falcon-kac/templates/clusterrole.yaml b/helm-charts/falcon-kac/templates/clusterrole.yaml index ee2f12ad..66b7a3f2 100644 --- a/helm-charts/falcon-kac/templates/clusterrole.yaml +++ b/helm-charts/falcon-kac/templates/clusterrole.yaml @@ -95,4 +95,14 @@ rules: verbs: - get - list - - watch \ No newline at end of file + - watch +{{- if and .Values.openshift.enabled (not .Values.openshift.createSCC) .Values.openshift.sccName }} +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - {{ include "falcon-kac.sccName" . }} + verbs: + - use +{{- end }} \ No newline at end of file diff --git a/helm-charts/falcon-kac/templates/deployment_webhook.yaml b/helm-charts/falcon-kac/templates/deployment_webhook.yaml index 7c84afda..bc817c4b 100644 --- a/helm-charts/falcon-kac/templates/deployment_webhook.yaml +++ b/helm-charts/falcon-kac/templates/deployment_webhook.yaml @@ -87,6 +87,9 @@ spec: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | quote }} + {{- if and .Values.openshift.enabled .Values.openshift.createSCC .Values.hostNetwork }} + openshift.io/scc: {{ include "falcon-kac.sccName" . }} + {{- end }} {{- if or (.Values.autoDeploymentUpdate) (.Values.podAnnotations) }} {{- if .Values.autoDeploymentUpdate }} rollme: {{ randAlphaNum 5 | quote }} diff --git a/helm-charts/falcon-kac/templates/scc.yaml b/helm-charts/falcon-kac/templates/scc.yaml new file mode 100644 index 00000000..a06f5d0c --- /dev/null +++ b/helm-charts/falcon-kac/templates/scc.yaml @@ -0,0 +1,50 @@ +{{- if and .Values.openshift.enabled .Values.openshift.createSCC .Values.hostNetwork }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ include "falcon-kac.sccName" . }} + labels: + {{- include "falcon-kac.labels" . | nindent 4 }} + annotations: + kubernetes.io/description: >- + Grants the Falcon KAC Deployment the host network and host ports (4443, 4080) + access required when a custom CNI is in use. All other privileges remain at + the restricted level. +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: true +allowHostPID: false +allowHostPorts: true +allowPrivilegeEscalation: false +allowPrivilegedContainer: false +allowedCapabilities: [] +defaultAddCapabilities: [] +fsGroup: + type: MustRunAs + ranges: + - min: 1 + max: 65535 +readOnlyRootFilesystem: true +requiredDropCapabilities: + - ALL +runAsUser: + type: MustRunAsNonRoot +seLinuxContext: + type: MustRunAs +seccompProfiles: + - runtime/default +supplementalGroups: + type: MustRunAs + ranges: + - min: 1 + max: 65535 +users: + - system:serviceaccount:{{ include "falcon-kac.namespace" . }}:{{ .Values.serviceAccount.name }} +groups: [] +volumes: + - configMap + - downwardAPI + - emptyDir + - projected + - secret +{{- end }} diff --git a/helm-charts/falcon-kac/templates/tests/test-cluster-permissions.yaml b/helm-charts/falcon-kac/templates/tests/test-cluster-permissions.yaml index ca4b27a2..67daa745 100644 --- a/helm-charts/falcon-kac/templates/tests/test-cluster-permissions.yaml +++ b/helm-charts/falcon-kac/templates/tests/test-cluster-permissions.yaml @@ -33,6 +33,7 @@ rules: verbs: - get - list + - watch - apiGroups: - rbac.authorization.k8s.io resources: @@ -48,6 +49,22 @@ rules: verbs: - get - list +{{- if .Values.openshift.enabled }} +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + verbs: + - get +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - {{ include "falcon-kac.sccName" . }} + verbs: + - use +{{- end }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/helm-charts/falcon-kac/templates/tests/test-kac-running.yaml b/helm-charts/falcon-kac/templates/tests/test-kac-running.yaml index 8f94c425..a6547b17 100644 --- a/helm-charts/falcon-kac/templates/tests/test-kac-running.yaml +++ b/helm-charts/falcon-kac/templates/tests/test-kac-running.yaml @@ -12,6 +12,7 @@ spec: containers: - name: kubectl image: docker.io/bitnami/kubectl + imagePullPolicy: IfNotPresent command: - /bin/sh - -c @@ -19,7 +20,11 @@ spec: FAILED=0 echo "--- Waiting for pods to initialize ---" - sleep 10 + kubectl wait deployment \ + "{{ include "falcon-kac.name" . }}" \ + -n "{{ include "falcon-kac.namespace" . }}" \ + --for=condition=Available \ + --timeout=300s echo "--- Checking all KAC pods are running ---" # Exclude test pods by filtering out pods with helm.sh/hook annotation @@ -33,7 +38,7 @@ spec: fi echo "--- Checking ConfigMap ---" - CM_NAME="{{ include "falcon-kac.name" . }}-config" + CM_NAME="{{ include "falcon-kac.fullname" . }}-config" if ! kubectl get configmap "${CM_NAME}" -n "{{ include "falcon-kac.namespace" . }}" > /dev/null 2>&1; then echo "[FAIL]: ConfigMap '${CM_NAME}' not found" FAILED=1 @@ -101,7 +106,7 @@ spec: # Exclude test pods by filtering out pods with helm.sh/hook annotation PODS=$(kubectl get pods -n "{{ include "falcon-kac.namespace" . }}" \ -l "app={{ include "falcon-kac.name" . }}" \ - -o json 2>&1 | jq -r '.items[] | select(.metadata.annotations["helm.sh/hook"] == null) | .metadata.name') + -o json 2>/dev/null | jq -r '.items[] | select(.metadata.annotations["helm.sh/hook"] == null) | .metadata.name') if [ -z "${PODS}" ]; then echo "[FAIL]: No KAC pods found" FAILED=1 diff --git a/helm-charts/falcon-kac/templates/tests/test-openshift.yaml b/helm-charts/falcon-kac/templates/tests/test-openshift.yaml new file mode 100644 index 00000000..0b3db8bd --- /dev/null +++ b/helm-charts/falcon-kac/templates/tests/test-openshift.yaml @@ -0,0 +1,82 @@ +{{- if and .Values.testing.enabled .Values.openshift.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "falcon-kac.fullname" . }}-test-openshift" + namespace: {{ include "falcon-kac.namespace" . }} + labels: + {{- include "falcon-kac.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: kubectl + image: docker.io/bitnami/kubectl + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - | + FAILED=0 + + {{- if and .Values.openshift.createSCC .Values.hostNetwork }} + echo "--- Checking SCC exists ---" + if ! kubectl get scc "{{ include "falcon-kac.sccName" . }}" > /dev/null 2>&1; then + echo "[FAIL]: SCC '{{ include "falcon-kac.sccName" . }}' not found" + FAILED=1 + else + echo "[OK]: SCC '{{ include "falcon-kac.sccName" . }}' exists" + fi + + echo "--- Checking service account is bound to SCC ---" + SA_ENTRY="system:serviceaccount:{{ include "falcon-kac.namespace" . }}:{{ .Values.serviceAccount.name }}" + SCC_USERS=$(kubectl get scc "{{ include "falcon-kac.sccName" . }}" -o jsonpath="{.users}" 2>&1) + if ! echo "${SCC_USERS}" | grep -q "${SA_ENTRY}"; then + echo "[FAIL]: Service account '${SA_ENTRY}' is not bound to SCC" + echo "${SCC_USERS}" + FAILED=1 + else + echo "[OK]: Service account is bound to SCC" + fi + {{- end }} + + echo "--- Checking Deployment pods have openshift.io/scc annotation ---" + sleep 10 + # Exclude test pods by filtering out pods with helm.sh/hook annotation + PODS=$(kubectl get pods -n "{{ include "falcon-kac.namespace" . }}" \ + -l "app={{ include "falcon-kac.name" . }}" \ + -o json 2>&1 | jq -r '.items[] | select(.metadata.annotations["helm.sh/hook"] == null) | .metadata.name') + if [ -z "${PODS}" ]; then + echo "[FAIL]: No KAC pods found" + FAILED=1 + else + for POD in ${PODS}; do + SCC_ANNOTATION=$(kubectl get pod "${POD}" \ + -n "{{ include "falcon-kac.namespace" . }}" \ + -o jsonpath="{.metadata.annotations.openshift\.io/scc}" 2>&1) + if [ -z "${SCC_ANNOTATION}" ]; then + echo "[FAIL]: Pod '${POD}' is missing openshift.io/scc annotation" + FAILED=1 + else + echo "[OK]: Pod '${POD}' is using SCC '${SCC_ANNOTATION}'" + fi + done + fi + + if [ "${FAILED}" -eq 1 ]; then + exit 1 + fi + exit 0 + securityContext: + runAsNonRoot: true + runAsUser: 1000 + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + serviceAccountName: {{ include "falcon-kac.fullname" . }}-test-sa + restartPolicy: Never +{{- end }} diff --git a/helm-charts/falcon-kac/values.schema.json b/helm-charts/falcon-kac/values.schema.json index cab84cb6..3af1866b 100644 --- a/helm-charts/falcon-kac/values.schema.json +++ b/helm-charts/falcon-kac/values.schema.json @@ -368,6 +368,32 @@ "type": "boolean", "default": "false" }, + "openshift": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "createSCC": { + "type": "boolean", + "default": true + }, + "sccName": { + "type": "string", + "default": "" + } + } + }, + "testing": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + } + } + }, "dnsPolicy": { "type": [ "null", diff --git a/helm-charts/falcon-kac/values.yaml b/helm-charts/falcon-kac/values.yaml index 1bc66ba5..ebba2726 100644 --- a/helm-charts/falcon-kac/values.yaml +++ b/helm-charts/falcon-kac/values.yaml @@ -186,6 +186,20 @@ webhook: # custom CNI is in use where control plane nodes cannot establish network communication with pods. hostNetwork: false +# OpenShift configuration. +# NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator +# (https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) is the +# recommended installation method for OpenShift clusters. +openshift: + # Set to true to enable OpenShift compatibility mode. + enabled: false + # Set to true to create a SecurityContextConstraints (SCC) resource. Only applies when + # openshift.enabled and hostNetwork are also true; the default restricted-v2 SCC is sufficient otherwise. + createSCC: true + # Name of the SCC to create or use. If empty, defaults to the release fullname. + # Set createSCC: false and provide a name here to reference an existing SCC. + sccName: "" + # Define Falcon KAC POD DNS Policy, follows cluster default when not set and sets "ClusterFirstWithHostNet" when hostNetwork = true unless overriden dnsPolicy: @@ -203,3 +217,7 @@ global: containerRegistry: pullSecret: "" configJSON: "" + +# Deploys the test suite during install for testing purposes. +testing: + enabled: false diff --git a/helm-charts/falcon-platform/Chart.lock b/helm-charts/falcon-platform/Chart.lock index 04fffa2d..6216a6fe 100644 --- a/helm-charts/falcon-platform/Chart.lock +++ b/helm-charts/falcon-platform/Chart.lock @@ -1,12 +1,12 @@ dependencies: - name: falcon-sensor repository: file://../falcon-sensor - version: 1.36.0 + version: 1.37.0-openshift.rc.1 - name: falcon-kac repository: file://../falcon-kac - version: 1.6.0 + version: 1.7.0-openshift.rc.1 - name: falcon-image-analyzer repository: file://../falcon-image-analyzer - version: 1.1.20 -digest: sha256:df5d3f9047c9ae430112c5c69860afc7f9a27771590ea9a872e85cd8ae27ae11 -generated: "2026-05-05T10:37:59.520948-04:00" + version: 1.1.21-openshift.rc.1 +digest: sha256:2d219429ad6a139273bdbcf8c6e67774400204152b0b738275762817d7e00a30 +generated: "2026-06-08T09:49:49.971981-05:00" diff --git a/helm-charts/falcon-platform/Chart.yaml b/helm-charts/falcon-platform/Chart.yaml index 3ff59a24..9f621388 100644 --- a/helm-charts/falcon-platform/Chart.yaml +++ b/helm-charts/falcon-platform/Chart.yaml @@ -8,7 +8,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.4.0 +version: 1.5.0-openshift.rc.1 keywords: - CrowdStrike @@ -35,14 +35,14 @@ kubeVersion: ">1.22.0-0" dependencies: - name: falcon-sensor - version: 1.36.0 + version: 1.37.0-openshift.rc.1 repository: file://../falcon-sensor condition: falcon-sensor.enabled - name: falcon-kac - version: 1.6.0 + version: 1.7.0-openshift.rc.1 repository: file://../falcon-kac condition: falcon-kac.enabled - name: falcon-image-analyzer - version: 1.1.20 + version: 1.1.21-openshift.rc.1 repository: file://../falcon-image-analyzer condition: falcon-image-analyzer.enabled diff --git a/helm-charts/falcon-sensor/Chart.yaml b/helm-charts/falcon-sensor/Chart.yaml index 466534f5..1fa71165 100644 --- a/helm-charts/falcon-sensor/Chart.yaml +++ b/helm-charts/falcon-sensor/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.36.0 +version: 1.37.0-openshift.rc.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm-charts/falcon-sensor/README.md b/helm-charts/falcon-sensor/README.md index 85a0ff6d..b9a92bd0 100644 --- a/helm-charts/falcon-sensor/README.md +++ b/helm-charts/falcon-sensor/README.md @@ -39,6 +39,12 @@ The Falcon Helm chart has been tested to deploy on the following Kubernetes dist * Google Kubernetes Engine (GKE) * Rancher K3s +> **OpenShift:** OpenShift is **not a recommended** configuration for this Helm chart. The +> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) +> is the recommended installation method for OpenShift clusters. A best-effort +> compatibility mode is available for the node DaemonSet only (see +> [OpenShift Compatibility](#openshift-compatibility) below). + # Dependencies 1. Requires a x86_64 or ARM64 Kubernetes cluster @@ -604,3 +610,119 @@ After validating the removal of the `/opt/Crowdstrike` directory, the cleanup Da ```bash helm uninstall falcon-helm -n \ ``` + +## OpenShift Compatibility + +> **Note:** OpenShift is **not a recommended** configuration for this Helm chart. The +> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) +> is the recommended installation method for OpenShift clusters. + +This chart provides a best-effort compatibility mode for deploying the Falcon node sensor as a DaemonSet on OpenShift clusters. **The container sensor (`container.enabled`) is not supported on OpenShift** and will produce an error if enabled alongside `node.openshift.enabled`. + +### Security Context Constraints + +OpenShift uses Security Context Constraints (SCC) to control pod privileges. Because the Falcon node sensor requires privileged host access (`hostPID`, `hostIPC`, `hostNetwork`, and a privileged container), the default `restricted` SCC is insufficient. + +When `node.openshift.enabled=true` and `node.openshift.createSCC=true`, the chart creates an SCC named `-falcon-sensor-node-sensor` and binds it to the DaemonSet and cleanup DaemonSet service accounts. To use an existing SCC instead, set `node.openshift.createSCC=false` and bind the service accounts manually before installing. + +OpenShift runs Pod Security Admission in warn/audit mode alongside SCCs. To suppress PSA warnings for the install namespace, label it before installing: + +```bash +kubectl label namespace falcon-system \ + pod-security.kubernetes.io/enforce=privileged \ + pod-security.kubernetes.io/warn=privileged \ + pod-security.kubernetes.io/audit=privileged +``` + +### OpenShift Values + +| Parameter | Description | Default | +|:-------------------------------|:--------------------------------------------------------------------------------------------------------------|:------------------------------------------| +| `node.openshift.enabled` | Enable OpenShift compatibility mode for the node DaemonSet | `false` | +| `node.openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the DaemonSet service account the required privileges | `true` | +| `node.openshift.sccName` | Name of the SCC to create or use. If empty, defaults to `-falcon-sensor-node-sensor` | `""` (auto-generated from release name) | +| `node.pss.manageNamespace` | Allow Helm to manage the install namespace and apply Pod Security Standard labels | `false` | + +### Pod Security Standards (PSS) Namespace Labeling + +Kubernetes 1.23+ enforces Pod Security Standards (PSS) which can block privileged pods like the Falcon node sensor. When `node.pss.manageNamespace=true`, Helm will manage the install namespace and apply the required `privileged` PSS labels automatically. + +**Option 1: Let Helm manage the namespace (recommended for new installations)** + +```bash +helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ + -n falcon-system --create-namespace \ + --set falcon.cid="" \ + --set node.image.repository="/falcon-node-sensor" \ + --set node.pss.manageNamespace=true +``` + +**Option 2: Manually label the namespace before installation** + +If you prefer to manage the namespace yourself or are installing into an existing namespace: + +```bash +kubectl label namespace falcon-system \ + pod-security.kubernetes.io/enforce=privileged \ + pod-security.kubernetes.io/warn=privileged \ + pod-security.kubernetes.io/audit=privileged +``` + +Then install without `node.pss.manageNamespace`: + +```bash +helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ + -n falcon-system \ + --set falcon.cid="" \ + --set node.image.repository="/falcon-node-sensor" +``` + +### Installing on OpenShift + +**Basic OpenShift installation with automatic SCC creation:** + +```bash +helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ + -n falcon-system --create-namespace \ + --set falcon.cid="" \ + --set node.image.repository="/falcon-node-sensor" \ + --set node.openshift.enabled=true +``` + +**With automatic PSS namespace labeling (suppresses PSA warnings):** + +```bash +helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ + -n falcon-system --create-namespace \ + --set falcon.cid="" \ + --set node.image.repository="/falcon-node-sensor" \ + --set node.openshift.enabled=true \ + --set node.pss.manageNamespace=true +``` + +**Using an existing SCC:** + +Set `node.openshift.createSCC=false` and specify the SCC name, then bind the service accounts before installing: + +```bash +helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ + -n falcon-system --create-namespace \ + --set falcon.cid="" \ + --set node.image.repository="/falcon-node-sensor" \ + --set node.openshift.enabled=true \ + --set node.openshift.createSCC=false \ + --set node.openshift.sccName="my-existing-scc" +``` + +**Using a custom SCC name:** + +To create an SCC with a custom name instead of the default auto-generated name: + +```bash +helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ + -n falcon-system --create-namespace \ + --set falcon.cid="" \ + --set node.image.repository="/falcon-node-sensor" \ + --set node.openshift.enabled=true \ + --set node.openshift.sccName="crowdstrike-falcon-node" +``` diff --git a/helm-charts/falcon-sensor/templates/_helpers.tpl b/helm-charts/falcon-sensor/templates/_helpers.tpl index 2dba1244..4735e878 100644 --- a/helm-charts/falcon-sensor/templates/_helpers.tpl +++ b/helm-charts/falcon-sensor/templates/_helpers.tpl @@ -337,3 +337,23 @@ Validate AITap configuration. {{- fail "AITap: 'container.aitap.aidrSecretName' is required when 'container.aitap.useExistingSecret' is true. Set this to the name of the existing secret that contains the AI-DR collector token." -}} {{- end -}} {{- end -}} + +{{/* +OpenShift SCC name for the node DaemonSet. +*/}} +{{- define "falcon-sensor.sccName" -}} +{{- if .Values.node.openshift.sccName -}} +{{- .Values.node.openshift.sccName -}} +{{- else -}} +{{- printf "%s-node-sensor" (include "falcon-sensor.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Validate OpenShift configuration: container sensor is not supported in OpenShift mode. +*/}} +{{- define "falcon-sensor.validateOpenshiftConfig" -}} +{{- if and .Values.node.openshift.enabled .Values.container.enabled -}} +{{- fail "OpenShift mode (node.openshift.enabled) is only supported with the node DaemonSet. The container sensor (container.enabled) is not supported on OpenShift. Use the official Red Hat certified operator instead." -}} +{{- end -}} +{{- end -}} diff --git a/helm-charts/falcon-sensor/templates/clusterrole.yaml b/helm-charts/falcon-sensor/templates/clusterrole.yaml index 064932fc..a373a792 100644 --- a/helm-charts/falcon-sensor/templates/clusterrole.yaml +++ b/helm-charts/falcon-sensor/templates/clusterrole.yaml @@ -39,4 +39,14 @@ rules: - watch - list {{- end }} +{{- if and .Values.node.openshift.enabled (not .Values.node.openshift.createSCC) .Values.node.openshift.sccName }} +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - {{ include "falcon-sensor.sccName" . }} + verbs: + - use +{{- end }} {{- end }} diff --git a/helm-charts/falcon-sensor/templates/daemonset.yaml b/helm-charts/falcon-sensor/templates/daemonset.yaml index 445fdeaa..f6d867e3 100644 --- a/helm-charts/falcon-sensor/templates/daemonset.yaml +++ b/helm-charts/falcon-sensor/templates/daemonset.yaml @@ -1,5 +1,6 @@ {{- if and .Values.node.enabled (not .Values.node.cleanupOnly) }} {{- include "falcon-sensor.validateFalconSecretName" . }} +{{- include "falcon-sensor.validateOpenshiftConfig" . }} {{- $imagePullSecretName := include "falcon-sensor.node.imagePullSecretName" . }} {{- $registryConfigJson := include "falcon-sensor.node.registryConfigJson" . }} apiVersion: apps/v1 @@ -43,6 +44,9 @@ spec: metadata: annotations: {{ .Values.node.daemonset.podAnnotationKey }}: disabled + {{- if .Values.node.openshift.enabled }} + openshift.io/scc: {{ include "falcon-sensor.sccName" . }} + {{- end }} {{- range $key, $value := .Values.node.podAnnotations }} {{ $key }}: {{ $value | quote }} {{- end }} diff --git a/helm-charts/falcon-sensor/templates/namespace_labels.yaml b/helm-charts/falcon-sensor/templates/namespace_labels.yaml new file mode 100644 index 00000000..b0f03a50 --- /dev/null +++ b/helm-charts/falcon-sensor/templates/namespace_labels.yaml @@ -0,0 +1,77 @@ +{{- if and .Values.node.pss.manageNamespace .Values.node.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "falcon-sensor.fullname" . }}-ns-labeler + namespace: {{ include "falcon-sensor.namespace" . }} + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-10" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "falcon-sensor.fullname" . }}-ns-labeler + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-10" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +rules: + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "falcon-sensor.fullname" . }}-ns-labeler + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-10" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +subjects: + - kind: ServiceAccount + name: {{ include "falcon-sensor.fullname" . }}-ns-labeler + namespace: {{ include "falcon-sensor.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ include "falcon-sensor.fullname" . }}-ns-labeler + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "falcon-sensor.fullname" . }}-ns-labeler + namespace: {{ include "falcon-sensor.namespace" . }} + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + template: + spec: + serviceAccountName: {{ include "falcon-sensor.fullname" . }}-ns-labeler + restartPolicy: OnFailure + containers: + - name: kubectl + image: docker.io/bitnami/kubectl + command: + - kubectl + - label + - namespace + - {{ include "falcon-sensor.namespace" . }} + - "pod-security.kubernetes.io/enforce=privileged" + - "pod-security.kubernetes.io/warn=privileged" + - "pod-security.kubernetes.io/audit=privileged" + - "--overwrite" +{{- end }} diff --git a/helm-charts/falcon-sensor/templates/node_cleanup.yaml b/helm-charts/falcon-sensor/templates/node_cleanup.yaml index 383aa557..901ef8ea 100644 --- a/helm-charts/falcon-sensor/templates/node_cleanup.yaml +++ b/helm-charts/falcon-sensor/templates/node_cleanup.yaml @@ -41,6 +41,9 @@ spec: metadata: annotations: {{ .Values.node.daemonset.podAnnotationKey }}: disabled + {{- if .Values.node.openshift.enabled }} + openshift.io/scc: {{ include "falcon-sensor.sccName" . }} + {{- end }} {{- range $key, $value := .Values.node.podAnnotations }} {{ $key }}: {{ $value | quote }} {{- end }} diff --git a/helm-charts/falcon-sensor/templates/scc.yaml b/helm-charts/falcon-sensor/templates/scc.yaml new file mode 100644 index 00000000..12c78f64 --- /dev/null +++ b/helm-charts/falcon-sensor/templates/scc.yaml @@ -0,0 +1,51 @@ +{{- if and .Values.node.enabled .Values.node.openshift.enabled .Values.node.openshift.createSCC }} +# NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator +# (https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) is the +# recommended installation method for OpenShift clusters. +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ include "falcon-sensor.sccName" . }} + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + kubernetes.io/description: >- + Grants the Falcon node sensor DaemonSet the privileges required to monitor + and protect cluster nodes. This SCC is required because the Falcon sensor + runs as a privileged process in the host's kernel. OpenShift is not a + recommended configuration; use the official Red Hat certified operator for + production deployments. +allowHostDirVolumePlugin: true +allowHostIPC: true +allowHostNetwork: true +allowHostPID: true +allowHostPorts: false +allowPrivilegeEscalation: true +allowPrivilegedContainer: true +allowedCapabilities: + - '*' +defaultAddCapabilities: [] +fsGroup: + type: RunAsAny +readOnlyRootFilesystem: false +requiredDropCapabilities: [] +runAsUser: + type: RunAsAny +seLinuxContext: + type: RunAsAny +seccompProfiles: + - '*' +supplementalGroups: + type: RunAsAny +users: + - system:serviceaccount:{{ include "falcon-sensor.namespace" . }}:{{ .Values.serviceAccount.name }} +groups: [] +volumes: + - configMap + - downwardAPI + - emptyDir + - hostPath + - persistentVolumeClaim + - projected + - secret +{{- end }} diff --git a/helm-charts/falcon-sensor/templates/scc_cleanup.yaml b/helm-charts/falcon-sensor/templates/scc_cleanup.yaml new file mode 100644 index 00000000..82dea5cd --- /dev/null +++ b/helm-charts/falcon-sensor/templates/scc_cleanup.yaml @@ -0,0 +1,124 @@ +{{- if and .Values.node.enabled .Values.node.openshift.enabled .Values.node.openshift.createSCC .Values.node.hooks.postDelete.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup + namespace: {{ include "falcon-sensor.namespace" . }} + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +rules: + - apiGroups: ["security.openshift.io"] + resources: ["securitycontextconstraints"] + verbs: ["delete"] + resourceNames: + - {{ include "falcon-sensor.sccName" . | quote }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +subjects: + - kind: ServiceAccount + name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup + namespace: {{ include "falcon-sensor.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup + namespace: {{ include "falcon-sensor.namespace" . }} + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + template: + spec: + serviceAccountName: {{ include "falcon-sensor.fullname" . }}-scc-cleanup + restartPolicy: OnFailure + containers: + - name: kubectl + image: docker.io/bitnami/kubectl + command: + - kubectl + - delete + - scc + - {{ include "falcon-sensor.sccName" . | quote }} + - --ignore-not-found +--- +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ include "falcon-sensor.sccName" . }}-cleanup + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + kubernetes.io/description: >- + Grants the Falcon node sensor cleanup DaemonSet the privileges required to + uninstall the sensor from cluster nodes. Created during helm uninstall and + deleted once the cleanup DaemonSet completes. + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "0" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +allowHostDirVolumePlugin: true +allowHostIPC: true +allowHostNetwork: true +allowHostPID: true +allowHostPorts: false +allowPrivilegeEscalation: true +allowPrivilegedContainer: true +allowedCapabilities: + - '*' +defaultAddCapabilities: [] +fsGroup: + type: RunAsAny +readOnlyRootFilesystem: false +requiredDropCapabilities: [] +runAsUser: + type: RunAsAny +seLinuxContext: + type: RunAsAny +seccompProfiles: + - '*' +supplementalGroups: + type: RunAsAny +users: + - system:serviceaccount:{{ include "falcon-sensor.namespace" . }}:{{ include "falcon-sensor.cleanupServiceAccountName" . }} +groups: [] +volumes: + - configMap + - downwardAPI + - emptyDir + - hostPath + - persistentVolumeClaim + - projected + - secret +{{- end }} diff --git a/helm-charts/falcon-sensor/templates/tests/test-cluster-permissions.yaml b/helm-charts/falcon-sensor/templates/tests/test-cluster-permissions.yaml index bc7f30b7..b8e3ec29 100644 --- a/helm-charts/falcon-sensor/templates/tests/test-cluster-permissions.yaml +++ b/helm-charts/falcon-sensor/templates/tests/test-cluster-permissions.yaml @@ -34,6 +34,7 @@ rules: verbs: - get - list + - watch - apiGroups: - rbac.authorization.k8s.io resources: @@ -50,6 +51,22 @@ rules: verbs: - get - list +{{- if .Values.node.openshift.enabled }} +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + verbs: + - get +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - {{ include "falcon-sensor.sccName" . }} + verbs: + - use +{{- end }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml b/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml index 98a09588..1ab787d5 100644 --- a/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml +++ b/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml @@ -20,7 +20,10 @@ spec: FAILED=0 echo "--- Waiting for pods to initialize ---" - sleep 10 + kubectl rollout status daemonset \ + "{{ include "falcon-sensor.fullname" . }}" \ + -n "{{ include "falcon-sensor.namespace" . }}" \ + --timeout=300s echo "--- Checking all sensor pods are running ---" KUBECMD=$(kubectl get pods -n "{{ include "falcon-sensor.namespace" . }}" -l "app.kubernetes.io/component=kernel_sensor" --field-selector=status.phase!=Running --no-headers 2>&1) @@ -109,6 +112,22 @@ spec: done fi + {{- if .Values.node.pss.manageNamespace }} + echo "--- Checking PSS namespace labels ---" + NS_NAME="{{ include "falcon-sensor.namespace" . }}" + for LABEL in "pod-security.kubernetes.io/enforce=privileged" "pod-security.kubernetes.io/warn=privileged" "pod-security.kubernetes.io/audit=privileged"; do + KEY="${LABEL%%=*}" + VALUE="${LABEL##*=}" + ACTUAL=$(kubectl get namespace "${NS_NAME}" -o json 2>&1 | jq -r --arg key "${KEY}" '.metadata.labels[$key] // ""') + if [ "${ACTUAL}" != "${VALUE}" ]; then + echo "[FAIL]: Namespace '${NS_NAME}' label '${KEY}' is '${ACTUAL}', expected '${VALUE}'" + FAILED=1 + else + echo "[OK]: Namespace '${NS_NAME}' has label '${KEY}=${VALUE}'" + fi + done + {{- end }} + echo "--- Checking pod labels ---" for POD in ${PODS}; do # Check component label diff --git a/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml b/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml new file mode 100644 index 00000000..76709c30 --- /dev/null +++ b/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml @@ -0,0 +1,79 @@ +{{- if and .Values.testing.enabled .Values.node.enabled .Values.node.openshift.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "falcon-sensor.fullname" . }}-test-openshift" + namespace: {{ include "falcon-sensor.namespace" . }} + labels: + {{- include "falcon-sensor.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: kubectl + image: docker.io/bitnami/kubectl + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - | + FAILED=0 + + {{- if .Values.node.openshift.createSCC }} + echo "--- Checking SCC exists ---" + if ! kubectl get scc "{{ include "falcon-sensor.sccName" . }}" > /dev/null 2>&1; then + echo "[FAIL]: SCC '{{ include "falcon-sensor.sccName" . }}' not found" + FAILED=1 + else + echo "[OK]: SCC '{{ include "falcon-sensor.sccName" . }}' exists" + fi + + echo "--- Checking service account is bound to SCC ---" + SA_ENTRY="system:serviceaccount:{{ include "falcon-sensor.namespace" . }}:{{ .Values.serviceAccount.name }}" + SCC_USERS=$(kubectl get scc "{{ include "falcon-sensor.sccName" . }}" -o jsonpath="{.users}" 2>&1) + if ! echo "${SCC_USERS}" | grep -q "${SA_ENTRY}"; then + echo "[FAIL]: Service account '${SA_ENTRY}' is not bound to SCC" + echo "${SCC_USERS}" + FAILED=1 + else + echo "[OK]: Service account is bound to SCC" + fi + {{- end }} + + echo "--- Checking DaemonSet pods have openshift.io/scc annotation ---" + sleep 10 + PODS=$(kubectl get pods -n "{{ include "falcon-sensor.namespace" . }}" \ + -l "app.kubernetes.io/component=kernel_sensor" \ + -o jsonpath="{.items[*].metadata.name}" 2>&1) + if [ -z "${PODS}" ]; then + echo "[FAIL]: No DaemonSet sensor pods found" + FAILED=1 + else + for POD in ${PODS}; do + SCC_ANNOTATION=$(kubectl get pod "${POD}" \ + -n "{{ include "falcon-sensor.namespace" . }}" \ + -o jsonpath="{.metadata.annotations.openshift\.io/scc}" 2>&1) + if [ -z "${SCC_ANNOTATION}" ]; then + echo "[FAIL]: Pod '${POD}' is missing openshift.io/scc annotation" + FAILED=1 + else + echo "[OK]: Pod '${POD}' is using SCC '${SCC_ANNOTATION}'" + fi + done + fi + + if [ "${FAILED}" -eq 1 ]; then + exit 1 + fi + exit 0 + securityContext: + runAsNonRoot: true + runAsUser: 1000 + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + serviceAccountName: {{ include "falcon-sensor.fullname" . }}-test-sa + restartPolicy: Never +{{- end }} diff --git a/helm-charts/falcon-sensor/templates/tests/test-sidecar-sensor-running.yaml b/helm-charts/falcon-sensor/templates/tests/test-sidecar-sensor-running.yaml index 8ef7bb36..85a7a298 100644 --- a/helm-charts/falcon-sensor/templates/tests/test-sidecar-sensor-running.yaml +++ b/helm-charts/falcon-sensor/templates/tests/test-sidecar-sensor-running.yaml @@ -65,6 +65,7 @@ spec: containers: - name: kubectl image: docker.io/bitnami/kubectl + imagePullPolicy: IfNotPresent command: - /bin/sh - -c @@ -72,7 +73,11 @@ spec: FAILED=0 echo "--- Waiting for pods to initialize ---" - sleep 10 + kubectl wait deployment \ + "{{ include "falcon-sensor.fullname" . }}" \ + -n "{{ include "falcon-sensor.namespace" . }}" \ + --for=condition=Available \ + --timeout=300s echo "--- Checking all injector pods are running ---" KUBECMD=$(kubectl get pods -n "{{ include "falcon-sensor.namespace" . }}" -l "app.kubernetes.io/component=container_sensor" --field-selector=status.phase!=Running --no-headers 2>&1) diff --git a/helm-charts/falcon-sensor/values.schema.json b/helm-charts/falcon-sensor/values.schema.json index 6cf3e645..a2b3cb3e 100644 --- a/helm-charts/falcon-sensor/values.schema.json +++ b/helm-charts/falcon-sensor/values.schema.json @@ -296,6 +296,32 @@ "example": [ "my_prod_cluster" ] + }, + "openshift": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "createSCC": { + "type": "boolean", + "default": true + }, + "sccName": { + "type": "string", + "default": "" + } + } + }, + "pss": { + "type": "object", + "properties": { + "manageNamespace": { + "type": "boolean", + "default": false + } + } } } }, diff --git a/helm-charts/falcon-sensor/values.yaml b/helm-charts/falcon-sensor/values.yaml index ec5dd1dd..1a1f78d9 100644 --- a/helm-charts/falcon-sensor/values.yaml +++ b/helm-charts/falcon-sensor/values.yaml @@ -111,6 +111,28 @@ node: # Enable, to run cleanup for the prior daemonset deployment cleanupOnly: false + # OpenShift configuration. + # NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator + # (https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) is the + # recommended installation method for OpenShift clusters. + # These settings apply only to the node DaemonSet and have no effect on the container sensor. + openshift: + # Set to true to enable OpenShift compatibility mode for the node DaemonSet. + enabled: false + # Set to true to create a SecurityContextConstraints (SCC) resource granting the + # DaemonSet service account the privileges required by the Falcon node sensor. + createSCC: true + # Name of the SCC to create or use. If empty, defaults to "-falcon-sensor-node-sensor" + sccName: "" + + # Pod Security Standards (PSS) namespace labeling. + # When enabled, Helm manages the install namespace and applies the labels required + # for the privileged Pod Security Standard. This is required for Kubernetes 1.23+ + # and suppresses PSA warnings on OpenShift. + pss: + # Set to true to allow Helm to manage the install namespace PSS labels. + manageNamespace: false + container: # When enabled, Helm chart deploys the Falcon Container Sensor to Pods through Webhooks enabled: false From 28c3aede665fc008083bb1e1585ffd95d366499f Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 10:31:56 -0500 Subject: [PATCH 02/16] testing --- helm-charts/falcon-image-analyzer/README.md | 53 +++++++-------------- helm-charts/falcon-kac/README.md | 17 ++----- helm-charts/falcon-sensor/README.md | 2 +- 3 files changed, 22 insertions(+), 50 deletions(-) diff --git a/helm-charts/falcon-image-analyzer/README.md b/helm-charts/falcon-image-analyzer/README.md index c31a54b8..b5a3d59f 100644 --- a/helm-charts/falcon-image-analyzer/README.md +++ b/helm-charts/falcon-image-analyzer/README.md @@ -113,10 +113,6 @@ The following tables list the Falcon sensor configurable parameters and their de | `log.output` optional ( available Helm Chart v >= 1.1.7 & falcon-imageanalyzer >= 1.0.12) | Set the value to for log output terminal. `2=stderr` and `1=stdout` | 2 ( stderr ) | | `hostNetwork` optional ( available Helm Chart v >= 1.1.11) | Set the value to `true` to use the hostNetwork instead of pod network | `false` | | `dnsPolicy` optional ( available Helm Chart v >= 1.1.11) | Set the value to any supported value from https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | `` no value implies `Default` | -| `openshift.enabled` optional | Enable OpenShift compatibility mode. Creates a SecurityContextConstraints resource sized to the active workload mode (DaemonSet or Deployment). | `false` | -| `openshift.createSCC` optional | Create the SCC resource. Set to `false` to manage the SCC outside of Helm. | `true` | -| `openshift.sccName` optional | Name of the SCC to create or use. If empty, defaults to the release fullname. | `""` | -| `pss.manageNamespace` optional | Allow Helm to manage the install namespace PSS labels (`privileged`). Independent of OpenShift — can be enabled on any cluster running Kubernetes 1.25+. | `false` | | ~~`scanStats.enabled`~~ optional (**Deprecated in 1.1.17+** . available Helm Chart v >= 1.1.8 & falcon-imageanalyzer >= 1.0.13) | Set `enabled` to true for agent to send scan error and stats to cloud | `true` | | `crowdstrikeConfig.clusterName` optional | Cluster name | None | | `crowdstrikeConfig.enableDebug` optional | Set to `true` for debug level log verbosity. | false | @@ -140,10 +136,10 @@ The `[CROWDSTRIKE_IMAGE_REGISTRY]` can be replaced with below registries based o -| Region | ImageName | +| Region | ImageName | |:-------|:-------------------------------------------------------------------------------------------| | `us-1` | `registry.crowdstrike.com/falcon-imageanalyzer/release/falcon-imageanalyzer` | -| `us-2` | `registry.crowdstrike.com/falcon-imageanalyzer/release/falcon-imageanalyzer` | +| `us-2` | `registry.crowdstrike.com/falcon-imageanalyzer/release/falcon-imageanalyzer` | | `eu-1` | `registry.crowdstrike.com/falcon-imageanalyzer/release/falcon-imageanalyzer` | | `gov1` | `registry.laggar.gcw.crowdstrike.com/falcon-imageanalyzer/release/falcon-imageanalyzer` | | `gov2` | `registry.us-gov-2.crowdstrike.mil/falcon-imageanalyzer/release/falcon-imageanalyzer` | @@ -251,8 +247,8 @@ From IAR ver >-= 1.0.20 IAR will dynamically switch between PRIMARY and SECONDAR IAR requires internet access to your assigned CrowdStrike authentication API and upload servers. If your network requires it, configure your allowlists with your assigned CrowdStrike cloud servers. -| Region | Authentication API | PRIMARY Scan Upload Servers | SECONDARY Scan Upload Servers | -|:----:|:--:|:---------------------------------------------------:|----------------------------------------| +| Region | Authentication API | PRIMARY Scan Upload Servers | SECONDARY Scan Upload Servers | +|:----:|:--:|:---------------------------------------------------:|----------------------------------------| | US-1 | https://api.crowdstrike.com | https://container-upload.us-1.crowdstrike.com | https://api.crowdstrike.com | | US-2 | https://api.us-2.crowdstrike.com | https://container-upload.us-2.crowdstrike.com | https://api.us-2.crowdstrike.com | | EU-1 | https://api.eu-1.crowdstrike.com | https://container-upload.eu-1.crowdstrike.com | https://api.eu-1.crowdstrike.com | @@ -261,8 +257,8 @@ If your network requires it, configure your allowlists with your assigned CrowdS #### ***For IAR versions < 1.0.20 both Authtentication/Upload Servers point to the same -| Region | Authentication API | Scan Upload Servers | -|:----:|:--:|:--------------------------------------:| +| Region | Authentication API | Scan Upload Servers | +|:----:|:--:|:--------------------------------------:| | US-1 | https://api.crowdstrike.com | https://api.crowdstrike.com | | US-2 | https://api.us-2.crowdstrike.com | https://api.us-2.crowdstrike.com | | EU-1 | https://api.eu-1.crowdstrike.com | https://api.eu-1.crowdstrike.com | @@ -339,22 +335,9 @@ Set `openshift.enabled: true` to have the chart create the appropriate SCC autom minimum permissions required for the active workload mode. The SCC is managed as a standard Helm release resource and will be created on install and removed on uninstall. -**DaemonSet mode on OpenShift:** -``` -helm upgrade --install -f /path/to/config_values.yaml \ - --create-namespace -n falcon-image-analyzer imageanalyzer crowdstrike/falcon-image-analyzer \ - --set openshift.enabled=true -``` - -**Deployment mode on OpenShift:** -``` -helm upgrade --install -f /path/to/config_values.yaml \ - --create-namespace -n falcon-image-analyzer imageanalyzer crowdstrike/falcon-image-analyzer \ - --set openshift.enabled=true -``` - -To manage the SCC outside of Helm, set `openshift.createSCC: false` and apply a SCC that grants the permissions -described above to the IAR service account. +To manage the SCC outside of Helm, set `openshift.createSCC: false`, define `openshift.sccName` with the name of your +SCC, and ensure the SCC is created prior to deployment. The SCC must grant the permissions described above to the IAR +service account. #### OpenShift Values @@ -371,7 +354,7 @@ By Default, this is set to `20Gi` but can be overridden by the customer by addin ``` # This is a mandatory mount for both deployment and daemonset. # this is used as a tmp working space for image storage. -# adjust this space to any comfortable value. the temp ssize limit should be equal to +# adjust this space to any comfortable value. the temp ssize limit should be equal to # 2 X to the largest image possible to run in the container. # for e.g. if the largest possible image is in the range of 4g put 8Gi as the value. volumes: @@ -384,7 +367,7 @@ volumes: ### AWS IAM Roles for Service Accounts -- **KIAM OR Kube2IAM.** +- **KIAM OR Kube2IAM.** For the IAR to detect cloud as AWS, it should be able to retrieve sts token to assume role to retrieve ECR Tokens. There are 2 options for that . If your EKS cluster us using the **kiam** or **kube2iam** admission controller, add annotations for the IAR service account in the `config_values.yaml` as stated below, before installing. Make sure the roles have trust-relationship to allow @@ -503,8 +486,8 @@ use the above secret as `"my-app-ns:regcred,my-app-ns:regcred2"` `autoDiscoverCredentials` if set to true, the IAR will try to discover the docker-registry secrets across all namespaces. if autoDiscoverCredentials is set to `true` then the provided credentials are ignored. Note that the secret -should be existing of type docker-registry in ANY namespace on the cluster to be discovered. -IAR will NOT pick up any new secret added to the cluster after IAR is running. +should be existing of type docker-registry in ANY namespace on the cluster to be discovered. +IAR will NOT pick up any new secret added to the cluster after IAR is running. For that a restart of IAR is needed. ### PROXY Usage @@ -522,11 +505,11 @@ If a customer us using proxy settings. Please make sure to add the registry doma This is so that the IAR can connect to the registries without proxy and authenticate if needed using secrets provided or download the public free images. ***Note that some registries domains also have other urls based on the auth challenge that is sent by the registry service. Please make sure to add those as well to ```NO_PROXY``` -for e.g. for gitlab registries there exists the -- registry domain ```my-reg.gitlab.com``` +for e.g. for gitlab registries there exists the +- registry domain ```my-reg.gitlab.com``` - and the other ```www.gitlab.com``` -- The above is very registry provider specific. One needs to ensure nothing ie being blocked by Proxy +- The above is very registry provider specific. One needs to ensure nothing ie being blocked by Proxy ### Pod Eviction If for some reason pod evictions are observed in the Cluster due to exceeding ephemeral storage @@ -574,7 +557,7 @@ metadata: #### Images Images can be excluded by adding the full image name in the below section of the `config_values.yaml` - Image without registries will be defaulted to `index.docker.io` -- Images without tags will be defaulted to `latest` tag +- Images without tags will be defaulted to `latest` tag ``` exclusions: imageName: "myregistry.io/mynamespace/myimage:tag1,myregistry.io/mynamespace/myimage@sha2561234678901209" @@ -610,7 +593,7 @@ kind: Deployment / Daemonset metadata: name: myapp namespace: mynamespace - + spec: replicas: 1 template: diff --git a/helm-charts/falcon-kac/README.md b/helm-charts/falcon-kac/README.md index 83a55f44..0e9a91ef 100644 --- a/helm-charts/falcon-kac/README.md +++ b/helm-charts/falcon-kac/README.md @@ -159,19 +159,11 @@ satisfies the built-in `restricted-v2` SCC without any additional configuration. If `hostNetwork` must be enabled (required when a custom CNI prevents control plane nodes from communicating directly with pods), a custom SCC that permits host network access is required. The chart can create this SCC automatically: -``` -helm install falcon-kac crowdstrike/falcon-kac \ - -n falcon-kac --create-namespace \ - --set falcon.cid=$FALCON_CID \ - --set image.repository=$KAC_IMAGE_REPO \ - --set image.tag=$KAC_IMAGE_TAG \ - --set hostNetwork=true \ - --set openshift.enabled=true -``` - The SCC is managed as a standard Helm release resource and will be created on install and removed on uninstall. -To use an existing SCC instead, set `openshift.createSCC=false` and bind the service account manually before installing. +To use an existing SCC instead, set `openshift.createSCC=false`, define `openshift.sccName` with the name of your SCC, +and ensure the SCC is created prior to deployment. The SCC must be bound to the service account manually before +installing. ### OpenShift Values @@ -251,6 +243,3 @@ The following tables lists the Falcon KAC configurable parameters and their defa | `clusterName` | Manually set cluster name for self-hosted Kubernetes clusters where auto-discovery fails (e.g., MicroK8s). Displayed as hostname in Host Management UI. | None (auto-discovery used) | | `falconImageAnalyzerNamespace` | Falcon Image Analyzer namespace | falcon-image-analyzer | | `hostNetwork` | Enable host network mode. Required when a custom CNI prevents control plane to pod communication. | `false` | -| `openshift.enabled` | Enable OpenShift compatibility mode. When `hostNetwork` is also `true`, creates an SCC granting host network access. | `false` | -| `openshift.createSCC` | Create a SecurityContextConstraints resource. Only has effect when `openshift.enabled` and `hostNetwork` are both `true`. | `true` | -| `openshift.sccName` | Name of the SCC to create or use. If empty, defaults to the release fullname. | `""` | diff --git a/helm-charts/falcon-sensor/README.md b/helm-charts/falcon-sensor/README.md index b9a92bd0..beff2115 100644 --- a/helm-charts/falcon-sensor/README.md +++ b/helm-charts/falcon-sensor/README.md @@ -623,7 +623,7 @@ This chart provides a best-effort compatibility mode for deploying the Falcon no OpenShift uses Security Context Constraints (SCC) to control pod privileges. Because the Falcon node sensor requires privileged host access (`hostPID`, `hostIPC`, `hostNetwork`, and a privileged container), the default `restricted` SCC is insufficient. -When `node.openshift.enabled=true` and `node.openshift.createSCC=true`, the chart creates an SCC named `-falcon-sensor-node-sensor` and binds it to the DaemonSet and cleanup DaemonSet service accounts. To use an existing SCC instead, set `node.openshift.createSCC=false` and bind the service accounts manually before installing. +When `node.openshift.enabled=true` and `node.openshift.createSCC=true`, the chart creates an SCC named `-falcon-sensor-node-sensor` and binds it to the DaemonSet and cleanup DaemonSet service accounts. To use an existing SCC instead, set `node.openshift.createSCC=false`, define `node.openshift.sccName` with the name of your SCC, and ensure the SCC is created prior to deployment. The SCC must be bound to the service accounts manually before installing. OpenShift runs Pod Security Admission in warn/audit mode alongside SCCs. To suppress PSA warnings for the install namespace, label it before installing: From 119c9cd0b65ca39d221cb596987e29ed99ac5e9a Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 10:46:22 -0500 Subject: [PATCH 03/16] fix scc annotation --- helm-charts/falcon-image-analyzer/templates/daemonset.yaml | 2 +- helm-charts/falcon-image-analyzer/templates/deployment.yaml | 2 +- helm-charts/falcon-kac/templates/deployment_webhook.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/helm-charts/falcon-image-analyzer/templates/daemonset.yaml b/helm-charts/falcon-image-analyzer/templates/daemonset.yaml index 043c427f..ca931841 100644 --- a/helm-charts/falcon-image-analyzer/templates/daemonset.yaml +++ b/helm-charts/falcon-image-analyzer/templates/daemonset.yaml @@ -49,7 +49,7 @@ spec: metadata: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled - {{- if and .Values.openshift.enabled .Values.openshift.createSCC }} + {{- if .Values.openshift.enabled }} openshift.io/scc: {{ include "falcon-image-analyzer.sccName" . }} {{- end }} {{- with .Values.podAnnotations }} diff --git a/helm-charts/falcon-image-analyzer/templates/deployment.yaml b/helm-charts/falcon-image-analyzer/templates/deployment.yaml index d0b86e08..1e97260c 100644 --- a/helm-charts/falcon-image-analyzer/templates/deployment.yaml +++ b/helm-charts/falcon-image-analyzer/templates/deployment.yaml @@ -50,7 +50,7 @@ spec: metadata: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled - {{- if and .Values.openshift.enabled .Values.openshift.createSCC }} + {{- if .Values.openshift.enabled }} openshift.io/scc: {{ include "falcon-image-analyzer.sccName" . }} {{- end }} {{- with .Values.podAnnotations }} diff --git a/helm-charts/falcon-kac/templates/deployment_webhook.yaml b/helm-charts/falcon-kac/templates/deployment_webhook.yaml index bc817c4b..8cb054ab 100644 --- a/helm-charts/falcon-kac/templates/deployment_webhook.yaml +++ b/helm-charts/falcon-kac/templates/deployment_webhook.yaml @@ -87,7 +87,7 @@ spec: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | quote }} - {{- if and .Values.openshift.enabled .Values.openshift.createSCC .Values.hostNetwork }} + {{- if and .Values.openshift.enabled .Values.hostNetwork }} openshift.io/scc: {{ include "falcon-kac.sccName" . }} {{- end }} {{- if or (.Values.autoDeploymentUpdate) (.Values.podAnnotations) }} From 81758dda7e1c07702a3a927b532118e347e2469d Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 11:15:36 -0500 Subject: [PATCH 04/16] fix tests --- .../templates/tests/test-openshift.yaml | 7 +++- .../templates/tests/test-openshift.yaml | 8 ++++ .../templates/tests/test-openshift.yaml | 38 ++++++++++++++++--- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml b/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml index 7b1ed088..74793c3a 100644 --- a/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml @@ -46,9 +46,11 @@ spec: echo "--- Checking {{ if .Values.daemonset.enabled }}DaemonSet{{ else }}Deployment{{ end }} pods have openshift.io/scc annotation ---" sleep 10 + EXPECTED_SCC="{{ include "falcon-image-analyzer.sccName" . }}" + # Exclude test pods by filtering out pods with helm.sh/hook annotation PODS=$(kubectl get pods -n "{{ include "falcon-image-analyzer.namespace" . }}" \ -l "app.kubernetes.io/name={{ include "falcon-image-analyzer.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" \ - -o jsonpath="{.items[*].metadata.name}" 2>&1) + -o json 2>&1 | jq -r '.items[] | select(.metadata.annotations["helm.sh/hook"] == null) | .metadata.name') if [ -z "${PODS}" ]; then echo "[FAIL]: No image analyzer pods found" FAILED=1 @@ -60,6 +62,9 @@ spec: if [ -z "${SCC_ANNOTATION}" ]; then echo "[FAIL]: Pod '${POD}' is missing openshift.io/scc annotation" FAILED=1 + elif [ "${SCC_ANNOTATION}" != "${EXPECTED_SCC}" ]; then + echo "[FAIL]: Pod '${POD}' has SCC '${SCC_ANNOTATION}' but expected '${EXPECTED_SCC}'" + FAILED=1 else echo "[OK]: Pod '${POD}' is using SCC '${SCC_ANNOTATION}'" fi diff --git a/helm-charts/falcon-kac/templates/tests/test-openshift.yaml b/helm-charts/falcon-kac/templates/tests/test-openshift.yaml index 0b3db8bd..2bd3a844 100644 --- a/helm-charts/falcon-kac/templates/tests/test-openshift.yaml +++ b/helm-charts/falcon-kac/templates/tests/test-openshift.yaml @@ -40,8 +40,10 @@ spec: fi {{- end }} + {{- if .Values.hostNetwork }} echo "--- Checking Deployment pods have openshift.io/scc annotation ---" sleep 10 + EXPECTED_SCC="{{ include "falcon-kac.sccName" . }}" # Exclude test pods by filtering out pods with helm.sh/hook annotation PODS=$(kubectl get pods -n "{{ include "falcon-kac.namespace" . }}" \ -l "app={{ include "falcon-kac.name" . }}" \ @@ -57,11 +59,17 @@ spec: if [ -z "${SCC_ANNOTATION}" ]; then echo "[FAIL]: Pod '${POD}' is missing openshift.io/scc annotation" FAILED=1 + elif [ "${SCC_ANNOTATION}" != "${EXPECTED_SCC}" ]; then + echo "[FAIL]: Pod '${POD}' has SCC '${SCC_ANNOTATION}' but expected '${EXPECTED_SCC}'" + FAILED=1 else echo "[OK]: Pod '${POD}' is using SCC '${SCC_ANNOTATION}'" fi done fi + {{- else }} + echo "--- Skipping SCC annotation check (hostNetwork is disabled) ---" + {{- end }} if [ "${FAILED}" -eq 1 ]; then exit 1 diff --git a/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml b/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml index 76709c30..13c9bd2c 100644 --- a/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml +++ b/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml @@ -42,22 +42,50 @@ spec: echo "--- Checking DaemonSet pods have openshift.io/scc annotation ---" sleep 10 - PODS=$(kubectl get pods -n "{{ include "falcon-sensor.namespace" . }}" \ + EXPECTED_SCC="{{ include "falcon-sensor.sccName" . }}" + + # Check main sensor DaemonSet pods + SENSOR_PODS=$(kubectl get pods -n "{{ include "falcon-sensor.namespace" . }}" \ -l "app.kubernetes.io/component=kernel_sensor" \ -o jsonpath="{.items[*].metadata.name}" 2>&1) - if [ -z "${PODS}" ]; then + if [ -z "${SENSOR_PODS}" ]; then echo "[FAIL]: No DaemonSet sensor pods found" FAILED=1 else - for POD in ${PODS}; do + for POD in ${SENSOR_PODS}; do + SCC_ANNOTATION=$(kubectl get pod "${POD}" \ + -n "{{ include "falcon-sensor.namespace" . }}" \ + -o jsonpath="{.metadata.annotations.openshift\.io/scc}" 2>&1) + if [ -z "${SCC_ANNOTATION}" ]; then + echo "[FAIL]: Sensor pod '${POD}' is missing openshift.io/scc annotation" + FAILED=1 + elif [ "${SCC_ANNOTATION}" != "${EXPECTED_SCC}" ]; then + echo "[FAIL]: Sensor pod '${POD}' has SCC '${SCC_ANNOTATION}' but expected '${EXPECTED_SCC}'" + FAILED=1 + else + echo "[OK]: Sensor pod '${POD}' is using SCC '${SCC_ANNOTATION}'" + fi + done + fi + + # Check cleanup DaemonSet pods if they exist + CLEANUP_PODS=$(kubectl get pods -n "{{ include "falcon-sensor.namespace" . }}" \ + -l "app.kubernetes.io/component=cleanup" \ + -o jsonpath="{.items[*].metadata.name}" 2>&1) + if [ -n "${CLEANUP_PODS}" ]; then + echo "--- Checking cleanup DaemonSet pods have openshift.io/scc annotation ---" + for POD in ${CLEANUP_PODS}; do SCC_ANNOTATION=$(kubectl get pod "${POD}" \ -n "{{ include "falcon-sensor.namespace" . }}" \ -o jsonpath="{.metadata.annotations.openshift\.io/scc}" 2>&1) if [ -z "${SCC_ANNOTATION}" ]; then - echo "[FAIL]: Pod '${POD}' is missing openshift.io/scc annotation" + echo "[FAIL]: Cleanup pod '${POD}' is missing openshift.io/scc annotation" + FAILED=1 + elif [ "${SCC_ANNOTATION}" != "${EXPECTED_SCC}" ]; then + echo "[FAIL]: Cleanup pod '${POD}' has SCC '${SCC_ANNOTATION}' but expected '${EXPECTED_SCC}'" FAILED=1 else - echo "[OK]: Pod '${POD}' is using SCC '${SCC_ANNOTATION}'" + echo "[OK]: Cleanup pod '${POD}' is using SCC '${SCC_ANNOTATION}'" fi done fi From abf528831d1da8a5751e1da37d344b4c72f404ac Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 11:26:50 -0500 Subject: [PATCH 05/16] Update docs to state required user scc permissions --- helm-charts/falcon-image-analyzer/README.md | 13 +++++-------- helm-charts/falcon-kac/README.md | 5 ++++- helm-charts/falcon-sensor/README.md | 6 +++++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/helm-charts/falcon-image-analyzer/README.md b/helm-charts/falcon-image-analyzer/README.md index b5a3d59f..774b6ebd 100644 --- a/helm-charts/falcon-image-analyzer/README.md +++ b/helm-charts/falcon-image-analyzer/README.md @@ -300,17 +300,11 @@ For a successful deployment, you will want to ensure that: Starting with Kubernetes 1.25, Pod Security Standards (PSS) are enforced via the Pod Security Admission (PSA) controller. Falcon Image Analyzer requires `privileged` PSS labels on its namespace because it accesses the container runtime socket (DaemonSet mode) or runs as root (Deployment mode). -Set `pss.manageNamespace: true` to have Helm apply the required labels automatically as part of install and upgrade: - -``` -helm upgrade --install imageanalyzer crowdstrike/falcon-image-analyzer \ - --create-namespace -n falcon-image-analyzer \ - --set pss.manageNamespace=true -``` +Set `pss.manageNamespace: true` to have Helm apply the required labels automatically as part of install and upgrade. To apply the labels manually instead: ``` -kubectl label --overwrite ns falcon-image-analyzer \ +kubectl label --overwrite ns \ pod-security.kubernetes.io/enforce=privileged \ pod-security.kubernetes.io/warn=privileged \ pod-security.kubernetes.io/audit=privileged @@ -335,6 +329,9 @@ Set `openshift.enabled: true` to have the chart create the appropriate SCC autom minimum permissions required for the active workload mode. The SCC is managed as a standard Helm release resource and will be created on install and removed on uninstall. +**Helm User Permissions:** When `openshift.createSCC: true`, the user or service account running Helm must have +permission to create, update, and delete `SecurityContextConstraints` resources at the cluster level. + To manage the SCC outside of Helm, set `openshift.createSCC: false`, define `openshift.sccName` with the name of your SCC, and ensure the SCC is created prior to deployment. The SCC must grant the permissions described above to the IAR service account. diff --git a/helm-charts/falcon-kac/README.md b/helm-charts/falcon-kac/README.md index 0e9a91ef..241cb9e9 100644 --- a/helm-charts/falcon-kac/README.md +++ b/helm-charts/falcon-kac/README.md @@ -157,10 +157,13 @@ satisfies the built-in `restricted-v2` SCC without any additional configuration. ### Security Context Constraints If `hostNetwork` must be enabled (required when a custom CNI prevents control plane nodes from communicating directly -with pods), a custom SCC that permits host network access is required. The chart can create this SCC automatically: +with pods), a custom SCC that permits host network access is required. The chart can create this SCC automatically. The SCC is managed as a standard Helm release resource and will be created on install and removed on uninstall. +**Helm User Permissions:** When `openshift.createSCC: true`, the user or service account running Helm must have +permission to create, update, and delete `SecurityContextConstraints` resources at the cluster level. + To use an existing SCC instead, set `openshift.createSCC=false`, define `openshift.sccName` with the name of your SCC, and ensure the SCC is created prior to deployment. The SCC must be bound to the service account manually before installing. diff --git a/helm-charts/falcon-sensor/README.md b/helm-charts/falcon-sensor/README.md index beff2115..1486b9d9 100644 --- a/helm-charts/falcon-sensor/README.md +++ b/helm-charts/falcon-sensor/README.md @@ -623,7 +623,11 @@ This chart provides a best-effort compatibility mode for deploying the Falcon no OpenShift uses Security Context Constraints (SCC) to control pod privileges. Because the Falcon node sensor requires privileged host access (`hostPID`, `hostIPC`, `hostNetwork`, and a privileged container), the default `restricted` SCC is insufficient. -When `node.openshift.enabled=true` and `node.openshift.createSCC=true`, the chart creates an SCC named `-falcon-sensor-node-sensor` and binds it to the DaemonSet and cleanup DaemonSet service accounts. To use an existing SCC instead, set `node.openshift.createSCC=false`, define `node.openshift.sccName` with the name of your SCC, and ensure the SCC is created prior to deployment. The SCC must be bound to the service accounts manually before installing. +When `node.openshift.enabled=true` and `node.openshift.createSCC=true`, the chart creates an SCC named `-falcon-sensor-node-sensor` and binds it to the DaemonSet and cleanup DaemonSet service accounts. + +**Helm User Permissions:** When `node.openshift.createSCC: true`, the user or service account running Helm must have permission to create, update, and delete `SecurityContextConstraints` resources at the cluster level. + +To use an existing SCC instead, set `node.openshift.createSCC=false`, define `node.openshift.sccName` with the name of your SCC, and ensure the SCC is created prior to deployment. The SCC must be bound to the service accounts manually before installing. OpenShift runs Pod Security Admission in warn/audit mode alongside SCCs. To suppress PSA warnings for the install namespace, label it before installing: From 7b8f35635735be86360afc07ea26e88bcf6e8df3 Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 11:49:04 -0500 Subject: [PATCH 06/16] Misc updates --- helm-charts/falcon-image-analyzer/README.md | 2 +- helm-charts/falcon-image-analyzer/values.yaml | 2 +- helm-charts/falcon-kac/README.md | 2 +- helm-charts/falcon-kac/values.yaml | 2 +- helm-charts/falcon-sensor/README.md | 71 ++----------------- .../container_deployment_webhook.yaml | 1 + .../falcon-sensor/templates/daemonset.yaml | 1 - helm-charts/falcon-sensor/templates/scc.yaml | 2 +- helm-charts/falcon-sensor/values.yaml | 2 +- 9 files changed, 13 insertions(+), 72 deletions(-) diff --git a/helm-charts/falcon-image-analyzer/README.md b/helm-charts/falcon-image-analyzer/README.md index 774b6ebd..ff248266 100644 --- a/helm-charts/falcon-image-analyzer/README.md +++ b/helm-charts/falcon-image-analyzer/README.md @@ -313,7 +313,7 @@ kubectl label --overwrite ns \ ### OpenShift Compatibility > **Note:** OpenShift is **not a recommended** configuration for this Helm chart. The -> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) +> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) > is the recommended installation method for OpenShift clusters. #### Security Context Constraints diff --git a/helm-charts/falcon-image-analyzer/values.yaml b/helm-charts/falcon-image-analyzer/values.yaml index 6571223d..889da1da 100644 --- a/helm-charts/falcon-image-analyzer/values.yaml +++ b/helm-charts/falcon-image-analyzer/values.yaml @@ -127,7 +127,7 @@ hostNetwork: false # OpenShift configuration. # NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator -# (https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) is the +# (https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) is the # recommended installation method for OpenShift clusters. openshift: # Set to true to enable OpenShift compatibility mode. diff --git a/helm-charts/falcon-kac/README.md b/helm-charts/falcon-kac/README.md index 241cb9e9..70da88d1 100644 --- a/helm-charts/falcon-kac/README.md +++ b/helm-charts/falcon-kac/README.md @@ -148,7 +148,7 @@ CID checksum, and then click **Copy your Customer ID checksum to the clipboard** ## OpenShift Compatibility > **Note:** OpenShift is **not a recommended** configuration for this Helm chart. The -> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) +> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) > is the recommended installation method for OpenShift clusters. In the default configuration, all containers run as non-root with no privilege escalation and no host access, which diff --git a/helm-charts/falcon-kac/values.yaml b/helm-charts/falcon-kac/values.yaml index ebba2726..afe638df 100644 --- a/helm-charts/falcon-kac/values.yaml +++ b/helm-charts/falcon-kac/values.yaml @@ -188,7 +188,7 @@ hostNetwork: false # OpenShift configuration. # NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator -# (https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) is the +# (https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) is the # recommended installation method for OpenShift clusters. openshift: # Set to true to enable OpenShift compatibility mode. diff --git a/helm-charts/falcon-sensor/README.md b/helm-charts/falcon-sensor/README.md index 1486b9d9..2a4df56b 100644 --- a/helm-charts/falcon-sensor/README.md +++ b/helm-charts/falcon-sensor/README.md @@ -40,7 +40,7 @@ The Falcon Helm chart has been tested to deploy on the following Kubernetes dist * Rancher K3s > **OpenShift:** OpenShift is **not a recommended** configuration for this Helm chart. The -> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) +> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) > is the recommended installation method for OpenShift clusters. A best-effort > compatibility mode is available for the node DaemonSet only (see > [OpenShift Compatibility](#openshift-compatibility) below). @@ -614,7 +614,7 @@ helm uninstall falcon-helm -n \ ## OpenShift Compatibility > **Note:** OpenShift is **not a recommended** configuration for this Helm chart. The -> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) +> [official Red Hat certified CrowdStrike Falcon Operator](https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) > is the recommended installation method for OpenShift clusters. This chart provides a best-effort compatibility mode for deploying the Falcon node sensor as a DaemonSet on OpenShift clusters. **The container sensor (`container.enabled`) is not supported on OpenShift** and will produce an error if enabled alongside `node.openshift.enabled`. @@ -653,80 +653,21 @@ Kubernetes 1.23+ enforces Pod Security Standards (PSS) which can block privilege **Option 1: Let Helm manage the namespace (recommended for new installations)** -```bash -helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ - -n falcon-system --create-namespace \ - --set falcon.cid="" \ - --set node.image.repository="/falcon-node-sensor" \ - --set node.pss.manageNamespace=true -``` +Set `node.pss.manageNamespace=true` to have Helm apply the required labels automatically. **Option 2: Manually label the namespace before installation** If you prefer to manage the namespace yourself or are installing into an existing namespace: ```bash -kubectl label namespace falcon-system \ +kubectl label namespace \ pod-security.kubernetes.io/enforce=privileged \ pod-security.kubernetes.io/warn=privileged \ pod-security.kubernetes.io/audit=privileged ``` -Then install without `node.pss.manageNamespace`: - -```bash -helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ - -n falcon-system \ - --set falcon.cid="" \ - --set node.image.repository="/falcon-node-sensor" -``` - ### Installing on OpenShift -**Basic OpenShift installation with automatic SCC creation:** +Set `node.openshift.enabled=true` to enable OpenShift compatibility mode. The chart will automatically create and manage the required SCC unless `node.openshift.createSCC=false` is set. -```bash -helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ - -n falcon-system --create-namespace \ - --set falcon.cid="" \ - --set node.image.repository="/falcon-node-sensor" \ - --set node.openshift.enabled=true -``` - -**With automatic PSS namespace labeling (suppresses PSA warnings):** - -```bash -helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ - -n falcon-system --create-namespace \ - --set falcon.cid="" \ - --set node.image.repository="/falcon-node-sensor" \ - --set node.openshift.enabled=true \ - --set node.pss.manageNamespace=true -``` - -**Using an existing SCC:** - -Set `node.openshift.createSCC=false` and specify the SCC name, then bind the service accounts before installing: - -```bash -helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ - -n falcon-system --create-namespace \ - --set falcon.cid="" \ - --set node.image.repository="/falcon-node-sensor" \ - --set node.openshift.enabled=true \ - --set node.openshift.createSCC=false \ - --set node.openshift.sccName="my-existing-scc" -``` - -**Using a custom SCC name:** - -To create an SCC with a custom name instead of the default auto-generated name: - -```bash -helm upgrade --install falcon-helm crowdstrike/falcon-sensor \ - -n falcon-system --create-namespace \ - --set falcon.cid="" \ - --set node.image.repository="/falcon-node-sensor" \ - --set node.openshift.enabled=true \ - --set node.openshift.sccName="crowdstrike-falcon-node" -``` +For additional configuration options, see the [OpenShift Values](#openshift-values) table above. diff --git a/helm-charts/falcon-sensor/templates/container_deployment_webhook.yaml b/helm-charts/falcon-sensor/templates/container_deployment_webhook.yaml index bbe7e1b5..1f0eef79 100644 --- a/helm-charts/falcon-sensor/templates/container_deployment_webhook.yaml +++ b/helm-charts/falcon-sensor/templates/container_deployment_webhook.yaml @@ -1,4 +1,5 @@ {{- if .Values.container.enabled }} +{{- include "falcon-sensor.validateOpenshiftConfig" . }} {{- $namespace := (include "falcon-sensor.namespace" .) -}} {{- $name := (printf "%s-injector" (include "falcon-sensor.name" .)) -}} {{- $fullName := (printf "%s.%s.svc" $name $namespace) -}} diff --git a/helm-charts/falcon-sensor/templates/daemonset.yaml b/helm-charts/falcon-sensor/templates/daemonset.yaml index f6d867e3..d0fde5c3 100644 --- a/helm-charts/falcon-sensor/templates/daemonset.yaml +++ b/helm-charts/falcon-sensor/templates/daemonset.yaml @@ -1,6 +1,5 @@ {{- if and .Values.node.enabled (not .Values.node.cleanupOnly) }} {{- include "falcon-sensor.validateFalconSecretName" . }} -{{- include "falcon-sensor.validateOpenshiftConfig" . }} {{- $imagePullSecretName := include "falcon-sensor.node.imagePullSecretName" . }} {{- $registryConfigJson := include "falcon-sensor.node.registryConfigJson" . }} apiVersion: apps/v1 diff --git a/helm-charts/falcon-sensor/templates/scc.yaml b/helm-charts/falcon-sensor/templates/scc.yaml index 12c78f64..c6827b13 100644 --- a/helm-charts/falcon-sensor/templates/scc.yaml +++ b/helm-charts/falcon-sensor/templates/scc.yaml @@ -1,6 +1,6 @@ {{- if and .Values.node.enabled .Values.node.openshift.enabled .Values.node.openshift.createSCC }} # NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator -# (https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) is the +# (https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) is the # recommended installation method for OpenShift clusters. apiVersion: security.openshift.io/v1 kind: SecurityContextConstraints diff --git a/helm-charts/falcon-sensor/values.yaml b/helm-charts/falcon-sensor/values.yaml index 1a1f78d9..b3ead088 100644 --- a/helm-charts/falcon-sensor/values.yaml +++ b/helm-charts/falcon-sensor/values.yaml @@ -113,7 +113,7 @@ node: # OpenShift configuration. # NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator - # (https://catalog.redhat.com/software/operators/detail/5e7e24f99fca9b7637249d4d) is the + # (https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) is the # recommended installation method for OpenShift clusters. # These settings apply only to the node DaemonSet and have no effect on the container sensor. openshift: From b9fd1bf6ef542a04b0f8566badfa0326a243536d Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 11:56:12 -0500 Subject: [PATCH 07/16] Refactoring cleanup scc ds --- helm-charts/falcon-sensor/templates/scc.yaml | 1 + .../falcon-sensor/templates/scc_cleanup.yaml | 124 ------------------ 2 files changed, 1 insertion(+), 124 deletions(-) delete mode 100644 helm-charts/falcon-sensor/templates/scc_cleanup.yaml diff --git a/helm-charts/falcon-sensor/templates/scc.yaml b/helm-charts/falcon-sensor/templates/scc.yaml index c6827b13..76cbee81 100644 --- a/helm-charts/falcon-sensor/templates/scc.yaml +++ b/helm-charts/falcon-sensor/templates/scc.yaml @@ -39,6 +39,7 @@ supplementalGroups: type: RunAsAny users: - system:serviceaccount:{{ include "falcon-sensor.namespace" . }}:{{ .Values.serviceAccount.name }} + - system:serviceaccount:{{ include "falcon-sensor.namespace" . }}:{{ include "falcon-sensor.cleanupServiceAccountName" . }} groups: [] volumes: - configMap diff --git a/helm-charts/falcon-sensor/templates/scc_cleanup.yaml b/helm-charts/falcon-sensor/templates/scc_cleanup.yaml deleted file mode 100644 index 82dea5cd..00000000 --- a/helm-charts/falcon-sensor/templates/scc_cleanup.yaml +++ /dev/null @@ -1,124 +0,0 @@ -{{- if and .Values.node.enabled .Values.node.openshift.enabled .Values.node.openshift.createSCC .Values.node.hooks.postDelete.enabled }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup - namespace: {{ include "falcon-sensor.namespace" . }} - labels: - {{- include "falcon-sensor.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": post-delete - "helm.sh/hook-weight": "1" - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup - labels: - {{- include "falcon-sensor.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": post-delete - "helm.sh/hook-weight": "1" - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded -rules: - - apiGroups: ["security.openshift.io"] - resources: ["securitycontextconstraints"] - verbs: ["delete"] - resourceNames: - - {{ include "falcon-sensor.sccName" . | quote }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup - labels: - {{- include "falcon-sensor.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": post-delete - "helm.sh/hook-weight": "1" - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded -subjects: - - kind: ServiceAccount - name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup - namespace: {{ include "falcon-sensor.namespace" . }} -roleRef: - kind: ClusterRole - name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup - apiGroup: rbac.authorization.k8s.io ---- -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ include "falcon-sensor.fullname" . }}-scc-cleanup - namespace: {{ include "falcon-sensor.namespace" . }} - labels: - {{- include "falcon-sensor.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": post-delete - "helm.sh/hook-weight": "2" - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded -spec: - template: - spec: - serviceAccountName: {{ include "falcon-sensor.fullname" . }}-scc-cleanup - restartPolicy: OnFailure - containers: - - name: kubectl - image: docker.io/bitnami/kubectl - command: - - kubectl - - delete - - scc - - {{ include "falcon-sensor.sccName" . | quote }} - - --ignore-not-found ---- -apiVersion: security.openshift.io/v1 -kind: SecurityContextConstraints -metadata: - name: {{ include "falcon-sensor.sccName" . }}-cleanup - labels: - {{- include "falcon-sensor.labels" . | nindent 4 }} - annotations: - kubernetes.io/description: >- - Grants the Falcon node sensor cleanup DaemonSet the privileges required to - uninstall the sensor from cluster nodes. Created during helm uninstall and - deleted once the cleanup DaemonSet completes. - "helm.sh/hook": post-delete - "helm.sh/hook-weight": "0" - "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded -allowHostDirVolumePlugin: true -allowHostIPC: true -allowHostNetwork: true -allowHostPID: true -allowHostPorts: false -allowPrivilegeEscalation: true -allowPrivilegedContainer: true -allowedCapabilities: - - '*' -defaultAddCapabilities: [] -fsGroup: - type: RunAsAny -readOnlyRootFilesystem: false -requiredDropCapabilities: [] -runAsUser: - type: RunAsAny -seLinuxContext: - type: RunAsAny -seccompProfiles: - - '*' -supplementalGroups: - type: RunAsAny -users: - - system:serviceaccount:{{ include "falcon-sensor.namespace" . }}:{{ include "falcon-sensor.cleanupServiceAccountName" . }} -groups: [] -volumes: - - configMap - - downwardAPI - - emptyDir - - hostPath - - persistentVolumeClaim - - projected - - secret -{{- end }} From 77f3245a076577a2e65d2bdecfab13830aa4d750 Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:01:34 -0500 Subject: [PATCH 08/16] revert chart version changes --- helm-charts/falcon-image-analyzer/Chart.yaml | 2 +- helm-charts/falcon-kac/Chart.yaml | 2 +- helm-charts/falcon-platform/Chart.lock | 10 +++++----- helm-charts/falcon-platform/Chart.yaml | 8 ++++---- helm-charts/falcon-sensor/Chart.yaml | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/helm-charts/falcon-image-analyzer/Chart.yaml b/helm-charts/falcon-image-analyzer/Chart.yaml index 982afd62..a4f77006 100644 --- a/helm-charts/falcon-image-analyzer/Chart.yaml +++ b/helm-charts/falcon-image-analyzer/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.1.21-openshift.rc.1 +version: 1.1.20 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm-charts/falcon-kac/Chart.yaml b/helm-charts/falcon-kac/Chart.yaml index 3a7956a9..fdeac40f 100644 --- a/helm-charts/falcon-kac/Chart.yaml +++ b/helm-charts/falcon-kac/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.7.0-openshift.rc.1 +version: 1.6.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm-charts/falcon-platform/Chart.lock b/helm-charts/falcon-platform/Chart.lock index 6216a6fe..f25431ad 100644 --- a/helm-charts/falcon-platform/Chart.lock +++ b/helm-charts/falcon-platform/Chart.lock @@ -1,12 +1,12 @@ dependencies: - name: falcon-sensor repository: file://../falcon-sensor - version: 1.37.0-openshift.rc.1 + version: 1.36.0 - name: falcon-kac repository: file://../falcon-kac - version: 1.7.0-openshift.rc.1 + version: 1.6.0 - name: falcon-image-analyzer repository: file://../falcon-image-analyzer - version: 1.1.21-openshift.rc.1 -digest: sha256:2d219429ad6a139273bdbcf8c6e67774400204152b0b738275762817d7e00a30 -generated: "2026-06-08T09:49:49.971981-05:00" + version: 1.1.20 +digest: sha256:df5d3f9047c9ae430112c5c69860afc7f9a27771590ea9a872e85cd8ae27ae11 +generated: "2026-06-09T12:00:33.86277-05:00" diff --git a/helm-charts/falcon-platform/Chart.yaml b/helm-charts/falcon-platform/Chart.yaml index 9f621388..3ff59a24 100644 --- a/helm-charts/falcon-platform/Chart.yaml +++ b/helm-charts/falcon-platform/Chart.yaml @@ -8,7 +8,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.5.0-openshift.rc.1 +version: 1.4.0 keywords: - CrowdStrike @@ -35,14 +35,14 @@ kubeVersion: ">1.22.0-0" dependencies: - name: falcon-sensor - version: 1.37.0-openshift.rc.1 + version: 1.36.0 repository: file://../falcon-sensor condition: falcon-sensor.enabled - name: falcon-kac - version: 1.7.0-openshift.rc.1 + version: 1.6.0 repository: file://../falcon-kac condition: falcon-kac.enabled - name: falcon-image-analyzer - version: 1.1.21-openshift.rc.1 + version: 1.1.20 repository: file://../falcon-image-analyzer condition: falcon-image-analyzer.enabled diff --git a/helm-charts/falcon-sensor/Chart.yaml b/helm-charts/falcon-sensor/Chart.yaml index 1fa71165..466534f5 100644 --- a/helm-charts/falcon-sensor/Chart.yaml +++ b/helm-charts/falcon-sensor/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.37.0-openshift.rc.1 +version: 1.36.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to From bdd7862578d5bd5f7d8f774bb86b3134cf22afcb Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:10:17 -0500 Subject: [PATCH 09/16] missing newline --- helm-charts/falcon-kac/templates/clusterrole.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm-charts/falcon-kac/templates/clusterrole.yaml b/helm-charts/falcon-kac/templates/clusterrole.yaml index 66b7a3f2..59d3cc74 100644 --- a/helm-charts/falcon-kac/templates/clusterrole.yaml +++ b/helm-charts/falcon-kac/templates/clusterrole.yaml @@ -105,4 +105,4 @@ rules: - {{ include "falcon-kac.sccName" . }} verbs: - use -{{- end }} \ No newline at end of file +{{- end }} From bc54eb46145915ef01b8d6dc4c1874b756fde5a6 Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 14:08:35 -0500 Subject: [PATCH 10/16] Move PSS labeling to testing only --- helm-charts/falcon-image-analyzer/README.md | 5 ++--- .../setup-namespace-labels.yaml} | 2 +- .../templates/tests/test-image-analyzer-running.yaml | 2 +- helm-charts/falcon-image-analyzer/values.schema.json | 9 --------- helm-charts/falcon-image-analyzer/values.yaml | 8 -------- helm-charts/falcon-sensor/README.md | 11 +---------- .../setup-namespace-labels.yaml} | 2 +- .../templates/tests/test-ds-sensor-running.yaml | 2 +- helm-charts/falcon-sensor/values.schema.json | 9 --------- helm-charts/falcon-sensor/values.yaml | 8 -------- 10 files changed, 7 insertions(+), 51 deletions(-) rename helm-charts/falcon-image-analyzer/templates/{namespace_labels.yaml => tests/setup-namespace-labels.yaml} (98%) rename helm-charts/falcon-sensor/templates/{namespace_labels.yaml => tests/setup-namespace-labels.yaml} (97%) diff --git a/helm-charts/falcon-image-analyzer/README.md b/helm-charts/falcon-image-analyzer/README.md index ff248266..a9d92e81 100644 --- a/helm-charts/falcon-image-analyzer/README.md +++ b/helm-charts/falcon-image-analyzer/README.md @@ -300,10 +300,9 @@ For a successful deployment, you will want to ensure that: Starting with Kubernetes 1.25, Pod Security Standards (PSS) are enforced via the Pod Security Admission (PSA) controller. Falcon Image Analyzer requires `privileged` PSS labels on its namespace because it accesses the container runtime socket (DaemonSet mode) or runs as root (Deployment mode). -Set `pss.manageNamespace: true` to have Helm apply the required labels automatically as part of install and upgrade. +Apply the required labels to the namespace before installing: -To apply the labels manually instead: -``` +```bash kubectl label --overwrite ns \ pod-security.kubernetes.io/enforce=privileged \ pod-security.kubernetes.io/warn=privileged \ diff --git a/helm-charts/falcon-image-analyzer/templates/namespace_labels.yaml b/helm-charts/falcon-image-analyzer/templates/tests/setup-namespace-labels.yaml similarity index 98% rename from helm-charts/falcon-image-analyzer/templates/namespace_labels.yaml rename to helm-charts/falcon-image-analyzer/templates/tests/setup-namespace-labels.yaml index 7598d04d..5702a6d6 100644 --- a/helm-charts/falcon-image-analyzer/templates/namespace_labels.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/setup-namespace-labels.yaml @@ -1,4 +1,4 @@ -{{- if .Values.pss.manageNamespace }} +{{- if .Values.testing.enabled }} --- apiVersion: v1 kind: ServiceAccount diff --git a/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml b/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml index 362cc022..667c376f 100644 --- a/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml @@ -171,7 +171,7 @@ spec: done fi - {{- if .Values.pss.manageNamespace }} + {{- if .Values.openshift.enabled }} echo "--- Checking PSS namespace labels ---" NS_NAME="{{ include "falcon-image-analyzer.namespace" . }}" for LABEL in "pod-security.kubernetes.io/enforce=privileged" "pod-security.kubernetes.io/warn=privileged" "pod-security.kubernetes.io/audit=privileged"; do diff --git a/helm-charts/falcon-image-analyzer/values.schema.json b/helm-charts/falcon-image-analyzer/values.schema.json index 03086490..7d57732e 100644 --- a/helm-charts/falcon-image-analyzer/values.schema.json +++ b/helm-charts/falcon-image-analyzer/values.schema.json @@ -255,15 +255,6 @@ } } }, - "pss": { - "type": "object", - "properties": { - "manageNamespace": { - "type": "boolean", - "default": false - } - } - }, "testing": { "type": "object", "properties": { diff --git a/helm-charts/falcon-image-analyzer/values.yaml b/helm-charts/falcon-image-analyzer/values.yaml index 889da1da..ac54dbeb 100644 --- a/helm-charts/falcon-image-analyzer/values.yaml +++ b/helm-charts/falcon-image-analyzer/values.yaml @@ -140,14 +140,6 @@ openshift: # Set createSCC: false and provide a name here to reference an existing SCC. sccName: "" -# Pod Security Standards (PSS) namespace labeling. -# PSS management is optional and independent of OpenShift. It can be enabled on any cluster. -# When enabled, Helm manages the install namespace and applies the labels required for the -# appropriate Pod Security Standard. -pss: - # Set to true to allow Helm to manage the install namespace PSS labels. - manageNamespace: false - # Define ImageAnalyzer POD DNS Policy, defaults to "ClusterFirstWithHostNet" when hostNetwork = true dnsPolicy: diff --git a/helm-charts/falcon-sensor/README.md b/helm-charts/falcon-sensor/README.md index 2a4df56b..4f8dd6ca 100644 --- a/helm-charts/falcon-sensor/README.md +++ b/helm-charts/falcon-sensor/README.md @@ -645,19 +645,10 @@ kubectl label namespace falcon-system \ | `node.openshift.enabled` | Enable OpenShift compatibility mode for the node DaemonSet | `false` | | `node.openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the DaemonSet service account the required privileges | `true` | | `node.openshift.sccName` | Name of the SCC to create or use. If empty, defaults to `-falcon-sensor-node-sensor` | `""` (auto-generated from release name) | -| `node.pss.manageNamespace` | Allow Helm to manage the install namespace and apply Pod Security Standard labels | `false` | ### Pod Security Standards (PSS) Namespace Labeling -Kubernetes 1.23+ enforces Pod Security Standards (PSS) which can block privileged pods like the Falcon node sensor. When `node.pss.manageNamespace=true`, Helm will manage the install namespace and apply the required `privileged` PSS labels automatically. - -**Option 1: Let Helm manage the namespace (recommended for new installations)** - -Set `node.pss.manageNamespace=true` to have Helm apply the required labels automatically. - -**Option 2: Manually label the namespace before installation** - -If you prefer to manage the namespace yourself or are installing into an existing namespace: +Kubernetes 1.23+ enforces Pod Security Standards (PSS) which can block privileged pods like the Falcon node sensor. Apply the required `privileged` PSS labels to the install namespace before installing: ```bash kubectl label namespace \ diff --git a/helm-charts/falcon-sensor/templates/namespace_labels.yaml b/helm-charts/falcon-sensor/templates/tests/setup-namespace-labels.yaml similarity index 97% rename from helm-charts/falcon-sensor/templates/namespace_labels.yaml rename to helm-charts/falcon-sensor/templates/tests/setup-namespace-labels.yaml index b0f03a50..ea1b40a8 100644 --- a/helm-charts/falcon-sensor/templates/namespace_labels.yaml +++ b/helm-charts/falcon-sensor/templates/tests/setup-namespace-labels.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.node.pss.manageNamespace .Values.node.enabled }} +{{- if and .Values.testing.enabled .Values.node.enabled }} --- apiVersion: v1 kind: ServiceAccount diff --git a/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml b/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml index 1ab787d5..22fce561 100644 --- a/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml +++ b/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml @@ -112,7 +112,7 @@ spec: done fi - {{- if .Values.node.pss.manageNamespace }} + {{- if .Values.node.openshift.enabled }} echo "--- Checking PSS namespace labels ---" NS_NAME="{{ include "falcon-sensor.namespace" . }}" for LABEL in "pod-security.kubernetes.io/enforce=privileged" "pod-security.kubernetes.io/warn=privileged" "pod-security.kubernetes.io/audit=privileged"; do diff --git a/helm-charts/falcon-sensor/values.schema.json b/helm-charts/falcon-sensor/values.schema.json index a2b3cb3e..810eb604 100644 --- a/helm-charts/falcon-sensor/values.schema.json +++ b/helm-charts/falcon-sensor/values.schema.json @@ -313,15 +313,6 @@ "default": "" } } - }, - "pss": { - "type": "object", - "properties": { - "manageNamespace": { - "type": "boolean", - "default": false - } - } } } }, diff --git a/helm-charts/falcon-sensor/values.yaml b/helm-charts/falcon-sensor/values.yaml index b3ead088..e349c254 100644 --- a/helm-charts/falcon-sensor/values.yaml +++ b/helm-charts/falcon-sensor/values.yaml @@ -125,14 +125,6 @@ node: # Name of the SCC to create or use. If empty, defaults to "-falcon-sensor-node-sensor" sccName: "" - # Pod Security Standards (PSS) namespace labeling. - # When enabled, Helm manages the install namespace and applies the labels required - # for the privileged Pod Security Standard. This is required for Kubernetes 1.23+ - # and suppresses PSA warnings on OpenShift. - pss: - # Set to true to allow Helm to manage the install namespace PSS labels. - manageNamespace: false - container: # When enabled, Helm chart deploys the Falcon Container Sensor to Pods through Webhooks enabled: false From ddf4bd554075402630e86ee60cc88e3932681ce8 Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 16:39:40 -0500 Subject: [PATCH 11/16] add global openshift vars --- .../falcon-image-analyzer/templates/_helpers.tpl | 14 ++++++++++++++ .../templates/cluster-role-read-access.yaml | 2 +- .../templates/daemonset.yaml | 2 +- .../templates/deployment.yaml | 2 +- .../falcon-image-analyzer/templates/scc.yaml | 2 +- .../templates/tests/setup-namespace-labels.yaml | 2 +- .../tests/test-cluster-permissions.yaml | 2 +- .../tests/test-image-analyzer-running.yaml | 2 +- .../templates/tests/test-openshift.yaml | 4 ++-- .../falcon-image-analyzer/values.schema.json | 4 ++++ helm-charts/falcon-image-analyzer/values.yaml | 7 +++++++ helm-charts/falcon-kac/templates/_helpers.tpl | 14 ++++++++++++++ .../falcon-kac/templates/clusterrole.yaml | 2 +- .../falcon-kac/templates/deployment_webhook.yaml | 2 +- helm-charts/falcon-kac/templates/scc.yaml | 2 +- .../tests/test-cluster-permissions.yaml | 2 +- .../templates/tests/test-openshift.yaml | 4 ++-- helm-charts/falcon-kac/values.yaml | 3 +++ helm-charts/falcon-platform/values.schema.json | 16 ++++++++++++++++ helm-charts/falcon-platform/values.yaml | 11 +++++++++++ helm-charts/falcon-sensor/templates/_helpers.tpl | 16 +++++++++++++++- .../falcon-sensor/templates/clusterrole.yaml | 2 +- .../falcon-sensor/templates/daemonset.yaml | 2 +- .../falcon-sensor/templates/node_cleanup.yaml | 2 +- helm-charts/falcon-sensor/templates/scc.yaml | 2 +- .../templates/tests/setup-namespace-labels.yaml | 2 +- .../tests/test-cluster-permissions.yaml | 2 +- .../templates/tests/test-ds-sensor-running.yaml | 2 +- .../templates/tests/test-openshift.yaml | 4 ++-- helm-charts/falcon-sensor/values.schema.json | 4 ++++ helm-charts/falcon-sensor/values.yaml | 7 +++++++ 31 files changed, 119 insertions(+), 25 deletions(-) diff --git a/helm-charts/falcon-image-analyzer/templates/_helpers.tpl b/helm-charts/falcon-image-analyzer/templates/_helpers.tpl index 5f20297f..0f7778fe 100644 --- a/helm-charts/falcon-image-analyzer/templates/_helpers.tpl +++ b/helm-charts/falcon-image-analyzer/templates/_helpers.tpl @@ -276,3 +276,17 @@ OpenShift SCC name. Uses openshift.sccName if set, otherwise defaults to the ful {{- include "falcon-image-analyzer.fullname" . -}} {{- end -}} {{- end -}} + +{{/* +OpenShift mode enabled — true if either chart-level or global is true. +*/}} +{{- define "falcon-image-analyzer.openshiftEnabled" -}} +{{- or .Values.openshift.enabled (default false .Values.global.openshift.enabled) -}} +{{- end -}} + +{{/* +OpenShift createSCC — false if either chart-level or global disables it. +*/}} +{{- define "falcon-image-analyzer.openshiftCreateSCC" -}} +{{- and .Values.openshift.createSCC .Values.global.openshift.createSCC -}} +{{- end -}} diff --git a/helm-charts/falcon-image-analyzer/templates/cluster-role-read-access.yaml b/helm-charts/falcon-image-analyzer/templates/cluster-role-read-access.yaml index c380cbca..a1efab22 100644 --- a/helm-charts/falcon-image-analyzer/templates/cluster-role-read-access.yaml +++ b/helm-charts/falcon-image-analyzer/templates/cluster-role-read-access.yaml @@ -17,7 +17,7 @@ rules: - get - watch - list -{{- if and .Values.openshift.enabled (not .Values.openshift.createSCC) .Values.openshift.sccName }} +{{- if and (include "falcon-image-analyzer.openshiftEnabled" . | eq "true") (not (include "falcon-image-analyzer.openshiftCreateSCC" . | eq "true")) .Values.openshift.sccName }} - apiGroups: - security.openshift.io resources: diff --git a/helm-charts/falcon-image-analyzer/templates/daemonset.yaml b/helm-charts/falcon-image-analyzer/templates/daemonset.yaml index ca931841..4d56908a 100644 --- a/helm-charts/falcon-image-analyzer/templates/daemonset.yaml +++ b/helm-charts/falcon-image-analyzer/templates/daemonset.yaml @@ -49,7 +49,7 @@ spec: metadata: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled - {{- if .Values.openshift.enabled }} + {{- if include "falcon-image-analyzer.openshiftEnabled" . | eq "true" }} openshift.io/scc: {{ include "falcon-image-analyzer.sccName" . }} {{- end }} {{- with .Values.podAnnotations }} diff --git a/helm-charts/falcon-image-analyzer/templates/deployment.yaml b/helm-charts/falcon-image-analyzer/templates/deployment.yaml index 1e97260c..5f27b0ef 100644 --- a/helm-charts/falcon-image-analyzer/templates/deployment.yaml +++ b/helm-charts/falcon-image-analyzer/templates/deployment.yaml @@ -50,7 +50,7 @@ spec: metadata: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled - {{- if .Values.openshift.enabled }} + {{- if include "falcon-image-analyzer.openshiftEnabled" . | eq "true" }} openshift.io/scc: {{ include "falcon-image-analyzer.sccName" . }} {{- end }} {{- with .Values.podAnnotations }} diff --git a/helm-charts/falcon-image-analyzer/templates/scc.yaml b/helm-charts/falcon-image-analyzer/templates/scc.yaml index 9587b68c..ace34a1e 100644 --- a/helm-charts/falcon-image-analyzer/templates/scc.yaml +++ b/helm-charts/falcon-image-analyzer/templates/scc.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.openshift.enabled .Values.openshift.createSCC }} +{{- if and (include "falcon-image-analyzer.openshiftEnabled" . | eq "true") (include "falcon-image-analyzer.openshiftCreateSCC" . | eq "true") }} apiVersion: security.openshift.io/v1 kind: SecurityContextConstraints metadata: diff --git a/helm-charts/falcon-image-analyzer/templates/tests/setup-namespace-labels.yaml b/helm-charts/falcon-image-analyzer/templates/tests/setup-namespace-labels.yaml index 5702a6d6..2b7b59ea 100644 --- a/helm-charts/falcon-image-analyzer/templates/tests/setup-namespace-labels.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/setup-namespace-labels.yaml @@ -1,4 +1,4 @@ -{{- if .Values.testing.enabled }} +{{- if .Values.testing.labelNamespace }} --- apiVersion: v1 kind: ServiceAccount diff --git a/helm-charts/falcon-image-analyzer/templates/tests/test-cluster-permissions.yaml b/helm-charts/falcon-image-analyzer/templates/tests/test-cluster-permissions.yaml index 8f5416fd..7b93f567 100644 --- a/helm-charts/falcon-image-analyzer/templates/tests/test-cluster-permissions.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/test-cluster-permissions.yaml @@ -43,7 +43,7 @@ rules: verbs: - get - list -{{- if .Values.openshift.enabled }} +{{- if (include "falcon-image-analyzer.openshiftEnabled" . | eq "true") }} - apiGroups: - security.openshift.io resources: diff --git a/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml b/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml index 667c376f..045ff929 100644 --- a/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/test-image-analyzer-running.yaml @@ -171,7 +171,7 @@ spec: done fi - {{- if .Values.openshift.enabled }} + {{- if .Values.testing.labelNamespace }} echo "--- Checking PSS namespace labels ---" NS_NAME="{{ include "falcon-image-analyzer.namespace" . }}" for LABEL in "pod-security.kubernetes.io/enforce=privileged" "pod-security.kubernetes.io/warn=privileged" "pod-security.kubernetes.io/audit=privileged"; do diff --git a/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml b/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml index 74793c3a..bf672d07 100644 --- a/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml +++ b/helm-charts/falcon-image-analyzer/templates/tests/test-openshift.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.testing.enabled .Values.openshift.enabled }} +{{- if and .Values.testing.enabled (include "falcon-image-analyzer.openshiftEnabled" . | eq "true") }} apiVersion: v1 kind: Pod metadata: @@ -23,7 +23,7 @@ spec: - | FAILED=0 - {{- if .Values.openshift.createSCC }} + {{- if (include "falcon-image-analyzer.openshiftCreateSCC" . | eq "true") }} echo "--- Checking SCC exists ---" if ! kubectl get scc "{{ include "falcon-image-analyzer.sccName" . }}" > /dev/null 2>&1; then echo "[FAIL]: SCC '{{ include "falcon-image-analyzer.sccName" . }}' not found" diff --git a/helm-charts/falcon-image-analyzer/values.schema.json b/helm-charts/falcon-image-analyzer/values.schema.json index 7d57732e..c4a4eaa8 100644 --- a/helm-charts/falcon-image-analyzer/values.schema.json +++ b/helm-charts/falcon-image-analyzer/values.schema.json @@ -261,6 +261,10 @@ "enabled": { "type": "boolean", "default": false + }, + "labelNamespace": { + "type": "boolean", + "default": false } } } diff --git a/helm-charts/falcon-image-analyzer/values.yaml b/helm-charts/falcon-image-analyzer/values.yaml index ac54dbeb..b49e712f 100644 --- a/helm-charts/falcon-image-analyzer/values.yaml +++ b/helm-charts/falcon-image-analyzer/values.yaml @@ -245,7 +245,14 @@ global: containerRegistry: pullSecret: "" configJSON: "" + openshift: + enabled: false + createSCC: true # Deploys the test suite during install for testing purposes. testing: enabled: false + # Set to true to apply privileged PSS labels to the install namespace as a + # pre-install hook. Requires outbound access to docker.io. Not suitable for + # air-gapped or registry-restricted environments. + labelNamespace: false diff --git a/helm-charts/falcon-kac/templates/_helpers.tpl b/helm-charts/falcon-kac/templates/_helpers.tpl index 19a6efd5..50338e93 100644 --- a/helm-charts/falcon-kac/templates/_helpers.tpl +++ b/helm-charts/falcon-kac/templates/_helpers.tpl @@ -242,3 +242,17 @@ OpenShift SCC name. Uses openshift.sccName if set, otherwise defaults to the ful {{- include "falcon-kac.fullname" . -}} {{- end -}} {{- end -}} + +{{/* +OpenShift mode enabled — true if either chart-level or global is true. +*/}} +{{- define "falcon-kac.openshiftEnabled" -}} +{{- or .Values.openshift.enabled (default false .Values.global.openshift.enabled) -}} +{{- end -}} + +{{/* +OpenShift createSCC — false if either chart-level or global disables it. +*/}} +{{- define "falcon-kac.openshiftCreateSCC" -}} +{{- and .Values.openshift.createSCC .Values.global.openshift.createSCC -}} +{{- end -}} diff --git a/helm-charts/falcon-kac/templates/clusterrole.yaml b/helm-charts/falcon-kac/templates/clusterrole.yaml index 59d3cc74..554bdc9c 100644 --- a/helm-charts/falcon-kac/templates/clusterrole.yaml +++ b/helm-charts/falcon-kac/templates/clusterrole.yaml @@ -96,7 +96,7 @@ rules: - get - list - watch -{{- if and .Values.openshift.enabled (not .Values.openshift.createSCC) .Values.openshift.sccName }} +{{- if and (include "falcon-kac.openshiftEnabled" . | eq "true") (not (include "falcon-kac.openshiftCreateSCC" . | eq "true")) .Values.openshift.sccName }} - apiGroups: - security.openshift.io resources: diff --git a/helm-charts/falcon-kac/templates/deployment_webhook.yaml b/helm-charts/falcon-kac/templates/deployment_webhook.yaml index 8cb054ab..efb02b42 100644 --- a/helm-charts/falcon-kac/templates/deployment_webhook.yaml +++ b/helm-charts/falcon-kac/templates/deployment_webhook.yaml @@ -87,7 +87,7 @@ spec: annotations: sensor.falcon-system.crowdstrike.com/injection: disabled checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | quote }} - {{- if and .Values.openshift.enabled .Values.hostNetwork }} + {{- if and (include "falcon-kac.openshiftEnabled" . | eq "true") .Values.hostNetwork }} openshift.io/scc: {{ include "falcon-kac.sccName" . }} {{- end }} {{- if or (.Values.autoDeploymentUpdate) (.Values.podAnnotations) }} diff --git a/helm-charts/falcon-kac/templates/scc.yaml b/helm-charts/falcon-kac/templates/scc.yaml index a06f5d0c..09f6438c 100644 --- a/helm-charts/falcon-kac/templates/scc.yaml +++ b/helm-charts/falcon-kac/templates/scc.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.openshift.enabled .Values.openshift.createSCC .Values.hostNetwork }} +{{- if and (include "falcon-kac.openshiftEnabled" . | eq "true") (include "falcon-kac.openshiftCreateSCC" . | eq "true") .Values.hostNetwork }} apiVersion: security.openshift.io/v1 kind: SecurityContextConstraints metadata: diff --git a/helm-charts/falcon-kac/templates/tests/test-cluster-permissions.yaml b/helm-charts/falcon-kac/templates/tests/test-cluster-permissions.yaml index 67daa745..5daddbb1 100644 --- a/helm-charts/falcon-kac/templates/tests/test-cluster-permissions.yaml +++ b/helm-charts/falcon-kac/templates/tests/test-cluster-permissions.yaml @@ -49,7 +49,7 @@ rules: verbs: - get - list -{{- if .Values.openshift.enabled }} +{{- if (include "falcon-kac.openshiftEnabled" . | eq "true") }} - apiGroups: - security.openshift.io resources: diff --git a/helm-charts/falcon-kac/templates/tests/test-openshift.yaml b/helm-charts/falcon-kac/templates/tests/test-openshift.yaml index 2bd3a844..66a9c747 100644 --- a/helm-charts/falcon-kac/templates/tests/test-openshift.yaml +++ b/helm-charts/falcon-kac/templates/tests/test-openshift.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.testing.enabled .Values.openshift.enabled }} +{{- if and .Values.testing.enabled (include "falcon-kac.openshiftEnabled" . | eq "true") }} apiVersion: v1 kind: Pod metadata: @@ -19,7 +19,7 @@ spec: - | FAILED=0 - {{- if and .Values.openshift.createSCC .Values.hostNetwork }} + {{- if and (include "falcon-kac.openshiftCreateSCC" . | eq "true") .Values.hostNetwork }} echo "--- Checking SCC exists ---" if ! kubectl get scc "{{ include "falcon-kac.sccName" . }}" > /dev/null 2>&1; then echo "[FAIL]: SCC '{{ include "falcon-kac.sccName" . }}' not found" diff --git a/helm-charts/falcon-kac/values.yaml b/helm-charts/falcon-kac/values.yaml index afe638df..fbbdf850 100644 --- a/helm-charts/falcon-kac/values.yaml +++ b/helm-charts/falcon-kac/values.yaml @@ -217,6 +217,9 @@ global: containerRegistry: pullSecret: "" configJSON: "" + openshift: + enabled: false + createSCC: true # Deploys the test suite during install for testing purposes. testing: diff --git a/helm-charts/falcon-platform/values.schema.json b/helm-charts/falcon-platform/values.schema.json index 8e05428c..a9a47199 100644 --- a/helm-charts/falcon-platform/values.schema.json +++ b/helm-charts/falcon-platform/values.schema.json @@ -59,6 +59,22 @@ "description": "Base64 encoded docker config json for accessing private registries" } } + }, + "openshift": { + "type": "object", + "description": "Global OpenShift compatibility configuration applied to all Falcon components", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable OpenShift compatibility mode for all components", + "default": false + }, + "createSCC": { + "type": "boolean", + "description": "Create SecurityContextConstraints resources. Set to false to manage SCCs outside of Helm.", + "default": true + } + } } } }, diff --git a/helm-charts/falcon-platform/values.yaml b/helm-charts/falcon-platform/values.yaml index cce434c7..f4142d14 100644 --- a/helm-charts/falcon-platform/values.yaml +++ b/helm-charts/falcon-platform/values.yaml @@ -37,6 +37,17 @@ global: # $ cat ~/.docker/config.json | base64 - configJSON: "" + # OpenShift compatibility configuration. + # When enabled, each sub-chart will create the SecurityContextConstraints resource required + # for its workload. Chart-level openshift values take precedence over these globals. + # NOTE: OpenShift is not a recommended configuration. The official Red Hat certified + # CrowdStrike Falcon Operator is the recommended installation method for OpenShift clusters. + openshift: + # Set to true to enable OpenShift compatibility mode for all Falcon components. + enabled: false + # Set to false to manage SecurityContextConstraints resources outside of Helm. + createSCC: true + # Enable/disable individual components # Set enabled: true to deploy, enabled: false to skip diff --git a/helm-charts/falcon-sensor/templates/_helpers.tpl b/helm-charts/falcon-sensor/templates/_helpers.tpl index 4735e878..d88e129d 100644 --- a/helm-charts/falcon-sensor/templates/_helpers.tpl +++ b/helm-charts/falcon-sensor/templates/_helpers.tpl @@ -349,11 +349,25 @@ OpenShift SCC name for the node DaemonSet. {{- end -}} {{- end -}} +{{/* +OpenShift mode enabled — true if either chart-level or global is true. +*/}} +{{- define "falcon-sensor.openshiftEnabled" -}} +{{- or .Values.node.openshift.enabled (default false .Values.global.openshift.enabled) -}} +{{- end -}} + +{{/* +OpenShift createSCC — false if either chart-level or global disables it. +*/}} +{{- define "falcon-sensor.openshiftCreateSCC" -}} +{{- and .Values.node.openshift.createSCC .Values.global.openshift.createSCC -}} +{{- end -}} + {{/* Validate OpenShift configuration: container sensor is not supported in OpenShift mode. */}} {{- define "falcon-sensor.validateOpenshiftConfig" -}} -{{- if and .Values.node.openshift.enabled .Values.container.enabled -}} +{{- if and (include "falcon-sensor.openshiftEnabled" .) .Values.container.enabled -}} {{- fail "OpenShift mode (node.openshift.enabled) is only supported with the node DaemonSet. The container sensor (container.enabled) is not supported on OpenShift. Use the official Red Hat certified operator instead." -}} {{- end -}} {{- end -}} diff --git a/helm-charts/falcon-sensor/templates/clusterrole.yaml b/helm-charts/falcon-sensor/templates/clusterrole.yaml index a373a792..498b3401 100644 --- a/helm-charts/falcon-sensor/templates/clusterrole.yaml +++ b/helm-charts/falcon-sensor/templates/clusterrole.yaml @@ -39,7 +39,7 @@ rules: - watch - list {{- end }} -{{- if and .Values.node.openshift.enabled (not .Values.node.openshift.createSCC) .Values.node.openshift.sccName }} +{{- if and (include "falcon-sensor.openshiftEnabled" . | eq "true") (not (include "falcon-sensor.openshiftCreateSCC" . | eq "true")) .Values.node.openshift.sccName }} - apiGroups: - security.openshift.io resources: diff --git a/helm-charts/falcon-sensor/templates/daemonset.yaml b/helm-charts/falcon-sensor/templates/daemonset.yaml index d0fde5c3..4d2e9d93 100644 --- a/helm-charts/falcon-sensor/templates/daemonset.yaml +++ b/helm-charts/falcon-sensor/templates/daemonset.yaml @@ -43,7 +43,7 @@ spec: metadata: annotations: {{ .Values.node.daemonset.podAnnotationKey }}: disabled - {{- if .Values.node.openshift.enabled }} + {{- if include "falcon-sensor.openshiftEnabled" . | eq "true" }} openshift.io/scc: {{ include "falcon-sensor.sccName" . }} {{- end }} {{- range $key, $value := .Values.node.podAnnotations }} diff --git a/helm-charts/falcon-sensor/templates/node_cleanup.yaml b/helm-charts/falcon-sensor/templates/node_cleanup.yaml index 901ef8ea..7178b910 100644 --- a/helm-charts/falcon-sensor/templates/node_cleanup.yaml +++ b/helm-charts/falcon-sensor/templates/node_cleanup.yaml @@ -41,7 +41,7 @@ spec: metadata: annotations: {{ .Values.node.daemonset.podAnnotationKey }}: disabled - {{- if .Values.node.openshift.enabled }} + {{- if include "falcon-sensor.openshiftEnabled" . | eq "true" }} openshift.io/scc: {{ include "falcon-sensor.sccName" . }} {{- end }} {{- range $key, $value := .Values.node.podAnnotations }} diff --git a/helm-charts/falcon-sensor/templates/scc.yaml b/helm-charts/falcon-sensor/templates/scc.yaml index 76cbee81..bbcd96c5 100644 --- a/helm-charts/falcon-sensor/templates/scc.yaml +++ b/helm-charts/falcon-sensor/templates/scc.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.node.enabled .Values.node.openshift.enabled .Values.node.openshift.createSCC }} +{{- if and .Values.node.enabled (include "falcon-sensor.openshiftEnabled" . | eq "true") (include "falcon-sensor.openshiftCreateSCC" . | eq "true") }} # NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator # (https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) is the # recommended installation method for OpenShift clusters. diff --git a/helm-charts/falcon-sensor/templates/tests/setup-namespace-labels.yaml b/helm-charts/falcon-sensor/templates/tests/setup-namespace-labels.yaml index ea1b40a8..c16bd2bc 100644 --- a/helm-charts/falcon-sensor/templates/tests/setup-namespace-labels.yaml +++ b/helm-charts/falcon-sensor/templates/tests/setup-namespace-labels.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.testing.enabled .Values.node.enabled }} +{{- if and .Values.testing.labelNamespace .Values.node.enabled }} --- apiVersion: v1 kind: ServiceAccount diff --git a/helm-charts/falcon-sensor/templates/tests/test-cluster-permissions.yaml b/helm-charts/falcon-sensor/templates/tests/test-cluster-permissions.yaml index b8e3ec29..bb03b520 100644 --- a/helm-charts/falcon-sensor/templates/tests/test-cluster-permissions.yaml +++ b/helm-charts/falcon-sensor/templates/tests/test-cluster-permissions.yaml @@ -51,7 +51,7 @@ rules: verbs: - get - list -{{- if .Values.node.openshift.enabled }} +{{- if (include "falcon-sensor.openshiftEnabled" . | eq "true") }} - apiGroups: - security.openshift.io resources: diff --git a/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml b/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml index 22fce561..478b0865 100644 --- a/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml +++ b/helm-charts/falcon-sensor/templates/tests/test-ds-sensor-running.yaml @@ -112,7 +112,7 @@ spec: done fi - {{- if .Values.node.openshift.enabled }} + {{- if .Values.testing.labelNamespace }} echo "--- Checking PSS namespace labels ---" NS_NAME="{{ include "falcon-sensor.namespace" . }}" for LABEL in "pod-security.kubernetes.io/enforce=privileged" "pod-security.kubernetes.io/warn=privileged" "pod-security.kubernetes.io/audit=privileged"; do diff --git a/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml b/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml index 13c9bd2c..7ac82c74 100644 --- a/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml +++ b/helm-charts/falcon-sensor/templates/tests/test-openshift.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.testing.enabled .Values.node.enabled .Values.node.openshift.enabled }} +{{- if and .Values.testing.enabled .Values.node.enabled (include "falcon-sensor.openshiftEnabled" . | eq "true") }} apiVersion: v1 kind: Pod metadata: @@ -19,7 +19,7 @@ spec: - | FAILED=0 - {{- if .Values.node.openshift.createSCC }} + {{- if (include "falcon-sensor.openshiftCreateSCC" . | eq "true") }} echo "--- Checking SCC exists ---" if ! kubectl get scc "{{ include "falcon-sensor.sccName" . }}" > /dev/null 2>&1; then echo "[FAIL]: SCC '{{ include "falcon-sensor.sccName" . }}' not found" diff --git a/helm-charts/falcon-sensor/values.schema.json b/helm-charts/falcon-sensor/values.schema.json index 810eb604..18306a2d 100644 --- a/helm-charts/falcon-sensor/values.schema.json +++ b/helm-charts/falcon-sensor/values.schema.json @@ -579,6 +579,10 @@ "enabled": { "type": "boolean", "default": "false" + }, + "labelNamespace": { + "type": "boolean", + "default": false } } }, diff --git a/helm-charts/falcon-sensor/values.yaml b/helm-charts/falcon-sensor/values.yaml index e349c254..44bccb0b 100644 --- a/helm-charts/falcon-sensor/values.yaml +++ b/helm-charts/falcon-sensor/values.yaml @@ -303,6 +303,10 @@ serviceAccount: # Deploys the test suite during install for testing purposes. testing: enabled: false + # Set to true to apply privileged PSS labels to the install namespace as a + # pre-install hook. Requires outbound access to docker.io. Not suitable for + # air-gapped or registry-restricted environments. + labelNamespace: false # falcon.cid is required unless falconSecret.enabled is true and FALCONCTL_OPT_CID is already defined in an existing secret. falcon: @@ -337,3 +341,6 @@ global: containerRegistry: pullSecret: "" configJSON: "" + openshift: + enabled: false + createSCC: true From 02bd44be4dee2976aa3aba16e8806f81c7d1aeca Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 16:49:10 -0500 Subject: [PATCH 12/16] update documentation gaps --- helm-charts/falcon-image-analyzer/README.md | 13 +++++++++++++ helm-charts/falcon-kac/README.md | 11 +++++++++++ helm-charts/falcon-platform/README.md | 2 ++ helm-charts/falcon-sensor/README.md | 13 +++++++++++++ 4 files changed, 39 insertions(+) diff --git a/helm-charts/falcon-image-analyzer/README.md b/helm-charts/falcon-image-analyzer/README.md index a9d92e81..14ecd10b 100644 --- a/helm-charts/falcon-image-analyzer/README.md +++ b/helm-charts/falcon-image-analyzer/README.md @@ -309,6 +309,8 @@ kubectl label --overwrite ns \ pod-security.kubernetes.io/audit=privileged ``` +In automated testing environments, set `testing.labelNamespace: true` to apply these labels automatically via a pre-install Job. This requires outbound access to `docker.io` and is not suitable for air-gapped or registry-restricted environments. + ### OpenShift Compatibility > **Note:** OpenShift is **not a recommended** configuration for this Helm chart. The @@ -343,6 +345,17 @@ service account. | `openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the workload the required privileges for the active workload mode | `true` | | `openshift.sccName` | Name of the SCC to create or use. If empty, defaults to the release fullname | `""` (auto-generated) | +### Global OpenShift Override (falcon-platform only) + +When deploying via the `falcon-platform` umbrella chart, the `global.openshift` values enable OpenShift compatibility for all components from a single location: + +| Parameter | Description | Default | +|:-----------------------------|:-------------------------------------------------------------------------------------|:--------| +| `global.openshift.enabled` | Enable OpenShift compatibility mode for all Falcon components | `false` | +| `global.openshift.createSCC` | Create SCCs for all components. Set to `false` to manage SCCs outside of Helm | `true` | + +Chart-level `openshift.*` values take precedence and can override the global values for per-component control. + ### Temp Volume Mount In order to perform image scan, IAR will pull the image and un-compress it for traversal through layers and image config and manifest. For this, IAR will use a temp space that is added as a mount of type `emptyDir` . The idea of the storage here is to accommodate the max size image that one could run in the kubernetes. diff --git a/helm-charts/falcon-kac/README.md b/helm-charts/falcon-kac/README.md index 70da88d1..d557a7ff 100644 --- a/helm-charts/falcon-kac/README.md +++ b/helm-charts/falcon-kac/README.md @@ -176,6 +176,17 @@ installing. | `openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the Deployment service account host network access | `true` | | `openshift.sccName` | Name of the SCC to create or use. If empty, defaults to the release fullname | `""` (auto-generated) | +### Global OpenShift Override (falcon-platform only) + +When deploying via the `falcon-platform` umbrella chart, the `global.openshift` values enable OpenShift compatibility for all components from a single location: + +| Parameter | Description | Default | +|:-----------------------------|:-------------------------------------------------------------------------------------|:--------| +| `global.openshift.enabled` | Enable OpenShift compatibility mode for all Falcon components | `false` | +| `global.openshift.createSCC` | Create SCCs for all components. Set to `false` to manage SCCs outside of Helm | `true` | + +Chart-level `openshift.*` values take precedence and can override the global values for per-component control. + ## Update Falcon KAC When a new container image is available, you can update your Falcon KAC by passing the new container image to the Helm diff --git a/helm-charts/falcon-platform/README.md b/helm-charts/falcon-platform/README.md index 7df63d71..f3d34fd9 100644 --- a/helm-charts/falcon-platform/README.md +++ b/helm-charts/falcon-platform/README.md @@ -333,6 +333,8 @@ Global settings apply to all components unless component specific values are set | global.falconSecret.secretName | "" | Name of existing Kubernetes secret with sensitive data necessary for Falcon component installation | | global.containerRegistry.configJSON | "" | Your container registry config json as a base64 encoded string | | global.containerRegistry.pullSecret | "" | Name of existing container registry pull secret as an alternative to `registryConfigJSON` | +| global.openshift.enabled | false | Enable OpenShift compatibility mode for all Falcon components | +| global.openshift.createSCC | true | Create SecurityContextConstraints resources. Set to `false` to manage SCCs outside of Helm | > [!NOTE] Any existing secrets for `falconSecret` or `containerRegistry.pullSecret` must exist in the namespace dedicated to the respective Falcon component before installing the Helm chart. For example, you must already have an existing secret matching `global.falconSecret.secretName` in the `falcon-sensor` default namespace, or custom namespace you choose for your `falcon-sensor.namespaceOverride`. diff --git a/helm-charts/falcon-sensor/README.md b/helm-charts/falcon-sensor/README.md index 4f8dd6ca..1e1e5a7f 100644 --- a/helm-charts/falcon-sensor/README.md +++ b/helm-charts/falcon-sensor/README.md @@ -646,6 +646,17 @@ kubectl label namespace falcon-system \ | `node.openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the DaemonSet service account the required privileges | `true` | | `node.openshift.sccName` | Name of the SCC to create or use. If empty, defaults to `-falcon-sensor-node-sensor` | `""` (auto-generated from release name) | +### Global OpenShift Override (falcon-platform only) + +When deploying via the `falcon-platform` umbrella chart, the `global.openshift` values enable OpenShift compatibility for all components from a single location: + +| Parameter | Description | Default | +|:-----------------------------|:-------------------------------------------------------------------------------------|:--------| +| `global.openshift.enabled` | Enable OpenShift compatibility mode for all Falcon components | `false` | +| `global.openshift.createSCC` | Create SCCs for all components. Set to `false` to manage SCCs outside of Helm | `true` | + +Chart-level `node.openshift.*` values take precedence and can override the global values for per-component control. + ### Pod Security Standards (PSS) Namespace Labeling Kubernetes 1.23+ enforces Pod Security Standards (PSS) which can block privileged pods like the Falcon node sensor. Apply the required `privileged` PSS labels to the install namespace before installing: @@ -657,6 +668,8 @@ kubectl label namespace \ pod-security.kubernetes.io/audit=privileged ``` +In automated testing environments, set `testing.labelNamespace: true` to apply these labels automatically via a pre-install Job. This requires outbound access to `docker.io` and is not suitable for air-gapped or registry-restricted environments. + ### Installing on OpenShift Set `node.openshift.enabled=true` to enable OpenShift compatibility mode. The chart will automatically create and manage the required SCC unless `node.openshift.createSCC=false` is set. From fa85961c94da69d70139b3db7867ec0115a2a323 Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Tue, 9 Jun 2026 16:58:54 -0500 Subject: [PATCH 13/16] resolve comments --- helm-charts/falcon-sensor/templates/_helpers.tpl | 2 +- helm-charts/falcon-sensor/templates/scc.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm-charts/falcon-sensor/templates/_helpers.tpl b/helm-charts/falcon-sensor/templates/_helpers.tpl index d88e129d..ec17bb7e 100644 --- a/helm-charts/falcon-sensor/templates/_helpers.tpl +++ b/helm-charts/falcon-sensor/templates/_helpers.tpl @@ -368,6 +368,6 @@ Validate OpenShift configuration: container sensor is not supported in OpenShift */}} {{- define "falcon-sensor.validateOpenshiftConfig" -}} {{- if and (include "falcon-sensor.openshiftEnabled" .) .Values.container.enabled -}} -{{- fail "OpenShift mode (node.openshift.enabled) is only supported with the node DaemonSet. The container sensor (container.enabled) is not supported on OpenShift. Use the official Red Hat certified operator instead." -}} +{{- fail "OpenShift mode (node.openshift.enabled) is only supported with the node DaemonSet. The container sensor (container.enabled) is not fully supported on OpenShift." -}} {{- end -}} {{- end -}} diff --git a/helm-charts/falcon-sensor/templates/scc.yaml b/helm-charts/falcon-sensor/templates/scc.yaml index bbcd96c5..64563860 100644 --- a/helm-charts/falcon-sensor/templates/scc.yaml +++ b/helm-charts/falcon-sensor/templates/scc.yaml @@ -1,5 +1,5 @@ {{- if and .Values.node.enabled (include "falcon-sensor.openshiftEnabled" . | eq "true") (include "falcon-sensor.openshiftCreateSCC" . | eq "true") }} -# NOTE: OpenShift is NOT A RECOMMENDED configuration. The official Red Hat certified operator +# NOTE: Helm on an OpenShift cluster is NOT THE RECOMMENDED configuration. The official Red Hat certified falcon-operator # (https://catalog.redhat.com/en/software/container-stacks/detail/62f2d38f76d039249424703d) is the # recommended installation method for OpenShift clusters. apiVersion: security.openshift.io/v1 @@ -12,9 +12,9 @@ metadata: kubernetes.io/description: >- Grants the Falcon node sensor DaemonSet the privileges required to monitor and protect cluster nodes. This SCC is required because the Falcon sensor - runs as a privileged process in the host's kernel. OpenShift is not a - recommended configuration; use the official Red Hat certified operator for - production deployments. + runs as a privileged process in the host's kernel. Using the falcon-helm + charts on OpenShift is not the recommended configuration; use the official + Red Hat certified operator for production deployments. allowHostDirVolumePlugin: true allowHostIPC: true allowHostNetwork: true From 4943fca3d4246560df52ac1f098f196098017606 Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Wed, 10 Jun 2026 09:49:41 -0500 Subject: [PATCH 14/16] revert chart lock --- helm-charts/falcon-platform/Chart.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm-charts/falcon-platform/Chart.lock b/helm-charts/falcon-platform/Chart.lock index f25431ad..04fffa2d 100644 --- a/helm-charts/falcon-platform/Chart.lock +++ b/helm-charts/falcon-platform/Chart.lock @@ -9,4 +9,4 @@ dependencies: repository: file://../falcon-image-analyzer version: 1.1.20 digest: sha256:df5d3f9047c9ae430112c5c69860afc7f9a27771590ea9a872e85cd8ae27ae11 -generated: "2026-06-09T12:00:33.86277-05:00" +generated: "2026-05-05T10:37:59.520948-04:00" From 44a94300bf9b3fe953f1f8dc986631e248989207 Mon Sep 17 00:00:00 2001 From: Greg Pontejos <242696964+gpontejos-cs@users.noreply.github.com> Date: Wed, 10 Jun 2026 13:40:57 -0500 Subject: [PATCH 15/16] resolving comments --- helm-charts/falcon-image-analyzer/README.md | 11 ----------- helm-charts/falcon-kac/README.md | 11 ----------- helm-charts/falcon-sensor/README.md | 11 ----------- 3 files changed, 33 deletions(-) diff --git a/helm-charts/falcon-image-analyzer/README.md b/helm-charts/falcon-image-analyzer/README.md index 14ecd10b..e0ae7109 100644 --- a/helm-charts/falcon-image-analyzer/README.md +++ b/helm-charts/falcon-image-analyzer/README.md @@ -345,17 +345,6 @@ service account. | `openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the workload the required privileges for the active workload mode | `true` | | `openshift.sccName` | Name of the SCC to create or use. If empty, defaults to the release fullname | `""` (auto-generated) | -### Global OpenShift Override (falcon-platform only) - -When deploying via the `falcon-platform` umbrella chart, the `global.openshift` values enable OpenShift compatibility for all components from a single location: - -| Parameter | Description | Default | -|:-----------------------------|:-------------------------------------------------------------------------------------|:--------| -| `global.openshift.enabled` | Enable OpenShift compatibility mode for all Falcon components | `false` | -| `global.openshift.createSCC` | Create SCCs for all components. Set to `false` to manage SCCs outside of Helm | `true` | - -Chart-level `openshift.*` values take precedence and can override the global values for per-component control. - ### Temp Volume Mount In order to perform image scan, IAR will pull the image and un-compress it for traversal through layers and image config and manifest. For this, IAR will use a temp space that is added as a mount of type `emptyDir` . The idea of the storage here is to accommodate the max size image that one could run in the kubernetes. diff --git a/helm-charts/falcon-kac/README.md b/helm-charts/falcon-kac/README.md index d557a7ff..70da88d1 100644 --- a/helm-charts/falcon-kac/README.md +++ b/helm-charts/falcon-kac/README.md @@ -176,17 +176,6 @@ installing. | `openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the Deployment service account host network access | `true` | | `openshift.sccName` | Name of the SCC to create or use. If empty, defaults to the release fullname | `""` (auto-generated) | -### Global OpenShift Override (falcon-platform only) - -When deploying via the `falcon-platform` umbrella chart, the `global.openshift` values enable OpenShift compatibility for all components from a single location: - -| Parameter | Description | Default | -|:-----------------------------|:-------------------------------------------------------------------------------------|:--------| -| `global.openshift.enabled` | Enable OpenShift compatibility mode for all Falcon components | `false` | -| `global.openshift.createSCC` | Create SCCs for all components. Set to `false` to manage SCCs outside of Helm | `true` | - -Chart-level `openshift.*` values take precedence and can override the global values for per-component control. - ## Update Falcon KAC When a new container image is available, you can update your Falcon KAC by passing the new container image to the Helm diff --git a/helm-charts/falcon-sensor/README.md b/helm-charts/falcon-sensor/README.md index 1e1e5a7f..46421ce7 100644 --- a/helm-charts/falcon-sensor/README.md +++ b/helm-charts/falcon-sensor/README.md @@ -646,17 +646,6 @@ kubectl label namespace falcon-system \ | `node.openshift.createSCC` | Create a `SecurityContextConstraints` resource granting the DaemonSet service account the required privileges | `true` | | `node.openshift.sccName` | Name of the SCC to create or use. If empty, defaults to `-falcon-sensor-node-sensor` | `""` (auto-generated from release name) | -### Global OpenShift Override (falcon-platform only) - -When deploying via the `falcon-platform` umbrella chart, the `global.openshift` values enable OpenShift compatibility for all components from a single location: - -| Parameter | Description | Default | -|:-----------------------------|:-------------------------------------------------------------------------------------|:--------| -| `global.openshift.enabled` | Enable OpenShift compatibility mode for all Falcon components | `false` | -| `global.openshift.createSCC` | Create SCCs for all components. Set to `false` to manage SCCs outside of Helm | `true` | - -Chart-level `node.openshift.*` values take precedence and can override the global values for per-component control. - ### Pod Security Standards (PSS) Namespace Labeling Kubernetes 1.23+ enforces Pod Security Standards (PSS) which can block privileged pods like the Falcon node sensor. Apply the required `privileged` PSS labels to the install namespace before installing: From b2b58520e833984a7de0c62238af87be9c663d3b Mon Sep 17 00:00:00 2001 From: gpontejos-cs <242696964+gpontejos-cs@users.noreply.github.com> Date: Wed, 10 Jun 2026 13:41:38 -0500 Subject: [PATCH 16/16] Update helm-charts/falcon-image-analyzer/README.md Co-authored-by: Jung Choi <17916440+mr-jungchoi@users.noreply.github.com> --- helm-charts/falcon-image-analyzer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm-charts/falcon-image-analyzer/README.md b/helm-charts/falcon-image-analyzer/README.md index e0ae7109..5d9762cd 100644 --- a/helm-charts/falcon-image-analyzer/README.md +++ b/helm-charts/falcon-image-analyzer/README.md @@ -326,7 +326,7 @@ The required privileges differ depending on which workload mode is enabled: - **Deployment mode** (`deployment.enabled: true`): Requires only permission to run as root (UID 0) with all capabilities dropped. No host access is needed. -Set `openshift.enabled: true` to have the chart create the appropriate SCC automatically. The SCC grants only the +Set `openshift.enabled: true` and `openshift.createSCC: true` to have the chart create the appropriate SCC automatically. The SCC grants only the minimum permissions required for the active workload mode. The SCC is managed as a standard Helm release resource and will be created on install and removed on uninstall.