Post

Kubescape

Kubescape

Kubescape

Open-source Kubernetes security posture scanner from ARMO. Reads workloads, RBAC, and cluster-level objects straight through the current kubeconfig context — no in-cluster agent required — and grades them against compliance frameworks (NSA-CISA, MITRE ATT&CK) plus its own control set (misconfigurations, RBAC risk, hardening gaps). Used here for periodic, point-in-time audits of the k3s cluster rather than continuous in-cluster monitoring — see Homelab Infra for the cluster this scans.

Install

Official install script, arm64 build (matches the Pi this runs from):

1
2
curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | /bin/bash
export PATH=$PATH:$HOME/.kubescape/bin

Drops a single static binary at ~/.kubescape/bin/kubescape. Add the export line to ~/.bashrc to make it permanent. Verify:

1
kubescape version

No cluster-side install needed for ad-hoc scans — it just needs a working kubectl context with read access to the resources it’s scanning (cluster-admin or a broad read-only ClusterRole covers everything below).

Basic scan

1
kubescape scan

Scans every resource the current context can see, prints a per-control pass/fail table to the terminal, and ends with an overall compliance score (0–100, weighted by control severity and how many resources each control touches — not a simple pass/fail average). First run downloads the latest control definitions from ARMO’s regolibrary and caches them locally; subsequent runs reuse the cache unless --use-from or --update says otherwise.

Report formats

--format controls output shape, --output writes it to a file instead of stdout:

1
2
3
4
kubescape scan --format json --output results.json
kubescape scan --format pdf  --output results.pdf
kubescape scan --format junit --output results.xml   # CI pipelines
kubescape scan --format sarif --output results.sarif # GitHub/Gitea code scanning

json is the one worth keeping — it has the full per-resource, per-control breakdown (severity, category, pass/fail counts, fixPath suggestions) that the terminal and PDF output only summarize. The PDF is the one worth handing to someone who doesn’t want to open a JSON file.

Framework-specific scans

1
2
kubescape scan framework nsa
kubescape scan framework mitre

Same engine, filtered to just the controls that map to that framework. Useful when the ask is specifically “are we NSA-CISA compliant” rather than “what’s wrong in general” — the default kubescape scan already reports both frameworks’ scores in its summary, this just narrows the control list.

Scoping a scan

1
2
3
kubescape scan --include-namespaces default,longhorn-system
kubescape scan --exclude-namespaces kube-system
kubescape scan workload deployment/default/homeassistant

scan workload also pulls image vulnerability data for that specific workload (CVE scan), which the cluster-wide scan skips by default.

Reading the score

A single number hides a lot — a cluster can be “62/100” for very different reasons. Before acting on any finding, check whether it’s real for this resource:

  • Infra components that need the privilege they’re flagged for (a CSI driver needing hostPath, a load-balancer needing hostNetwork) aren’t bugs — kubescape can’t tell “required by design” from “misconfigured.”
  • Admin-tier ServiceAccounts (ArgoCD, Portainer, Longhorn) getting flagged for wildcard RBAC or secret access is usually working as intended — the actionable follow-up is tightening who can use that identity, not changing the RBAC itself.
  • Key-name pattern matches (C-0012, “credentials in configuration files”) flag on YAML keys like password: or token: regardless of whether the value is a real secret, a template placeholder, or an env-var reference — always check the actual value before treating it as a finding.

Kubescape’s own fixPath suggestions in the JSON output are reliable for the mechanical fixes (missing runAsGroup, missing resource limits); triage above is for deciding which findings are worth fixing at all.

How this is used here

No in-cluster operator — that would give continuous monitoring plus kubelet- level checks (C-0069/C-0070, which the CLI alone can’t evaluate: it needs hostdata.kubescape.cloud/v1beta0/KubeletInfo, only collected by the operator) but adds a persistent workload for a homelab cluster that doesn’t need it. Instead this is a periodic manual scan, both output formats saved locally with a yyyymmdd filename so successive scans are diffable:

1
2
kubescape scan --format json --output ./kubescape-results-$(date +%Y%m%d).json
kubescape scan --format pdf  --output ./kubescape-results-$(date +%Y%m%d).pdf

See the scan results post for the current findings and what’s actually worth fixing versus expected noise.

This post is licensed under CC BY 4.0 by the author.