Skip to content

feat: add SBOM scanner sidecar container to node-agent pod#802

Merged
matthyx merged 3 commits intomainfrom
feature/sbom-scanner-sidecar
Apr 2, 2026
Merged

feat: add SBOM scanner sidecar container to node-agent pod#802
matthyx merged 3 commits intomainfrom
feature/sbom-scanner-sidecar

Conversation

@slashben
Copy link
Copy Markdown
Contributor

@slashben slashben commented Mar 18, 2026

Summary

  • SBOM scanner sidecar: Adds Helm chart support for deploying the SBOM scanner as a sidecar container in the node-agent pod, enabling memory-isolated SBOM generation via Syft
  • Configuration under nodeAgent: All sidecar config lives at nodeAgent.sbomScanner in values.yaml, keeping node-agent pod config co-located
  • Autoscaler aware: The sidecar is excluded from autoscaler-generated templates (includeSbomScanner: false), matching the ClamAV pattern

Changes

File Change
values.yaml Add nodeAgent.sbomScanner config (enabled, image, command, resources, volumeMounts, volumes)
_node-agent.tpl Add sbomScannerContainer template, wire into podSpec containers, add sbom-comm volume/mount, add env vars
_common.tpl Add sbomScanner.enabled component flag
daemonset.yaml Pass includeSbomScanner: true
daemonsets.yaml Pass includeSbomScanner: true
template-configmap.yaml Pass includeSbomScanner: false (autoscaler)

Companion PR

Test plan

  • helm lint passes
  • helm template renders sidecar container with correct image, command, resources, env vars, and volumes
  • Autoscaler template correctly excludes the sidecar
  • Sidecar only renders when capabilities.nodeSbomGeneration=enable and nodeAgent.sbomScanner.enabled=true
  • Integration test in staging cluster

Made with Cursor

Summary by CodeRabbit

  • New Features
    • Added an optional SBOM scanner sidecar for the node agent. It can be enabled via Helm values, exposes configurable resource limits, environment variables for scanner runtime, and mounts for SBOM communication and host access. When enabled, the scanner is included alongside existing optional scanning components without changing their defaults.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

Adds an optional SBOM scanner sidecar to the node-agent Helm chart. Enablement is computed from capabilities.nodeSbomGeneration == "enable" AND nodeAgent.sbomScanner.enabled. Templates, daemonset inputs, pod spec, env vars, volumes, and default values for the scanner are introduced.

Changes

Cohort / File(s) Summary
Component Configuration
charts/kubescape-operator/templates/_common.tpl
Adds components.sbomScanner with enabled set to and (eq .Values.capabilities.nodeSbomGeneration "enable") .Values.nodeAgent.sbomScanner.enabled.
Node Agent Templates
charts/kubescape-operator/templates/node-agent/_node-agent.tpl
Adds node-agent.sbomScannerContainer template, injects SBOM_SCANNER_SOCKET and SCANNER_MEMORY_LIMIT envs, conditional sbom-comm mounts/volumes, and wires includeSbomScanner into podSpec to include the sidecar.
DaemonSet Specifications
charts/kubescape-operator/templates/node-agent/daemonset.yaml, charts/kubescape-operator/templates/node-agent/daemonsets.yaml
Passes includeSbomScanner: true into daemonset/daemonsets spec generation to enable the SBOM sidecar in generated manifests.
Template Configuration
charts/kubescape-operator/templates/node-agent/template-configmap.yaml
Adds includeSbomScanner: false to the template-configmap payload (defaulted false in that context).
Default Values
charts/kubescape-operator/values.yaml
Introduces nodeAgent.sbomScanner block: enabled, name, image/command, resources (requests/limits), volumeMounts for /sbom-comm and /host, and sbom-comm emptyDir (Memory, 10Mi).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped into charts at dawn’s first light,
A sidecar tucked close to scan the night.
Volumes and sockets, memory set just so,
I hum as SBOMs through the podflows go.
Hooray—small changes, big traces in tow!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding an SBOM scanner sidecar container to the node-agent pod, which is the core objective of this Helm chart enhancement.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/sbom-scanner-sidecar

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
charts/kubescape-operator/templates/node-agent/_node-agent.tpl (1)

