From 05cee51acaf51c9ced906016456f89e444585708 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 14:31:16 -0500 Subject: [PATCH 01/33] Revised initial commit for cluster hardening leveraging the compliance operator and existing scan profiles. This app is loaded first by Argo based on leveraging sync-wave annotation in the values-hub.yaml --- charts/compliance-scanning/Chart.yaml | 11 ++++ .../templates/_helpers.tpl | 61 +++++++++++++++++++ charts/compliance-scanning/templates/pvc.yaml | 20 ++++++ .../templates/results-viewer-pod.yaml | 46 ++++++++++++++ .../templates/scan-setting-binding.yaml | 27 ++++++++ .../templates/scan-setting.yaml | 40 ++++++++++++ charts/compliance-scanning/values.yaml | 59 ++++++++++++++++++ values-hub.yaml | 19 ++++++ 8 files changed, 283 insertions(+) create mode 100644 charts/compliance-scanning/Chart.yaml create mode 100644 charts/compliance-scanning/templates/_helpers.tpl create mode 100644 charts/compliance-scanning/templates/pvc.yaml create mode 100644 charts/compliance-scanning/templates/results-viewer-pod.yaml create mode 100644 charts/compliance-scanning/templates/scan-setting-binding.yaml create mode 100644 charts/compliance-scanning/templates/scan-setting.yaml create mode 100644 charts/compliance-scanning/values.yaml diff --git a/charts/compliance-scanning/Chart.yaml b/charts/compliance-scanning/Chart.yaml new file mode 100644 index 00000000..2878833e --- /dev/null +++ b/charts/compliance-scanning/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +description: Deploys resources for cluster hardening +keywords: + - pattern + - compliance + - zero trust + - hardening +name: compliance-scanning +type: application +icon: https://validatedpatterns.io/images/validated-patterns.png +version: 0.0.1 diff --git a/charts/compliance-scanning/templates/_helpers.tpl b/charts/compliance-scanning/templates/_helpers.tpl new file mode 100644 index 00000000..a83fcdf8 --- /dev/null +++ b/charts/compliance-scanning/templates/_helpers.tpl @@ -0,0 +1,61 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "compliance-scanning.name" -}} +{{- default .Chart.Name .Values.nameOverride }} +{{- end }} + +{{/* +Create a default fully qualified app name. +If release name contains chart name it will be used as a full name. +*/}} +{{- define "compliance-scanning.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "compliance-scanning.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "compliance-scanning.labels" -}} +helm.sh/chart: {{ include "compliance-scanning.chart" . }} +{{ include "compliance-scanning.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "compliance-scanning.selectorLabels" -}} +app.kubernetes.io/name: {{ include "compliance-scanning.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "compliance-scanning.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "compliance-scanning.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/compliance-scanning/templates/pvc.yaml b/charts/compliance-scanning/templates/pvc.yaml new file mode 100644 index 00000000..4c7ca393 --- /dev/null +++ b/charts/compliance-scanning/templates/pvc.yaml @@ -0,0 +1,20 @@ +{{- if .Values.compliance.storage.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ .Values.compliance.storage.pvc.name }} + namespace: openshift-compliance + annotations: + argocd.argoproj.io/sync-wave: '-10' + labels: + app.kubernetes.io/component: storage +spec: + accessModes: + - {{ .Values.compliance.storage.pvc.accessMode }} + resources: + requests: + storage: {{ .Values.compliance.storage.pvc.size }} + {{- if .Values.compliance.storage.pvc.storageClass }} + storageClassName: {{ .Values.compliance.storage.pvc.storageClass }} + {{- end }} +{{- end }} diff --git a/charts/compliance-scanning/templates/results-viewer-pod.yaml b/charts/compliance-scanning/templates/results-viewer-pod.yaml new file mode 100644 index 00000000..89f4acca --- /dev/null +++ b/charts/compliance-scanning/templates/results-viewer-pod.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.compliance.storage.enabled .Values.compliance.resultsViewer.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ .Values.compliance.resultsViewer.name }} + namespace: openshift-compliance + annotations: + argocd.argoproj.io/sync-wave: '10' + labels: + app.kubernetes.io/component: results-viewer +spec: + # Use a service account with appropriate permissions + serviceAccountName: default + # Container to access compliance scan results + containers: + - name: results-viewer + image: {{ .Values.compliance.resultsViewer.image }} + # Command to keep container running and provide shell access + command: ["/bin/bash"] + args: ["-c", "sleep infinity"] + # Mount the PVC containing scan results + volumeMounts: + - name: compliance-results + mountPath: {{ .Values.compliance.resultsViewer.mountPath }} + # Resource constraints + resources: + {{- toYaml .Values.compliance.resultsViewer.resources | nindent 6 }} + # Environment variables for easier navigation + env: + - name: SCAN_RESULTS_PATH + value: {{ .Values.compliance.resultsViewer.mountPath }} + - name: PS1 + value: "[compliance-results] \\u@\\h:\\w\\$ " + # Volume referencing the PVC + volumes: + - name: compliance-results + persistentVolumeClaim: + claimName: {{ .Values.compliance.storage.pvc.name }} + # Restart policy + restartPolicy: Always + # Tolerations to potentially run on master nodes if needed + tolerations: + - key: "node-role.kubernetes.io/master" + operator: "Exists" + effect: "NoSchedule" +{{- end }} diff --git a/charts/compliance-scanning/templates/scan-setting-binding.yaml b/charts/compliance-scanning/templates/scan-setting-binding.yaml new file mode 100644 index 00000000..c479e584 --- /dev/null +++ b/charts/compliance-scanning/templates/scan-setting-binding.yaml @@ -0,0 +1,27 @@ +apiVersion: compliance.openshift.io/v1alpha1 +kind: ScanSettingBinding +metadata: + name: {{ .Values.compliance.scanSettingBinding.name }} + namespace: openshift-compliance + annotations: + argocd.argoproj.io/sync-wave: '-10' + # Enable automatic remediation + compliance.openshift.io/default-auto-apply: "true" + labels: + app.kubernetes.io/component: compliance-scan-binding +spec: + settingsRef: + apiVersion: compliance.openshift.io/v1alpha1 + kind: ScanSetting + name: {{ .Values.compliance.scanSetting.name }} + # Profiles to bind to this scan setting + profiles: + {{- range .Values.compliance.scanSettingBinding.profiles }} + - apiVersion: compliance.openshift.io/v1alpha1 + kind: {{ .kind }} + name: {{ .name }} + {{- end }} + # Enable debug logging + {{- if .Values.compliance.scanSettingBinding.debug }} + debug: {{ .Values.compliance.scanSettingBinding.debug }} + {{- end }} diff --git a/charts/compliance-scanning/templates/scan-setting.yaml b/charts/compliance-scanning/templates/scan-setting.yaml new file mode 100644 index 00000000..05cd1f9c --- /dev/null +++ b/charts/compliance-scanning/templates/scan-setting.yaml @@ -0,0 +1,40 @@ +apiVersion: compliance.openshift.io/v1alpha1 +kind: ScanSetting +metadata: + name: {{ .Values.compliance.scanSetting.name }} + namespace: openshift-compliance + annotations: + argocd.argoproj.io/sync-wave: '-10' + labels: + app.kubernetes.io/component: compliance-scan-setting +spec: + # Enable automatic application of remediations + autoApplyRemediations: {{ .Values.compliance.scanSetting.autoApplyRemediations }} + # Use default-auto-apply annotation for automatic remediation + autoUpdateRemediations: true + # Scanning schedule (empty means manual trigger) + {{- if .Values.compliance.scanSetting.schedule }} + schedule: {{ .Values.compliance.scanSetting.schedule | quote }} + {{- end }} + # Scanner pod tolerations to run on all nodes including masters + scanTolerations: + {{- toYaml .Values.compliance.scanSetting.scanTolerations | nindent 4 }} + # Resource constraints for scanner pods + resources: + {{- toYaml .Values.compliance.scanSetting.resources | nindent 4 }} + # Node selector for scanner pods (if specified) + {{- if .Values.compliance.scanSetting.nodeSelector }} + nodeSelector: + {{- toYaml .Values.compliance.scanSetting.nodeSelector | nindent 4 }} + {{- end }} + # PVC for storing scan results + {{- if .Values.compliance.storage.enabled }} + rawResultStorage: + pvAccessModes: + - {{ .Values.compliance.storage.pvc.accessMode }} + rotation: 5 + size: {{ .Values.compliance.storage.pvc.size }} + {{- if .Values.compliance.storage.pvc.storageClass }} + storageClassName: {{ .Values.compliance.storage.pvc.storageClass }} + {{- end }} + {{- end }} diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml new file mode 100644 index 00000000..e39eddd5 --- /dev/null +++ b/charts/compliance-scanning/values.yaml @@ -0,0 +1,59 @@ +global: + localClusterDomain: local.example.com + +compliance: + # ScanSetting configuration + scanSetting: + name: compliance-scan-setting + # Enable automatic remediation + autoApplyRemediations: true + # Schedule scan (cron format) - empty means manual trigger + schedule: "" + # Set scanning tolerations + scanTolerations: + - key: "node-role.kubernetes.io/master" + operator: "Exists" + effect: "NoSchedule" + # Resources for scanner pods + resources: + limits: + memory: "1Gi" + cpu: "1000m" + requests: + memory: "512Mi" + cpu: "500m" + # Node selector for scanner pods + nodeSelector: {} + # (Future look at creating a TailoredProfile for ZT) + scanSettingBinding: + name: compliance-scan-binding + # Profile to scan - ocp4-moderate, ocp4-cis, rhcos4-moderate,... + profiles: + - name: "ocp4-moderate" + kind: "Profile" + # Set debug logging + debug: true + # Storage configuration for scan results + storage: + # Enable PVC creation + enabled: true + pvc: + name: compliance-scan-results + storageClass: "" + size: "2Gi" + accessMode: "ReadWriteOnce" + # Results viewer image with access to oscap to create html output + resultsViewer: + enabled: true + name: compliance-results-viewer + image: "registry.redhat.io/rhel8/toolbox:latest" + # Mount path for scan results + mountPath: "/compliance-results" + # Resources for viewer pod + resources: + limits: + memory: "512Mi" + cpu: "500m" + requests: + memory: "256Mi" + cpu: "250m" diff --git a/values-hub.yaml b/values-hub.yaml index 33e48e5d..279f4a4d 100644 --- a/values-hub.yaml +++ b/values-hub.yaml @@ -78,9 +78,18 @@ clusterGroup: # - '/overrides/values-{{ $.Values.global.hubClusterDomain }}.yaml' # - '/overrides/values-{{ $.Values.global.localClusterDomain }}.yaml' applications: + compliance-scanning: + name: compliance-scanning + namespace: openshift-compliance + annotations: + argocd.argoproj.io/sync-wave: '-30' + project: hub + path: charts/compliance-scanning vault: name: vault namespace: vault + annotations: + argocd.argoproj.io/sync-wave: '-20' project: hub chart: hashicorp-vault chartVersion: 0.1.* @@ -98,22 +107,30 @@ clusterGroup: golang-external-secrets: name: golang-external-secrets namespace: golang-external-secrets + annotations: + argocd.argoproj.io/sync-wave: '-20' project: hub chart: golang-external-secrets chartVersion: 0.1.* rh-keycloak: name: rh-keycloak namespace: keycloak-system + annotations: + argocd.argoproj.io/sync-wave: '-20' project: hub path: charts/keycloak rh-cert-manager: name: rh-cert-manager namespace: cert-manager-operator + annotations: + argocd.argoproj.io/sync-wave: '-20' project: hub path: charts/certmanager zero-trust-workload-identity-manager: name: zero-trust-workload-identity-manager namespace: zero-trust-workload-identity-manager + annotations: + argocd.argoproj.io/sync-wave: '-10' project: hub path: charts/zero-trust-workload-identity-manager overrides: @@ -122,6 +139,8 @@ clusterGroup: qtodo: name: qtodo namespace: qtodo + annotations: + argocd.argoproj.io/sync-wave: '0' project: hub path: charts/qtodo overrides: From cc6b3cedc80aad6d132cb52cdde9111811980457 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 15:52:20 -0500 Subject: [PATCH 02/33] Updated the ScanSetting and ScanSettingBinding yaml to not stick stuff in spec: and then ran linter against updated content --- .../templates/scan-setting-binding.yaml | 29 +++++---- .../templates/scan-setting.yaml | 59 +++++++++---------- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/charts/compliance-scanning/templates/scan-setting-binding.yaml b/charts/compliance-scanning/templates/scan-setting-binding.yaml index c479e584..d26181ac 100644 --- a/charts/compliance-scanning/templates/scan-setting-binding.yaml +++ b/charts/compliance-scanning/templates/scan-setting-binding.yaml @@ -9,19 +9,18 @@ metadata: compliance.openshift.io/default-auto-apply: "true" labels: app.kubernetes.io/component: compliance-scan-binding -spec: - settingsRef: - apiVersion: compliance.openshift.io/v1alpha1 - kind: ScanSetting - name: {{ .Values.compliance.scanSetting.name }} - # Profiles to bind to this scan setting - profiles: - {{- range .Values.compliance.scanSettingBinding.profiles }} - - apiVersion: compliance.openshift.io/v1alpha1 - kind: {{ .kind }} - name: {{ .name }} - {{- end }} - # Enable debug logging - {{- if .Values.compliance.scanSettingBinding.debug }} - debug: {{ .Values.compliance.scanSettingBinding.debug }} +settingsRef: + apiVersion: compliance.openshift.io/v1alpha1 + kind: ScanSetting + name: {{ .Values.compliance.scanSetting.name }} +# Profiles to bind to this scan setting +profiles: + {{- range .Values.compliance.scanSettingBinding.profiles }} + - apiVersion: compliance.openshift.io/v1alpha1 + kind: {{ .kind }} + name: {{ .name }} {{- end }} +# Enable debug logging +{{- if .Values.compliance.scanSettingBinding.debug }} +debug: {{ .Values.compliance.scanSettingBinding.debug }} +{{- end }} diff --git a/charts/compliance-scanning/templates/scan-setting.yaml b/charts/compliance-scanning/templates/scan-setting.yaml index 05cd1f9c..598c21a7 100644 --- a/charts/compliance-scanning/templates/scan-setting.yaml +++ b/charts/compliance-scanning/templates/scan-setting.yaml @@ -7,34 +7,33 @@ metadata: argocd.argoproj.io/sync-wave: '-10' labels: app.kubernetes.io/component: compliance-scan-setting -spec: - # Enable automatic application of remediations - autoApplyRemediations: {{ .Values.compliance.scanSetting.autoApplyRemediations }} - # Use default-auto-apply annotation for automatic remediation - autoUpdateRemediations: true - # Scanning schedule (empty means manual trigger) - {{- if .Values.compliance.scanSetting.schedule }} - schedule: {{ .Values.compliance.scanSetting.schedule | quote }} - {{- end }} - # Scanner pod tolerations to run on all nodes including masters - scanTolerations: - {{- toYaml .Values.compliance.scanSetting.scanTolerations | nindent 4 }} - # Resource constraints for scanner pods - resources: - {{- toYaml .Values.compliance.scanSetting.resources | nindent 4 }} - # Node selector for scanner pods (if specified) - {{- if .Values.compliance.scanSetting.nodeSelector }} - nodeSelector: - {{- toYaml .Values.compliance.scanSetting.nodeSelector | nindent 4 }} - {{- end }} - # PVC for storing scan results - {{- if .Values.compliance.storage.enabled }} - rawResultStorage: - pvAccessModes: - - {{ .Values.compliance.storage.pvc.accessMode }} - rotation: 5 - size: {{ .Values.compliance.storage.pvc.size }} - {{- if .Values.compliance.storage.pvc.storageClass }} - storageClassName: {{ .Values.compliance.storage.pvc.storageClass }} - {{- end }} +# Enable automatic application of remediations +autoApplyRemediations: {{ .Values.compliance.scanSetting.autoApplyRemediations }} +# Use default-auto-apply annotation for automatic remediation +autoUpdateRemediations: true +# Scanning schedule (empty means manual trigger) +{{- if .Values.compliance.scanSetting.schedule }} +schedule: {{ .Values.compliance.scanSetting.schedule | quote }} +{{- end }} +# Scanner pod tolerations to run on all nodes including masters +scanTolerations: + {{- toYaml .Values.compliance.scanSetting.scanTolerations | nindent 4 }} +# Resource constraints for scanner pods +resources: + {{- toYaml .Values.compliance.scanSetting.resources | nindent 4 }} +# Node selector for scanner pods (if specified) +{{- if .Values.compliance.scanSetting.nodeSelector }} +nodeSelector: + {{- toYaml .Values.compliance.scanSetting.nodeSelector | nindent 4 }} +{{- end }} +# PVC for storing scan results +{{- if .Values.compliance.storage.enabled }} +rawResultStorage: + pvAccessModes: + - {{ .Values.compliance.storage.pvc.accessMode }} + rotation: 5 + size: {{ .Values.compliance.storage.pvc.size }} + {{- if .Values.compliance.storage.pvc.storageClass }} + storageClassName: {{ .Values.compliance.storage.pvc.storageClass }} {{- end }} +{{- end }} From 4e181be84de8aa254525a4783b38256c71bf1df4 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 16:02:46 -0500 Subject: [PATCH 03/33] Removed resource limits from scan bindings and result viewer --- .../compliance-scanning/templates/results-viewer-pod.yaml | 3 --- charts/compliance-scanning/templates/scan-setting.yaml | 3 --- charts/compliance-scanning/values.yaml | 8 -------- 3 files changed, 14 deletions(-) diff --git a/charts/compliance-scanning/templates/results-viewer-pod.yaml b/charts/compliance-scanning/templates/results-viewer-pod.yaml index 89f4acca..a7d4a28f 100644 --- a/charts/compliance-scanning/templates/results-viewer-pod.yaml +++ b/charts/compliance-scanning/templates/results-viewer-pod.yaml @@ -22,9 +22,6 @@ spec: volumeMounts: - name: compliance-results mountPath: {{ .Values.compliance.resultsViewer.mountPath }} - # Resource constraints - resources: - {{- toYaml .Values.compliance.resultsViewer.resources | nindent 6 }} # Environment variables for easier navigation env: - name: SCAN_RESULTS_PATH diff --git a/charts/compliance-scanning/templates/scan-setting.yaml b/charts/compliance-scanning/templates/scan-setting.yaml index 598c21a7..352ebf86 100644 --- a/charts/compliance-scanning/templates/scan-setting.yaml +++ b/charts/compliance-scanning/templates/scan-setting.yaml @@ -18,9 +18,6 @@ schedule: {{ .Values.compliance.scanSetting.schedule | quote }} # Scanner pod tolerations to run on all nodes including masters scanTolerations: {{- toYaml .Values.compliance.scanSetting.scanTolerations | nindent 4 }} -# Resource constraints for scanner pods -resources: - {{- toYaml .Values.compliance.scanSetting.resources | nindent 4 }} # Node selector for scanner pods (if specified) {{- if .Values.compliance.scanSetting.nodeSelector }} nodeSelector: diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index e39eddd5..3dbe4ce8 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -14,14 +14,6 @@ compliance: - key: "node-role.kubernetes.io/master" operator: "Exists" effect: "NoSchedule" - # Resources for scanner pods - resources: - limits: - memory: "1Gi" - cpu: "1000m" - requests: - memory: "512Mi" - cpu: "500m" # Node selector for scanner pods nodeSelector: {} # (Future look at creating a TailoredProfile for ZT) From 20dcc464102a7ddcbf881e3b933c989bd4b5bb6a Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 16:03:21 -0500 Subject: [PATCH 04/33] Removed extra line from values.yaml --- charts/compliance-scanning/values.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 3dbe4ce8..fa6d2794 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -41,11 +41,3 @@ compliance: image: "registry.redhat.io/rhel8/toolbox:latest" # Mount path for scan results mountPath: "/compliance-results" - # Resources for viewer pod - resources: - limits: - memory: "512Mi" - cpu: "500m" - requests: - memory: "256Mi" - cpu: "250m" From 7d5ee8fccb72a910f4864df06cd6c3589472350b Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 16:13:44 -0500 Subject: [PATCH 05/33] Removed extra api refs --- .../compliance-scanning/templates/scan-setting-binding.yaml | 6 +----- charts/compliance-scanning/values.yaml | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/charts/compliance-scanning/templates/scan-setting-binding.yaml b/charts/compliance-scanning/templates/scan-setting-binding.yaml index d26181ac..46d60105 100644 --- a/charts/compliance-scanning/templates/scan-setting-binding.yaml +++ b/charts/compliance-scanning/templates/scan-setting-binding.yaml @@ -16,11 +16,7 @@ settingsRef: # Profiles to bind to this scan setting profiles: {{- range .Values.compliance.scanSettingBinding.profiles }} - - apiVersion: compliance.openshift.io/v1alpha1 kind: {{ .kind }} name: {{ .name }} {{- end }} -# Enable debug logging -{{- if .Values.compliance.scanSettingBinding.debug }} -debug: {{ .Values.compliance.scanSettingBinding.debug }} -{{- end }} +debug: true diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index fa6d2794..c2e17390 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -23,8 +23,6 @@ compliance: profiles: - name: "ocp4-moderate" kind: "Profile" - # Set debug logging - debug: true # Storage configuration for scan results storage: # Enable PVC creation From a3a70530e7db729445db9c5f688e8f05209fd570 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 16:25:00 -0500 Subject: [PATCH 06/33] Modified calling of single profile for scansettingbinding --- .../templates/scan-setting-binding.yaml | 7 +++---- charts/compliance-scanning/values.yaml | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/charts/compliance-scanning/templates/scan-setting-binding.yaml b/charts/compliance-scanning/templates/scan-setting-binding.yaml index 46d60105..8ee04902 100644 --- a/charts/compliance-scanning/templates/scan-setting-binding.yaml +++ b/charts/compliance-scanning/templates/scan-setting-binding.yaml @@ -15,8 +15,7 @@ settingsRef: name: {{ .Values.compliance.scanSetting.name }} # Profiles to bind to this scan setting profiles: - {{- range .Values.compliance.scanSettingBinding.profiles }} - kind: {{ .kind }} - name: {{ .name }} - {{- end }} + - name: {{ .Values.compliance.scanSettingBinding.profile }} + kind: Profile + apiGroup: compliance.openshift.io/v1alpha1 debug: true diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index c2e17390..5846ca9a 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -20,9 +20,7 @@ compliance: scanSettingBinding: name: compliance-scan-binding # Profile to scan - ocp4-moderate, ocp4-cis, rhcos4-moderate,... - profiles: - - name: "ocp4-moderate" - kind: "Profile" + profile: "ocp4-moderate" # Storage configuration for scan results storage: # Enable PVC creation From fff995d48b3da6c1f64951453b751b8897755206 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 16:26:59 -0500 Subject: [PATCH 07/33] Removed apiGroup from profiles --- charts/compliance-scanning/templates/scan-setting-binding.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/charts/compliance-scanning/templates/scan-setting-binding.yaml b/charts/compliance-scanning/templates/scan-setting-binding.yaml index 8ee04902..e0228259 100644 --- a/charts/compliance-scanning/templates/scan-setting-binding.yaml +++ b/charts/compliance-scanning/templates/scan-setting-binding.yaml @@ -17,5 +17,4 @@ settingsRef: profiles: - name: {{ .Values.compliance.scanSettingBinding.profile }} kind: Profile - apiGroup: compliance.openshift.io/v1alpha1 -debug: true + From 971563ccd5bb25678c5d3174870b6c9fc0367a6b Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 16:28:49 -0500 Subject: [PATCH 08/33] Removed apiVersion from settingsRef --- charts/compliance-scanning/templates/scan-setting-binding.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/charts/compliance-scanning/templates/scan-setting-binding.yaml b/charts/compliance-scanning/templates/scan-setting-binding.yaml index e0228259..fff36f6a 100644 --- a/charts/compliance-scanning/templates/scan-setting-binding.yaml +++ b/charts/compliance-scanning/templates/scan-setting-binding.yaml @@ -10,7 +10,6 @@ metadata: labels: app.kubernetes.io/component: compliance-scan-binding settingsRef: - apiVersion: compliance.openshift.io/v1alpha1 kind: ScanSetting name: {{ .Values.compliance.scanSetting.name }} # Profiles to bind to this scan setting From 8f0755d4898fac28fd59aad01fc8d7b450f6d910 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 16:31:29 -0500 Subject: [PATCH 09/33] Removed tolerations from result viewer --- charts/compliance-scanning/templates/results-viewer-pod.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/charts/compliance-scanning/templates/results-viewer-pod.yaml b/charts/compliance-scanning/templates/results-viewer-pod.yaml index a7d4a28f..7591e2ae 100644 --- a/charts/compliance-scanning/templates/results-viewer-pod.yaml +++ b/charts/compliance-scanning/templates/results-viewer-pod.yaml @@ -35,9 +35,4 @@ spec: claimName: {{ .Values.compliance.storage.pvc.name }} # Restart policy restartPolicy: Always - # Tolerations to potentially run on master nodes if needed - tolerations: - - key: "node-role.kubernetes.io/master" - operator: "Exists" - effect: "NoSchedule" {{- end }} From 123af1dcca8da2145a47de8b33b75d45952daee6 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 16:48:53 -0500 Subject: [PATCH 10/33] Updated to use the rhcos4-stig profile --- charts/compliance-scanning/values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 5846ca9a..58507ba9 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -19,8 +19,8 @@ compliance: # (Future look at creating a TailoredProfile for ZT) scanSettingBinding: name: compliance-scan-binding - # Profile to scan - ocp4-moderate, ocp4-cis, rhcos4-moderate,... - profile: "ocp4-moderate" + # Profile in oc get profiles.compliance -n openshift-compliance + profile: "rhcos4-stig" # Storage configuration for scan results storage: # Enable PVC creation From 88be04a405d1383e6e7e3c53bb6edb76755d1b8f Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 17:01:26 -0500 Subject: [PATCH 11/33] Setting a daily at 0200 cron to see if I can get setting to run on initial launch --- charts/compliance-scanning/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 58507ba9..91953a71 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -8,7 +8,7 @@ compliance: # Enable automatic remediation autoApplyRemediations: true # Schedule scan (cron format) - empty means manual trigger - schedule: "" + schedule: "02***" # Set scanning tolerations scanTolerations: - key: "node-role.kubernetes.io/master" From e2dfaf3ba995671a1dcfb9e5c4d1817a74b3baae Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Thu, 4 Sep 2025 17:04:49 -0500 Subject: [PATCH 12/33] Updated comment for schedule field --- charts/compliance-scanning/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 91953a71..4e6beb14 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -7,7 +7,7 @@ compliance: name: compliance-scan-setting # Enable automatic remediation autoApplyRemediations: true - # Schedule scan (cron format) - empty means manual trigger + # Schedule scan (cron format daily at 0200) schedule: "02***" # Set scanning tolerations scanTolerations: From 732c8bff5421b4d278414024b4575aa264b2cdd1 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 08:58:32 -0500 Subject: [PATCH 13/33] Upodated description and reintroiduced apiGroup elements in scan-setting-binding --- charts/compliance-scanning/Chart.yaml | 2 +- charts/compliance-scanning/templates/scan-setting-binding.yaml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/charts/compliance-scanning/Chart.yaml b/charts/compliance-scanning/Chart.yaml index 2878833e..bf114aeb 100644 --- a/charts/compliance-scanning/Chart.yaml +++ b/charts/compliance-scanning/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -description: Deploys resources for cluster hardening +description: compliance-scanning performs hardening of OCP cluster vis predefiend profile(s) keywords: - pattern - compliance diff --git a/charts/compliance-scanning/templates/scan-setting-binding.yaml b/charts/compliance-scanning/templates/scan-setting-binding.yaml index fff36f6a..a911f280 100644 --- a/charts/compliance-scanning/templates/scan-setting-binding.yaml +++ b/charts/compliance-scanning/templates/scan-setting-binding.yaml @@ -11,9 +11,11 @@ metadata: app.kubernetes.io/component: compliance-scan-binding settingsRef: kind: ScanSetting + apiGroup: compliance.openshift.io/v1alpha1 name: {{ .Values.compliance.scanSetting.name }} # Profiles to bind to this scan setting profiles: - name: {{ .Values.compliance.scanSettingBinding.profile }} kind: Profile + apiGroup: compliance.openshift.io/v1alpha1 From e4e1fbb988f34674d67c0df983f5b2a92ae82c4e Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 09:33:14 -0500 Subject: [PATCH 14/33] Updated cron format for schedule --- charts/compliance-scanning/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 4e6beb14..054f2c12 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -8,7 +8,7 @@ compliance: # Enable automatic remediation autoApplyRemediations: true # Schedule scan (cron format daily at 0200) - schedule: "02***" + schedule: "0 2 * * *" # Set scanning tolerations scanTolerations: - key: "node-role.kubernetes.io/master" From 06095df396438489a91e2af7dcd3b26ffc762b27 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 09:48:18 -0500 Subject: [PATCH 15/33] Added roles for master and worker to scansetting since they are not inherited --- charts/compliance-scanning/templates/scan-setting.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/charts/compliance-scanning/templates/scan-setting.yaml b/charts/compliance-scanning/templates/scan-setting.yaml index 352ebf86..ac00bae0 100644 --- a/charts/compliance-scanning/templates/scan-setting.yaml +++ b/charts/compliance-scanning/templates/scan-setting.yaml @@ -15,6 +15,9 @@ autoUpdateRemediations: true {{- if .Values.compliance.scanSetting.schedule }} schedule: {{ .Values.compliance.scanSetting.schedule | quote }} {{- end }} +roles: + master + worker # Scanner pod tolerations to run on all nodes including masters scanTolerations: {{- toYaml .Values.compliance.scanSetting.scanTolerations | nindent 4 }} From f168626d2da9f463a88be0f5615eed0b7f45e6e4 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 09:51:33 -0500 Subject: [PATCH 16/33] Fixed formatting issue on roles --- charts/compliance-scanning/templates/scan-setting.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/compliance-scanning/templates/scan-setting.yaml b/charts/compliance-scanning/templates/scan-setting.yaml index ac00bae0..3c891905 100644 --- a/charts/compliance-scanning/templates/scan-setting.yaml +++ b/charts/compliance-scanning/templates/scan-setting.yaml @@ -16,8 +16,8 @@ autoUpdateRemediations: true schedule: {{ .Values.compliance.scanSetting.schedule | quote }} {{- end }} roles: - master - worker + - master + - worker # Scanner pod tolerations to run on all nodes including masters scanTolerations: {{- toYaml .Values.compliance.scanSetting.scanTolerations | nindent 4 }} From bbc20218f9dbdf87f4a83fb7277c972bee3215d7 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 10:01:51 -0500 Subject: [PATCH 17/33] Removing schdule cron entry so it only runs on deployment of pattern --- charts/compliance-scanning/values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 054f2c12..683767fc 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -7,8 +7,8 @@ compliance: name: compliance-scan-setting # Enable automatic remediation autoApplyRemediations: true - # Schedule scan (cron format daily at 0200) - schedule: "0 2 * * *" + # Schedule scan + schedule: "" # Set scanning tolerations scanTolerations: - key: "node-role.kubernetes.io/master" From 5992d24cb4ff8b2d1f48eb37b401a5e93ab17d14 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 10:56:41 -0500 Subject: [PATCH 18/33] Used Cursor to generate a job that waits on execution of compliancescan and then for each complianceremediation generated it changes default state of spec.apply false to spec.apply true and then merges that back into cluster to take effect --- .../templates/remediation-job.yaml | 203 ++++++++++++++++++ charts/compliance-scanning/values.yaml | 41 ++++ 2 files changed, 244 insertions(+) create mode 100644 charts/compliance-scanning/templates/remediation-job.yaml diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml new file mode 100644 index 00000000..aebe7a9e --- /dev/null +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -0,0 +1,203 @@ +# ServiceAccount for the remediation job +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.compliance.remediationJob.serviceAccount.name }} + namespace: openshift-compliance + annotations: + argocd.argoproj.io/sync-wave: '0' + labels: + app.kubernetes.io/component: compliance-remediation-job +--- +# ClusterRole with permissions to manage compliance resources +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Values.compliance.remediationJob.clusterRole.name }} + annotations: + argocd.argoproj.io/sync-wave: '0' + labels: + app.kubernetes.io/component: compliance-remediation-job +rules: +- apiGroups: ["compliance.openshift.io"] + resources: ["compliancescans"] + verbs: ["get", "list", "watch"] +- apiGroups: ["compliance.openshift.io"] + resources: ["complianceremediations"] + verbs: ["get", "list", "watch", "update", "patch"] +- apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +--- +# ClusterRoleBinding to bind the role to the service account +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Values.compliance.remediationJob.clusterRoleBinding.name }} + annotations: + argocd.argoproj.io/sync-wave: '0' + labels: + app.kubernetes.io/component: compliance-remediation-job +subjects: +- kind: ServiceAccount + name: {{ .Values.compliance.remediationJob.serviceAccount.name }} + namespace: openshift-compliance +roleRef: + kind: ClusterRole + name: {{ .Values.compliance.remediationJob.clusterRole.name }} + apiGroup: rbac.authorization.k8s.io +--- +# Job to wait for scan completion and apply remediations +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Values.compliance.remediationJob.name }} + namespace: openshift-compliance + annotations: + argocd.argoproj.io/sync-wave: '10' + labels: + app.kubernetes.io/component: compliance-remediation-job +spec: + template: + metadata: + labels: + app.kubernetes.io/component: compliance-remediation-job + spec: + serviceAccountName: {{ .Values.compliance.remediationJob.serviceAccount.name }} + restartPolicy: OnFailure + containers: + - name: remediation-applier + image: {{ .Values.compliance.remediationJob.image }} + command: ["/bin/bash"] + args: + - -c + - | + set -euo pipefail + + echo "Installing required tools..." + + # Install kubectl and jq + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + chmod +x kubectl + mv kubectl /usr/local/bin/ + + microdnf install -y jq || yum install -y jq || (echo "Installing jq manually..." && \ + curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -o /usr/local/bin/jq && \ + chmod +x /usr/local/bin/jq) + + echo "Tools installed successfully." + echo "Starting compliance remediation job..." + echo "Scan Setting Binding: {{ .Values.compliance.scanSettingBinding.name }}" + echo "Profile: {{ .Values.compliance.scanSettingBinding.profile }}" + + # The ComplianceScan name is typically generated from the binding name and profile + # Format: - + SCAN_NAME="{{ .Values.compliance.scanSettingBinding.name }}-{{ .Values.compliance.scanSettingBinding.profile }}" + NAMESPACE="openshift-compliance" + + echo "Waiting for ComplianceScan: $SCAN_NAME to complete..." + + # Wait for the scan to exist first + max_wait_for_scan=600 # 10 minutes + wait_time=0 + + while ! kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" >/dev/null 2>&1; do + if [ $wait_time -ge $max_wait_for_scan ]; then + echo "ERROR: ComplianceScan $SCAN_NAME not found after ${max_wait_for_scan}s" + exit 1 + fi + echo "Waiting for ComplianceScan $SCAN_NAME to be created... (${wait_time}s elapsed)" + sleep 10 + wait_time=$((wait_time + 10)) + done + + echo "ComplianceScan $SCAN_NAME found. Waiting for completion..." + + # Wait for the scan to complete + max_wait=7200 # 2 hours + wait_time=0 + + while true; do + # Get the scan phase/status + PHASE=$(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{.status.phase}' 2>/dev/null || echo "") + + if [ "$PHASE" = "DONE" ]; then + echo "ComplianceScan $SCAN_NAME completed successfully!" + break + elif [ "$PHASE" = "ERROR" ] || [ "$PHASE" = "FAILED" ]; then + echo "ERROR: ComplianceScan $SCAN_NAME failed with phase: $PHASE" + exit 1 + elif [ -z "$PHASE" ]; then + echo "ComplianceScan $SCAN_NAME phase is empty, waiting..." + else + echo "ComplianceScan $SCAN_NAME is in phase: $PHASE (waiting...)" + fi + + if [ $wait_time -ge $max_wait ]; then + echo "ERROR: ComplianceScan $SCAN_NAME did not complete within ${max_wait}s" + exit 1 + fi + + sleep 30 + wait_time=$((wait_time + 30)) + done + + echo "Scan completed. Looking for pending ComplianceRemediations..." + + # Get all ComplianceRemediation objects with state=Pending and spec.apply=false + PENDING_REMEDIATIONS=$(kubectl get complianceremediations -n "$NAMESPACE" -o json | \ + jq -r '.items[] | select(.status.applicationState == "Pending" and .spec.apply == false) | .metadata.name') + + if [ -z "$PENDING_REMEDIATIONS" ]; then + echo "No pending ComplianceRemediations found with spec.apply=false" + exit 0 + fi + + echo "Found pending ComplianceRemediations to apply:" + echo "$PENDING_REMEDIATIONS" + + # Apply each remediation by setting spec.apply to true + APPLIED_COUNT=0 + for REMEDIATION in $PENDING_REMEDIATIONS; do + echo "Applying remediation: $REMEDIATION" + + if kubectl patch complianceremediation "$REMEDIATION" -n "$NAMESPACE" \ + --type='merge' \ + --patch='{"spec": {"apply": true}}'; then + echo "Successfully applied remediation: $REMEDIATION" + APPLIED_COUNT=$((APPLIED_COUNT + 1)) + else + echo "ERROR: Failed to apply remediation: $REMEDIATION" + fi + done + + echo "Remediation job completed. Applied $APPLIED_COUNT remediations." + + # Create an event to record the action + kubectl create event \ + --namespace="$NAMESPACE" \ + --type=Normal \ + --reason=RemediationApplied \ + --message="Applied $APPLIED_COUNT ComplianceRemediations after scan completion" \ + --for="job/{{ .Values.compliance.remediationJob.name }}" || true + env: + - name: KUBECONFIG + value: /var/run/secrets/kubernetes.io/serviceaccount/token + resources: + {{- toYaml .Values.compliance.remediationJob.resources | nindent 10 }} + {{- if .Values.compliance.remediationJob.securityContext }} + securityContext: + {{- toYaml .Values.compliance.remediationJob.securityContext | nindent 10 }} + {{- end }} + {{- if .Values.compliance.remediationJob.nodeSelector }} + nodeSelector: + {{- toYaml .Values.compliance.remediationJob.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.compliance.remediationJob.tolerations }} + tolerations: + {{- toYaml .Values.compliance.remediationJob.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.compliance.remediationJob.affinity }} + affinity: + {{- toYaml .Values.compliance.remediationJob.affinity | nindent 8 }} + {{- end }} diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 683767fc..04a207ba 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -37,3 +37,44 @@ compliance: image: "registry.redhat.io/rhel8/toolbox:latest" # Mount path for scan results mountPath: "/compliance-results" + # Remediation job configuration + remediationJob: + # Job name + name: compliance-remediation-job + # Container image with kubectl and jq + image: "registry.redhat.io/ubi8/ubi:latest" + # Service account configuration + serviceAccount: + name: compliance-remediation-sa + # RBAC configuration + clusterRole: + name: compliance-remediation-role + clusterRoleBinding: + name: compliance-remediation-binding + # Resource limits and requests + resources: + limits: + cpu: "200m" + memory: "256Mi" + requests: + cpu: "100m" + memory: "128Mi" + # Security context + securityContext: + runAsNonRoot: true + runAsUser: 1001 + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE + readOnlyRootFilesystem: false + seccompProfile: + type: RuntimeDefault + # Node selector (optional) + nodeSelector: {} + # Tolerations (optional) + tolerations: [] + # Affinity (optional) + affinity: {} From d8bfb6dbc6fff6132dfe50685f3e8ecdc09b941c Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 11:12:00 -0500 Subject: [PATCH 19/33] Needs to run as root. We can revisit this in review --- charts/compliance-scanning/values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 04a207ba..4e41586b 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -61,8 +61,8 @@ compliance: memory: "128Mi" # Security context securityContext: - runAsNonRoot: true - runAsUser: 1001 + runAsNonRoot: false + runAsUser: 0 allowPrivilegeEscalation: false capabilities: drop: From 202ada7c9d83a2688b4a0ce40d50e9942696b97a Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 11:14:48 -0500 Subject: [PATCH 20/33] Updated image refs to ubi9 unauthenticated access container images --- charts/compliance-scanning/values.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 4e41586b..420e784b 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -34,7 +34,8 @@ compliance: resultsViewer: enabled: true name: compliance-results-viewer - image: "registry.redhat.io/rhel8/toolbox:latest" + # TBD make this one of the utility container images from VP team for performing the oscap operations on results + image: "registry.access.redhat.com/ubi9/ubi:latest" # Mount path for scan results mountPath: "/compliance-results" # Remediation job configuration @@ -42,7 +43,7 @@ compliance: # Job name name: compliance-remediation-job # Container image with kubectl and jq - image: "registry.redhat.io/ubi8/ubi:latest" + image: "registry.access.redhat.com/ubi9/ubi:latest" # Service account configuration serviceAccount: name: compliance-remediation-sa From a8919035517b065225df69c19d4f63a9502108b1 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 11:19:31 -0500 Subject: [PATCH 21/33] Removed cursor generated securitycontext so we inherit from default cluster settings --- charts/compliance-scanning/values.yaml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 420e784b..a7b25155 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -60,19 +60,6 @@ compliance: requests: cpu: "100m" memory: "128Mi" - # Security context - securityContext: - runAsNonRoot: false - runAsUser: 0 - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - add: - - NET_BIND_SERVICE - readOnlyRootFilesystem: false - seccompProfile: - type: RuntimeDefault # Node selector (optional) nodeSelector: {} # Tolerations (optional) From 63adfa57640f99a1f348fc534cc818dc4eb7b2f4 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 11:31:43 -0500 Subject: [PATCH 22/33] Updated remediaiton job to not try and dnf install jq and kubectl but instead use vp container image that has tools preloaded --- .../templates/remediation-job.yaml | 12 ------------ charts/compliance-scanning/values.yaml | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml index aebe7a9e..0612d43e 100644 --- a/charts/compliance-scanning/templates/remediation-job.yaml +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -74,18 +74,6 @@ spec: - | set -euo pipefail - echo "Installing required tools..." - - # Install kubectl and jq - curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" - chmod +x kubectl - mv kubectl /usr/local/bin/ - - microdnf install -y jq || yum install -y jq || (echo "Installing jq manually..." && \ - curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -o /usr/local/bin/jq && \ - chmod +x /usr/local/bin/jq) - - echo "Tools installed successfully." echo "Starting compliance remediation job..." echo "Scan Setting Binding: {{ .Values.compliance.scanSettingBinding.name }}" echo "Profile: {{ .Values.compliance.scanSettingBinding.profile }}" diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index a7b25155..0c795493 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -43,7 +43,7 @@ compliance: # Job name name: compliance-remediation-job # Container image with kubectl and jq - image: "registry.access.redhat.com/ubi9/ubi:latest" + image: "quay.io/validatedpatterns/imperative-container:v1" # Service account configuration serviceAccount: name: compliance-remediation-sa From 4ef606876694327d3eb339973e633ebe17267438 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 11:51:37 -0500 Subject: [PATCH 23/33] Modified the image to pull from older quay vp registry org --- charts/compliance-scanning/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 0c795493..74eb10e8 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -43,7 +43,7 @@ compliance: # Job name name: compliance-remediation-job # Container image with kubectl and jq - image: "quay.io/validatedpatterns/imperative-container:v1" + image: "quay.io/hybridcloudpatterns/imperative-container:v1" # Service account configuration serviceAccount: name: compliance-remediation-sa From 821a784cb0abbc8bf2714307bfaa481c6a43938b Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 12:01:34 -0500 Subject: [PATCH 24/33] Updated the complaincescan naming convention to be profile-role --- charts/compliance-scanning/templates/remediation-job.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml index 0612d43e..27f8d594 100644 --- a/charts/compliance-scanning/templates/remediation-job.yaml +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -79,8 +79,8 @@ spec: echo "Profile: {{ .Values.compliance.scanSettingBinding.profile }}" # The ComplianceScan name is typically generated from the binding name and profile - # Format: - - SCAN_NAME="{{ .Values.compliance.scanSettingBinding.name }}-{{ .Values.compliance.scanSettingBinding.profile }}" + # Format: - + SCAN_NAME="{{ .Values.compliance.scanSettingBinding.profile }}-worker" NAMESPACE="openshift-compliance" echo "Waiting for ComplianceScan: $SCAN_NAME to complete..." From 4145d9094ef98aa356e8dc32d64aa6c4fc1b2fe0 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 12:29:40 -0500 Subject: [PATCH 25/33] Fixed while loop logic to get compliancescans correctly --- charts/compliance-scanning/templates/remediation-job.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml index 27f8d594..d3a37a3a 100644 --- a/charts/compliance-scanning/templates/remediation-job.yaml +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -89,7 +89,7 @@ spec: max_wait_for_scan=600 # 10 minutes wait_time=0 - while ! kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" >/dev/null 2>&1; do + while [[ $(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{..status.conditions[?(@.type=="Ready")].status}') != "True"]]; do if [ $wait_time -ge $max_wait_for_scan ]; then echo "ERROR: ComplianceScan $SCAN_NAME not found after ${max_wait_for_scan}s" exit 1 From 71ca8c01c6ef46f4ee31ae7f26d91a497b48cb99 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 12:38:23 -0500 Subject: [PATCH 26/33] Removed brackets around while --- charts/compliance-scanning/templates/remediation-job.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml index d3a37a3a..39ae144b 100644 --- a/charts/compliance-scanning/templates/remediation-job.yaml +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -89,7 +89,7 @@ spec: max_wait_for_scan=600 # 10 minutes wait_time=0 - while [[ $(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{..status.conditions[?(@.type=="Ready")].status}') != "True"]]; do + while $(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{..status.conditions[?(@.type=="Ready")].status}') != "True"; do if [ $wait_time -ge $max_wait_for_scan ]; then echo "ERROR: ComplianceScan $SCAN_NAME not found after ${max_wait_for_scan}s" exit 1 From f9caa156f5b23b4b1ee8e7f87dbdb0eeb8056111 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 12:44:43 -0500 Subject: [PATCH 27/33] Script fixes for value checks in remediation job --- charts/compliance-scanning/templates/remediation-job.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml index 39ae144b..18ad13a2 100644 --- a/charts/compliance-scanning/templates/remediation-job.yaml +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -89,7 +89,7 @@ spec: max_wait_for_scan=600 # 10 minutes wait_time=0 - while $(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{..status.conditions[?(@.type=="Ready")].status}') != "True"; do + while [[ $(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do if [ $wait_time -ge $max_wait_for_scan ]; then echo "ERROR: ComplianceScan $SCAN_NAME not found after ${max_wait_for_scan}s" exit 1 @@ -107,7 +107,7 @@ spec: while true; do # Get the scan phase/status - PHASE=$(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{.status.phase}' 2>/dev/null || echo "") + PHASE=$(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{.status.phase}') if [ "$PHASE" = "DONE" ]; then echo "ComplianceScan $SCAN_NAME completed successfully!" From d45f55fdcd4fce47c59e6fe6571476a389f5653a Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Fri, 5 Sep 2025 13:30:08 -0500 Subject: [PATCH 28/33] Updated bash script to patch the complianceremediaitons CRs with spec.apply set to True --- .../templates/remediation-job.yaml | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml index 18ad13a2..fd12b388 100644 --- a/charts/compliance-scanning/templates/remediation-job.yaml +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -84,12 +84,16 @@ spec: NAMESPACE="openshift-compliance" echo "Waiting for ComplianceScan: $SCAN_NAME to complete..." - + # Wait for the scan to exist first + max_wait_for_scan=600 # 10 minutes + wait_time=0 - - while [[ $(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do + + + while [[ $(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o \ + jsonpath='{..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do if [ $wait_time -ge $max_wait_for_scan ]; then echo "ERROR: ComplianceScan $SCAN_NAME not found after ${max_wait_for_scan}s" exit 1 @@ -98,13 +102,18 @@ spec: sleep 10 wait_time=$((wait_time + 10)) done - + + echo "ComplianceScan $SCAN_NAME found. Waiting for completion..." - + + # Wait for the scan to complete + max_wait=7200 # 2 hours + wait_time=0 - + + while true; do # Get the scan phase/status PHASE=$(kubectl get compliancescan "$SCAN_NAME" -n "$NAMESPACE" -o jsonpath='{.status.phase}') @@ -129,23 +138,31 @@ spec: sleep 30 wait_time=$((wait_time + 30)) done - + + echo "Scan completed. Looking for pending ComplianceRemediations..." - + + # Get all ComplianceRemediation objects with state=Pending and spec.apply=false + PENDING_REMEDIATIONS=$(kubectl get complianceremediations -n "$NAMESPACE" -o json | \ jq -r '.items[] | select(.status.applicationState == "Pending" and .spec.apply == false) | .metadata.name') - + if [ -z "$PENDING_REMEDIATIONS" ]; then echo "No pending ComplianceRemediations found with spec.apply=false" exit 0 fi - + + echo "Found pending ComplianceRemediations to apply:" + echo "$PENDING_REMEDIATIONS" - + + # Apply each remediation by setting spec.apply to true + APPLIED_COUNT=0 + for REMEDIATION in $PENDING_REMEDIATIONS; do echo "Applying remediation: $REMEDIATION" @@ -158,16 +175,18 @@ spec: echo "ERROR: Failed to apply remediation: $REMEDIATION" fi done - + + echo "Remediation job completed. Applied $APPLIED_COUNT remediations." - + + # Create an event to record the action + kubectl create event \ --namespace="$NAMESPACE" \ - --type=Normal \ --reason=RemediationApplied \ --message="Applied $APPLIED_COUNT ComplianceRemediations after scan completion" \ - --for="job/{{ .Values.compliance.remediationJob.name }}" || true + --for="job/compliance-remediation-job" || true env: - name: KUBECONFIG value: /var/run/secrets/kubernetes.io/serviceaccount/token From 187763d8f50fe5d63562b08754e747ac6aabb70d Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Mon, 8 Sep 2025 09:19:49 -0500 Subject: [PATCH 29/33] Updated version to chart --- charts/compliance-scanning/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/compliance-scanning/Chart.yaml b/charts/compliance-scanning/Chart.yaml index bf114aeb..270a1fb8 100644 --- a/charts/compliance-scanning/Chart.yaml +++ b/charts/compliance-scanning/Chart.yaml @@ -8,4 +8,4 @@ keywords: name: compliance-scanning type: application icon: https://validatedpatterns.io/images/validated-patterns.png -version: 0.0.1 +version: 0.0.3 From d5d6a1dea2f251a66dc255f761d1cad350b99818 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Mon, 8 Sep 2025 09:33:58 -0500 Subject: [PATCH 30/33] Removed env setting for bash script access to KUBECONFIG based on discussion with VP team and no need to do that in other examples --- charts/compliance-scanning/templates/remediation-job.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml index fd12b388..f2230aea 100644 --- a/charts/compliance-scanning/templates/remediation-job.yaml +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -72,7 +72,7 @@ spec: args: - -c - | - set -euo pipefail + set -Eeuxo pipefail echo "Starting compliance remediation job..." echo "Scan Setting Binding: {{ .Values.compliance.scanSettingBinding.name }}" @@ -187,9 +187,6 @@ spec: --reason=RemediationApplied \ --message="Applied $APPLIED_COUNT ComplianceRemediations after scan completion" \ --for="job/compliance-remediation-job" || true - env: - - name: KUBECONFIG - value: /var/run/secrets/kubernetes.io/serviceaccount/token resources: {{- toYaml .Values.compliance.remediationJob.resources | nindent 10 }} {{- if .Values.compliance.remediationJob.securityContext }} From 71b752207c71ee2c2c92bc8f60edee2c7a6e110b Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Mon, 8 Sep 2025 09:44:36 -0500 Subject: [PATCH 31/33] Removed reasonApplied for kubectl vreate event at end of bash script for remediation-job --- charts/compliance-scanning/templates/remediation-job.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/charts/compliance-scanning/templates/remediation-job.yaml b/charts/compliance-scanning/templates/remediation-job.yaml index f2230aea..85e395bf 100644 --- a/charts/compliance-scanning/templates/remediation-job.yaml +++ b/charts/compliance-scanning/templates/remediation-job.yaml @@ -184,7 +184,6 @@ spec: kubectl create event \ --namespace="$NAMESPACE" \ - --reason=RemediationApplied \ --message="Applied $APPLIED_COUNT ComplianceRemediations after scan completion" \ --for="job/compliance-remediation-job" || true resources: From 96ece4f773b8f49f31996c48184015b0cf93dee7 Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Mon, 8 Sep 2025 11:12:06 -0500 Subject: [PATCH 32/33] Removed the autoremediaiton annotation on scansettingbinding per discussion with compliance operator team. It should get generated at runtime --- charts/compliance-scanning/templates/scan-setting-binding.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/charts/compliance-scanning/templates/scan-setting-binding.yaml b/charts/compliance-scanning/templates/scan-setting-binding.yaml index a911f280..20d966be 100644 --- a/charts/compliance-scanning/templates/scan-setting-binding.yaml +++ b/charts/compliance-scanning/templates/scan-setting-binding.yaml @@ -5,8 +5,6 @@ metadata: namespace: openshift-compliance annotations: argocd.argoproj.io/sync-wave: '-10' - # Enable automatic remediation - compliance.openshift.io/default-auto-apply: "true" labels: app.kubernetes.io/component: compliance-scan-binding settingsRef: From e037fdb2030181632a64f51678dc6749c465386b Mon Sep 17 00:00:00 2001 From: Phil Osip Date: Mon, 8 Sep 2025 12:46:12 -0500 Subject: [PATCH 33/33] Removed the result viewer pod since user can see results directly form ComplianceCheckResults in Compliance Operator --- .../templates/results-viewer-pod.yaml | 38 ------------------- charts/compliance-scanning/values.yaml | 8 ---- 2 files changed, 46 deletions(-) delete mode 100644 charts/compliance-scanning/templates/results-viewer-pod.yaml diff --git a/charts/compliance-scanning/templates/results-viewer-pod.yaml b/charts/compliance-scanning/templates/results-viewer-pod.yaml deleted file mode 100644 index 7591e2ae..00000000 --- a/charts/compliance-scanning/templates/results-viewer-pod.yaml +++ /dev/null @@ -1,38 +0,0 @@ -{{- if and .Values.compliance.storage.enabled .Values.compliance.resultsViewer.enabled }} -apiVersion: v1 -kind: Pod -metadata: - name: {{ .Values.compliance.resultsViewer.name }} - namespace: openshift-compliance - annotations: - argocd.argoproj.io/sync-wave: '10' - labels: - app.kubernetes.io/component: results-viewer -spec: - # Use a service account with appropriate permissions - serviceAccountName: default - # Container to access compliance scan results - containers: - - name: results-viewer - image: {{ .Values.compliance.resultsViewer.image }} - # Command to keep container running and provide shell access - command: ["/bin/bash"] - args: ["-c", "sleep infinity"] - # Mount the PVC containing scan results - volumeMounts: - - name: compliance-results - mountPath: {{ .Values.compliance.resultsViewer.mountPath }} - # Environment variables for easier navigation - env: - - name: SCAN_RESULTS_PATH - value: {{ .Values.compliance.resultsViewer.mountPath }} - - name: PS1 - value: "[compliance-results] \\u@\\h:\\w\\$ " - # Volume referencing the PVC - volumes: - - name: compliance-results - persistentVolumeClaim: - claimName: {{ .Values.compliance.storage.pvc.name }} - # Restart policy - restartPolicy: Always -{{- end }} diff --git a/charts/compliance-scanning/values.yaml b/charts/compliance-scanning/values.yaml index 74eb10e8..de7b9789 100644 --- a/charts/compliance-scanning/values.yaml +++ b/charts/compliance-scanning/values.yaml @@ -30,14 +30,6 @@ compliance: storageClass: "" size: "2Gi" accessMode: "ReadWriteOnce" - # Results viewer image with access to oscap to create html output - resultsViewer: - enabled: true - name: compliance-results-viewer - # TBD make this one of the utility container images from VP team for performing the oscap operations on results - image: "registry.access.redhat.com/ubi9/ubi:latest" - # Mount path for scan results - mountPath: "/compliance-results" # Remediation job configuration remediationJob: # Job name