This is unreleased documentation for SBOM Scanner 0.12-dev.

Scanning Nodes

Overview

SBOM Scanner can scan container images through Registry configurations and workload scanning, but the security posture of a cluster also depends on the nodes themselves. Nodes run the operating system, the container runtime, the kubelet, and other system-level packages that are invisible to image-based scanners.

The Node Scan feature closes this gap. It deploys a worker on every eligible node as a DaemonSet, scans the host filesystem, and produces a NodeSBOM and a NodeVulnerabilityReport per node. This gives you a comprehensive overview of node-level vulnerabilities, ensuring the safety of the infrastructure where your workloads reside.

How it works

  1. A NodeScanConfiguration resource defines the global scan settings (interval, node selector, skip patterns, platforms).

  2. The controller creates a NodeScanJob for each matching node, either on a recurring schedule or on demand.

  3. Each worker, running as a DaemonSet pod on the target node, receives the scan request through NATS and scans the host filesystem.

  4. The worker generates a NodeSBOM (in SPDX format) and a NodeVulnerabilityReport, stored in the Storage API Extension Server.

Default behavior

The Node Scan reconcilers are enabled by default when installing SBOM Scanner via the Helm chart. Node scanning becomes active once you create a NodeScanConfiguration resource. A sample configuration is available in the examples folder.

Configuration

The NodeScanConfiguration is a cluster-scoped singleton resource named default. It is the single entry point for controlling the node scanning behavior. Only one instance is allowed.

To activate node scanning after installation, apply the example configuration:

kubectl apply -f https://raw.githubusercontent.com/kubewarden/sbomscanner/main/examples/nodescanconfiguration.yaml

Or create your own configuration:

apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: NodeScanConfiguration
metadata:
  name: default
spec:
  scanInterval: 5m
  nodeSelector:
    matchExpressions:
      - key: kubernetes.io/hostname
        operator: In
        values:
          - "node1"
          - "node2"
  skipPatterns:
    - "/run/k3s/containerd/"
  platforms:
    - arch: "amd64"
      os: "linux"

Fields

Field Description Default

scanInterval

How often nodes are scanned. If not specified, automatic scanning is disabled and you must create NodeScanJob resources manually.

-

nodeSelector

A standard Kubernetes label selector. Only nodes matching the selector are scanned.

All nodes

skipPatterns

Gitignore-style patterns for files and directories to exclude from the scan. Patterns ending with / are treated as directories, all others as files. Glob patterns like **/vendor/ or *.min.js are supported.

-

platforms

Which OS/architecture combinations to scan. Each entry specifies an arch and os field.

All platforms

Selecting which nodes to scan

Use the nodeSelector field to restrict scanning to a subset of nodes. This is useful when some nodes do not have enough resources for scanning or when you only want to target specific node pools.

Scan only nodes with a specific label:

spec:
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/worker: ""

Scan specific nodes by hostname:

spec:
  nodeSelector:
    matchExpressions:
      - key: kubernetes.io/hostname
        operator: In
        values:
          - "worker-1"
          - "worker-2"

If nodeSelector is omitted, all nodes in the cluster are scanned.

Excluding files and directories

The skipPatterns field accepts gitignore-style patterns to exclude paths from the filesystem scan. This is useful to reduce noise or avoid scanning sensitive or irrelevant paths.

spec:
  skipPatterns:
    - "/run/k3s/containerd/"
    - "/tmp/"
    - ".git/"
    - "node_modules/"
    - "*.min.js"
    - "package-lock.json"

Patterns ending with / match directories. All other patterns match files. Glob patterns such as **/vendor/ are supported.

Scanning specific platforms

By default, SBOM Scanner scans all nodes regardless of their platform. In clusters with mixed architectures, you can restrict scanning to specific OS/architecture combinations:

spec:
  platforms:
    - arch: "amd64"
      os: "linux"
    - arch: "arm64"
      os: "linux"

Running a scan on demand

You can trigger a one-time scan by creating a NodeScanJob resource manually. A NodeScanConfiguration must already exist in the cluster, since the job depends on its settings (skip patterns, platforms).

apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: NodeScanJob
metadata:
  name: scan-worker-1
spec:
  nodeName: worker-1

Apply the job:

kubectl apply -f nodescanjob.yaml

If another NodeScanJob is already in progress for the same node, the new job is marked as Failed with the reason ScanAlreadyInProgress.

Triggering an immediate rescan

To bypass the scan interval timer and trigger an immediate rescan of all matching nodes, annotate the NodeScanConfiguration:

kubectl annotate nodescanconfiguration default \
  sbomscanner.kubewarden.io/node-rescan-requested=true

The annotation is removed automatically after the scan jobs are created.

Monitoring scan progress

Check the status of node scan jobs:

kubectl get nodescanjobs

Example output:

NAME              STATUS       REASON       AGE
scan-worker-1     Complete     Complete     5m
scan-worker-2     InProgress   InProgress   1m

Get detailed status of a specific job:

kubectl get nodescanjob scan-worker-1 -o yaml

Example status:

status:
  startTime: "2026-06-01T10:00:00Z"
  completionTime: "2026-06-01T10:02:30Z"
  conditions:
    - type: Complete
      status: "True"
      reason: Complete
      message: "NodeScanJob completed successfully"
    - type: Failed
      status: "False"
      reason: Complete
    - type: InProgress
      status: "False"
      reason: Complete
    - type: Scheduled
      status: "False"
      reason: Complete

Status conditions

Each NodeScanJob has status conditions that track the scan lifecycle:

Status Meaning

Scheduled

The system has accepted the request and scheduled the scan.

InProgress

The scan is actively running on the node.

Complete

The scan finished successfully. The NodeSBOM and NodeVulnerabilityReport are available.

Failed

The scan encountered a terminal error. Check the condition’s reason and message for details.

Common failure reasons:

Reason Description

ScanAlreadyInProgress

Another scan job is already running for the same node.

NodeScanConfigurationMissing

No NodeScanConfiguration resource exists in the cluster.

NodeNotMatching

The target node does not match the nodeSelector defined in the configuration.

InternalError

An unexpected error occurred during the scan.

Viewing results

NodeSBOM

Once a scan completes, a NodeSBOM resource is created containing the Software Bill of Materials in SPDX format.

List node SBOMs:

kubectl get nodesboms

Query by node name:

kubectl get nodesboms --field-selector='nodeMetadata.name=worker-1'

Query by platform:

kubectl get nodesboms --field-selector='nodeMetadata.platform=linux/amd64'

View the full SBOM:

kubectl get nodesbom worker-node-1 -o yaml

Example output (truncated):

apiVersion: storage.sbomscanner.kubewarden.io/v1alpha1
kind: NodeSBOM
metadata:
  name: worker-node-1
nodeMetadata:
  name: worker-node-1
  platform: linux/amd64
spdx:
  spdxVersion: SPDX-2.3
  dataLicense: CC0-1.0
  name: worker-node-1
  packages:
    - name: libc6
      versionInfo: 2.39-0ubuntu8.3
      primaryPackagePurpose: LIBRARY
    - name: containerd
      versionInfo: 1.7.24-0ubuntu1~24.04.1
      primaryPackagePurpose: APPLICATION
    - name: kubelet
      versionInfo: 1.31.2-1.1
      primaryPackagePurpose: APPLICATION

NodeVulnerabilityReport

The vulnerability analysis results are stored in NodeVulnerabilityReport resources.

List node vulnerability reports:

kubectl get nodevulnerabilityreports

Query by node name:

kubectl get nodevulnerabilityreports --field-selector='nodeMetadata.name=worker-1'

View the full report:

kubectl get nodevulnerabilityreport worker-node-1 -o yaml

Supported nodeMetadata fields

NodeSBOM and NodeVulnerabilityReport resources share a common nodeMetadata field. These fields are useful when filtering resources with kubectl get --field-selector.

Field Type Description

name

string

The name of the node in the cluster.

platform

string

The OS and CPU architecture of the node, in OS/ARCH format. Example: linux/amd64.