64-69: Use includeSbomScanner as the single toggle across env/mounts/volumes too.

Right now, Line 517 controls sidecar container inclusion, but Lines 64-69, 137-140, and 369-373 are still controlled only by values/capability checks. Threading includeSbomScanner into those helpers will keep behavior consistent and avoid partial SBOM wiring without the sidecar.

♻️ Suggested refactor
 {{- define "node-agent.env" -}}
@@
-{{- if and (eq .Values.capabilities.nodeSbomGeneration "enable") .Values.nodeAgent.sbomScanner.enabled (not .autoscalerMode) }}
+{{- if and .includeSbomScanner .components.sbomScanner.enabled (not .autoscalerMode) }}
 - name: SBOM_SCANNER_SOCKET
   value: "/sbom-comm/scanner.sock"
 - name: SCANNER_MEMORY_LIMIT
   value: "{{ .Values.nodeAgent.sbomScanner.resources.limits.memory }}"
 {{- end }}

 {{- define "node-agent.volumeMounts" -}}
@@
-{{- if and (eq .Values.capabilities.nodeSbomGeneration "enable") .Values.nodeAgent.sbomScanner.enabled }}
+{{- if and .includeSbomScanner .components.sbomScanner.enabled }}
 - name: sbom-comm
   mountPath: /sbom-comm
 {{- end }}

 {{- define "node-agent.volumes" -}}
@@
-{{- if and (eq .Values.capabilities.nodeSbomGeneration "enable") .Values.nodeAgent.sbomScanner.enabled }}
+{{- if and .includeSbomScanner .components.sbomScanner.enabled }}
 {{- if .Values.nodeAgent.sbomScanner.volumes }}
 {{ toYaml .Values.nodeAgent.sbomScanner.volumes | trim }}
 {{- end }}
 {{- end }}

 {{- define "node-agent.container" -}}
@@
-    {{- include "node-agent.env" (dict "Values" .Values "components" .components "no_proxy_envar_list" .no_proxy_envar_list "autoscalerMode" .autoscalerMode "testingMode" .testingMode) | nindent 4 }}
+    {{- include "node-agent.env" (dict "Values" .Values "components" .components "no_proxy_envar_list" .no_proxy_envar_list "autoscalerMode" .autoscalerMode "testingMode" .testingMode "includeSbomScanner" .includeSbomScanner) | nindent 4 }}
@@
-    {{- include "node-agent.volumeMounts" (dict "Values" .Values "components" .components) | nindent 4 }}
+    {{- include "node-agent.volumeMounts" (dict "Values" .Values "components" .components "includeSbomScanner" .includeSbomScanner) | nindent 4 }}

 {{- define "node-agent.podSpec" -}}
@@
-volumes:
-{{ include "node-agent.volumes" (dict "Values" .Values "components" .components) | trim | nindent 0 }}
+volumes:
+{{ include "node-agent.volumes" (dict "Values" .Values "components" .components "includeSbomScanner" .includeSbomScanner) | trim | nindent 0 }}
@@
-{{ include "node-agent.container" (dict "Values" .Values "components" .components "no_proxy_envar_list" .no_proxy_envar_list "autoscalerMode" .autoscalerMode "testingMode" .testingMode "resources" .resources) | trim | nindent 0 }}
+{{ include "node-agent.container" (dict "Values" .Values "components" .components "no_proxy_envar_list" .no_proxy_envar_list "autoscalerMode" .autoscalerMode "testingMode" .testingMode "resources" .resources "includeSbomScanner" .includeSbomScanner) | trim | nindent 0 }}

