Post

Kubescape Scan Results — 2026-09-24

Kubescape Scan Results — 2026-09-24

Kubescape Scan Results — 2026-09-24

Initial Kubescape audit of the k3s cluster (see Kubescape for install/usage). This is the baseline scan — first time the cluster’s been run through it — so the score and per-control table below are the starting point future scans get compared against. Raw output saved as both formats, dated:

1
2
kubescape/kubescape-results-20260924.json
kubescape/kubescape-results-20260924.pdf

Score

Overall compliance score: 62/100 — 341 resources passed, 164 failed, out of 505 scanned. NSA-CISA framework: 56.6%. MITRE ATT&CK: 56.9%.

Not a bad starting point for a cluster that’s never been through a dedicated security pass before — most of the gap traces back to a handful of repeated patterns rather than 164 unrelated problems, which the breakdown below digs into.

Reading the findings — what’s real vs. expected

Most of the 164 failed resources aren’t 164 separate problems. A handful of repeated patterns account for almost all of it:

  • Infra components flagged for privileges they need by design — Longhorn (hostPath + privileged, to manage block devices), MetalLB speaker / kube-vip (hostNetwork + NET_ADMIN/NET_RAW, for VIP/ARP announcements), Tailscale (NET_ADMIN, for its tunnel). Not misconfigurations. The two exceptions worth a second look: Deployment/default/homeassistant (hostNetwork) and Deployment/default/gitea-runner (privileged) — both likely intentional (mDNS discovery, container-in-container builds) but worth confirming.
  • Admin-tier ServiceAccounts flagged for wildcard RBAC / secret access (C-0187, C-0015) — ArgoCD’s application-controller, Portainer’s cluster-admin SA, Longhorn’s support-bundle SA, system:masters, plus built-in kube-system controllers. Working as intended; the actionable item is guarding access to use these identities, not changing their RBAC.
  • C-0012 “credentials in configuration files” — all 4 findings are false positives on key-name pattern matching (password:, token: keys whose values are template placeholders, empty env-var references, or a Reloader checksum, not real secrets).
  • C-0262 anonymous access — the single finding is the stock Kubernetes system:public-info-viewer binding present in most clusters by default, not something added here.

The genuinely actionable, not-yet-done work is the remaining ~26 own-app Deployments in C-0013/C-0017/C-0016/C-0055 (non-root, immutable FS, no privilege escalation, general hardening) that could reasonably take runAsNonRoot: true and related securityContext fields, plus the near-total absence of NetworkPolicy resources (C-0030/C-0260/C-0054) — meaningful defense-in-depth, but a bigger design task than a patch.

Full failed-control breakdown

SeverityControlFailedPassedCompliance %CategoryName
HighC-0015277874.3Access controlList Kubernetes secrets
HighC-0270263557.4WorkloadEnsure CPU limits are set
HighC-0271253659.0WorkloadEnsure memory limits are set
HighC-0045115082.0WorkloadWritable hostPath mount
HighC-0048115082.0WorkloadHostPath mount
HighC-02561010090.9—External facing
HighC-005785386.9WorkloadPrivileged container
HighC-004655691.8WorkloadInsecure capabilities
HighC-0012410596.3SecretsApplications credentials in configuration files
HighC-0187410196.2Access controlMinimize wildcard use in Roles and ClusterRoles
HighC-004135895.1WorkloadHostNetwork access
HighC-0262110199.0Control planeAnonymous access enabled
MediumC-00537800Access controlAccess container service account
MediumC-0034597355.3SecretsAutomatic mapping of service account
MediumC-0030502432.4NetworkIngress and Egress blocked
MediumC-0260507259.0NetworkMissing network policy
MediumC-0055491219.7WorkloadLinux hardening
MediumC-0013471423.0WorkloadNon-root containers
MediumC-0016461524.6WorkloadAllow privilege escalation
MediumC-0007327369.5Access controlRoles with delete capabilities
MediumC-0188139287.6Access controlMinimize access to create pods
MediumC-005412214.3NetworkCluster internal networking
MediumC-003199691.4Access controlDelete Kubernetes events
MediumC-003799691.4Access controlCoreDNS poisoning
MediumC-0002410196.2Access controlPrevent containers from allowing command execution
MediumC-0035410196.2Access controlAdministrative Roles
MediumC-0063410196.2Access controlPortforwarding privileges
MediumC-0039200Access controlValidate admission controller (mutating)
MediumC-0021100WorkloadExposed sensitive interfaces
LowC-0017471423.0WorkloadImmutable container filesystem
LowC-0036300Access controlValidate admission controller (validating)

Next steps

  1. Confirm homeassistant (hostNetwork) and gitea-runner (privileged) are intentional — everything else in the High-severity infra findings is expected behavior for Longhorn/MetalLB/kube-vip/Tailscale.
  2. Batch-add securityContext.runAsNonRoot: true (and related hardening fields) across the ~26 own-app Deployments still missing it — template-first via a shared PodSecurityContext default for new workloads, rather than resource-by-resource.
  3. NetworkPolicy coverage is the next big structural gap — currently almost nonexistent — but it’s a design task for a future pass, not a quick fix.
This post is licensed under CC BY 4.0 by the author.