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) andDeployment/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-inkube-systemcontrollers. 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-0262anonymous access — the single finding is the stock Kubernetessystem:public-info-viewerbinding 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
| Severity | Control | Failed | Passed | Compliance % | Category | Name |
|---|---|---|---|---|---|---|
| High | C-0015 | 27 | 78 | 74.3 | Access control | List Kubernetes secrets |
| High | C-0270 | 26 | 35 | 57.4 | Workload | Ensure CPU limits are set |
| High | C-0271 | 25 | 36 | 59.0 | Workload | Ensure memory limits are set |
| High | C-0045 | 11 | 50 | 82.0 | Workload | Writable hostPath mount |
| High | C-0048 | 11 | 50 | 82.0 | Workload | HostPath mount |
| High | C-0256 | 10 | 100 | 90.9 | — | External facing |
| High | C-0057 | 8 | 53 | 86.9 | Workload | Privileged container |
| High | C-0046 | 5 | 56 | 91.8 | Workload | Insecure capabilities |
| High | C-0012 | 4 | 105 | 96.3 | Secrets | Applications credentials in configuration files |
| High | C-0187 | 4 | 101 | 96.2 | Access control | Minimize wildcard use in Roles and ClusterRoles |
| High | C-0041 | 3 | 58 | 95.1 | Workload | HostNetwork access |
| High | C-0262 | 1 | 101 | 99.0 | Control plane | Anonymous access enabled |
| Medium | C-0053 | 78 | 0 | 0 | Access control | Access container service account |
| Medium | C-0034 | 59 | 73 | 55.3 | Secrets | Automatic mapping of service account |
| Medium | C-0030 | 50 | 24 | 32.4 | Network | Ingress and Egress blocked |
| Medium | C-0260 | 50 | 72 | 59.0 | Network | Missing network policy |
| Medium | C-0055 | 49 | 12 | 19.7 | Workload | Linux hardening |
| Medium | C-0013 | 47 | 14 | 23.0 | Workload | Non-root containers |
| Medium | C-0016 | 46 | 15 | 24.6 | Workload | Allow privilege escalation |
| Medium | C-0007 | 32 | 73 | 69.5 | Access control | Roles with delete capabilities |
| Medium | C-0188 | 13 | 92 | 87.6 | Access control | Minimize access to create pods |
| Medium | C-0054 | 12 | 2 | 14.3 | Network | Cluster internal networking |
| Medium | C-0031 | 9 | 96 | 91.4 | Access control | Delete Kubernetes events |
| Medium | C-0037 | 9 | 96 | 91.4 | Access control | CoreDNS poisoning |
| Medium | C-0002 | 4 | 101 | 96.2 | Access control | Prevent containers from allowing command execution |
| Medium | C-0035 | 4 | 101 | 96.2 | Access control | Administrative Roles |
| Medium | C-0063 | 4 | 101 | 96.2 | Access control | Portforwarding privileges |
| Medium | C-0039 | 2 | 0 | 0 | Access control | Validate admission controller (mutating) |
| Medium | C-0021 | 1 | 0 | 0 | Workload | Exposed sensitive interfaces |
| Low | C-0017 | 47 | 14 | 23.0 | Workload | Immutable container filesystem |
| Low | C-0036 | 3 | 0 | 0 | Access control | Validate admission controller (validating) |
Next steps
- Confirm
homeassistant(hostNetwork) andgitea-runner(privileged) are intentional — everything else in the High-severity infra findings is expected behavior for Longhorn/MetalLB/kube-vip/Tailscale. - 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. NetworkPolicycoverage is the next big structural gap — currently almost nonexistent — but it’s a design task for a future pass, not a quick fix.