Also applies to: 137-140, 369-373, 517-519, 566-566

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/kubescape-operator/templates/node-agent/_node-agent.tpl` around lines
64 - 69, The env vars and mounts for the SBOM scanner (e.g., SBOM_SCANNER_SOCKET
and SCANNER_MEMORY_LIMIT) are gated by capability/value checks but not by the
includeSbomScanner toggle, which can lead to orphaned wiring when the sidecar is
omitted; update the template helpers and conditionals that render these blocks
(the helpers/sections rendering SBOM_SCANNER_SOCKET, SCANNER_MEMORY_LIMIT, the
mounts and volumes at the other mentioned locations) to require
includeSbomScanner to be true in addition to the existing checks (i.e., replace
or augment conditions like and (eq .Values.capabilities.nodeSbomGeneration
"enable") .Values.nodeAgent.sbomScanner.enabled with and (includeSbomScanner)
(eq .Values.capabilities.nodeSbomGeneration "enable")
.Values.nodeAgent.sbomScanner.enabled) so env/mount/volume fragments are only
emitted when the sidecar is actually included.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@charts/kubescape-operator/templates/node-agent/daemonset.yaml`:
- Line 36: The helm-unittest snapshots need updating because the DaemonSet
template node-agent/daemonset.yaml changed (the spec input now includes
"includeSbomScanner" true); run the helm-unittest tests for the
charts/kubescape-operator chart (including multi-daemonset variants), regenerate
the failing snapshot files, review the new rendered outputs for
node-agent/daemonset.yaml to confirm the includeSbomScanner change is expected,
and commit the updated snapshot files alongside this PR.

---

Nitpick comments:
In `@charts/kubescape-operator/templates/node-agent/_node-agent.tpl`:
- Around line 64-69: The env vars and mounts for the SBOM scanner (e.g.,
SBOM_SCANNER_SOCKET and SCANNER_MEMORY_LIMIT) are gated by capability/value
checks but not by the includeSbomScanner toggle, which can lead to orphaned
wiring when the sidecar is omitted; update the template helpers and conditionals
that render these blocks (the helpers/sections rendering SBOM_SCANNER_SOCKET,
SCANNER_MEMORY_LIMIT, the mounts and volumes at the other mentioned locations)
to require includeSbomScanner to be true in addition to the existing checks
(i.e., replace or augment conditions like and (eq
.Values.capabilities.nodeSbomGeneration "enable")
.Values.nodeAgent.sbomScanner.enabled with and (includeSbomScanner) (eq
.Values.capabilities.nodeSbomGeneration "enable")
.Values.nodeAgent.sbomScanner.enabled) so env/mount/volume fragments are only
emitted when the sidecar is actually included.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0c401786-dfa9-4b1a-80f7-ac0fc86a2aa2

📥 Commits

Reviewing files that changed from the base of the PR and between a1eab50 and 3c5ae4a.

📒 Files selected for processing (6)
  • charts/kubescape-operator/templates/_common.tpl
  • charts/kubescape-operator/templates/node-agent/_node-agent.tpl
  • charts/kubescape-operator/templates/node-agent/daemonset.yaml
  • charts/kubescape-operator/templates/node-agent/daemonsets.yaml
  • charts/kubescape-operator/templates/node-agent/template-configmap.yaml
  • charts/kubescape-operator/values.yaml

Comment thread charts/kubescape-operator/templates/node-agent/daemonset.yaml
@matthyx matthyx moved this to Needs Reviewer in KS PRs tracking Mar 31, 2026
slashben and others added 3 commits April 2, 2026 12:04
Add Helm chart support for the SBOM scanner sidecar that runs Syft
in a separate container with its own memory cgroup. Configuration is
nested under nodeAgent.sbomScanner in values.yaml.

- Add nodeAgent.sbomScanner section in values.yaml (enabled, image, resources, volumes)
- Add sbomScannerContainer template in _node-agent.tpl with GOMEMLIMIT downward API
- Wire sidecar into podSpec containers, volumes, and volumeMounts
- Add SBOM_SCANNER_SOCKET and SCANNER_MEMORY_LIMIT env vars to main container
- Add sbomScanner component flag in _common.tpl
- Exclude sidecar from autoscaler template (includeSbomScanner: false)

Made-with: Cursor
Signed-off-by: Ben <ben@armosec.io>

# Conflicts:
#	charts/kubescape-operator/values.yaml
Signed-off-by: Ben <ben@armosec.io>
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
@matthyx matthyx force-pushed the feature/sbom-scanner-sidecar branch from 8ab94e4 to 4331bc9 Compare April 2, 2026 10:21
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
charts/kubescape-operator/templates/node-agent/_node-agent.tpl (1)

259-295: Health probes are consistent with chart's sidecar design pattern, though adding them would be a best practice.

The missing liveness/readiness probes match the pattern used for other sidecars in this chart (e.g., ClamAV container at lines 240-257 also lacks probes). However, since the main node-agent container has comprehensive HTTP probes (lines 195-211), adding basic probes to the sbomScanner would improve observability:

  • Optional: Add readiness/liveness probes if the scanner exposes a health endpoint or socket availability check (e.g., probe the /sbom-comm/scanner.sock socket path).

Regarding capabilities: The drop: ["ALL"] restriction is appropriate. The sbomScanner doesn't directly access the host filesystem—it communicates via a shared volume (/sbom-comm) and receives the host path only as an environment variable (HOST_ROOT). Direct hostPath mounting is handled by the main container.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/kubescape-operator/templates/node-agent/_node-agent.tpl` around lines
259 - 295, Add optional liveness/readiness probes to the
node-agent.sbomScannerContainer template: introduce a conditional flag
.Values.nodeAgent.sbomScanner.probes.enabled and, when set, render livenessProbe
and readinessProbe under the sbom scanner container (inside the define
"node-agent.sbomScannerContainer"). If the scanner exposes a Unix socket use an
exec probe like ["sh","-c","test -S /sbom-comm/scanner.sock"] (or use httpGet to
the health endpoint if one exists) and keep probe settings (initialDelaySeconds,
periodSeconds, failureThreshold) configurable via
.Values.nodeAgent.sbomScanner.probes.*; render them with toYaml / nindent
consistent with the existing container fields so the probes appear alongside
env, resources, and volumeMounts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@charts/kubescape-operator/templates/node-agent/_node-agent.tpl`:
- Around line 259-295: Add optional liveness/readiness probes to the
node-agent.sbomScannerContainer template: introduce a conditional flag
.Values.nodeAgent.sbomScanner.probes.enabled and, when set, render livenessProbe
and readinessProbe under the sbom scanner container (inside the define
"node-agent.sbomScannerContainer"). If the scanner exposes a Unix socket use an
exec probe like ["sh","-c","test -S /sbom-comm/scanner.sock"] (or use httpGet to
the health endpoint if one exists) and keep probe settings (initialDelaySeconds,
periodSeconds, failureThreshold) configurable via
.Values.nodeAgent.sbomScanner.probes.*; render them with toYaml / nindent
consistent with the existing container fields so the probes appear alongside
env, resources, and volumeMounts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 60a0a9bf-2423-4111-a5c8-c35d055c0b18

📥 Commits

Reviewing files that changed from the base of the PR and between 3c5ae4a and 4331bc9.

⛔ Files ignored due to path filters (1)
  • charts/kubescape-operator/tests/__snapshot__/snapshot_test.yaml.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • charts/kubescape-operator/templates/_common.tpl
  • charts/kubescape-operator/templates/node-agent/_node-agent.tpl
  • charts/kubescape-operator/templates/node-agent/daemonset.yaml
  • charts/kubescape-operator/templates/node-agent/daemonsets.yaml
  • charts/kubescape-operator/templates/node-agent/template-configmap.yaml
  • charts/kubescape-operator/values.yaml
✅ Files skipped from review due to trivial changes (1)
  • charts/kubescape-operator/templates/node-agent/template-configmap.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
  • charts/kubescape-operator/templates/node-agent/daemonset.yaml
  • charts/kubescape-operator/templates/_common.tpl
  • charts/kubescape-operator/templates/node-agent/daemonsets.yaml

@matthyx matthyx merged commit f2ef870 into main Apr 2, 2026
9 checks passed
@matthyx matthyx deleted the feature/sbom-scanner-sidecar branch April 2, 2026 10:32
@matthyx matthyx moved this from Needs Reviewer to To Archive in KS PRs tracking Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants