In August 2019, the Cloud Native Computing Foundation published the results of the first comprehensive third-party security audit of Kubernetes, performed by Trail of Bits and Atredis Partners. The audit team catalogued 37 findings across kube-apiserver, etcd, kube-scheduler, kubelet, kube-proxy, and the container runtime interface — everything from insecure defaults to gaps in audit logging. None of it was theoretical: the audit followed CVE-2018-1002105, a CVSS 9.8 privilege-escalation flaw in kube-apiserver's proxy request handling that let any authenticated user achieve full cluster compromise via crafted WebSocket requests. Seven years later, the patterns that audit surfaced — permissive defaults, flat networking, unencrypted secrets — still show up in production clusters we scan today. This post breaks down what the audit actually found, what changed as a result, and what it still tells security teams about the gap between "Kubernetes is secure" and "your Kubernetes deployment is secure."
What was the CNCF Kubernetes security audit and why did it happen?
The audit was a CNCF-funded, third-party penetration test and code review of Kubernetes core components, conducted by Trail of Bits and Atredis Partners and published August 6, 2019. The CNCF commissioned it in the wake of CVE-2018-1002105 — discovered by Rancher co-founder Darren Shepherd in December 2018 — which showed that a single unauthenticated API request could escalate to full administrative control of any Kubernetes cluster running a vulnerable version. That CVE was patched within days, but it exposed how little independent scrutiny the project's authentication and authorization paths had received relative to its blast radius. The resulting engagement scoped in kube-apiserver, etcd, kube-scheduler, kubelet, kube-proxy, and the boundaries between the container runtime and the control plane, plus a companion "Kubernetes Threat Model" document meant to give the community a durable framework for reasoning about trust boundaries rather than a one-time punch list.
What did the audit find wrong with Kubernetes' default configuration?
The core finding was that Kubernetes shipped secure capabilities but insecure defaults, putting the burden of hardening entirely on the operator. Three examples drove that point home: etcd stored Secrets objects in plaintext by default, meaning anyone with etcd access — including through misconfigured backups — could read every credential in the cluster without ever touching the API server's RBAC layer. Kubelet's read-only port (10255) and its main API port (10250) could run with anonymous authentication enabled, letting unauthenticated network access retrieve pod specs, environment variables, and in some configurations execute commands inside containers. And Pod Security Policy, the admission controller meant to restrict privileged workloads, was disabled by default and, even when enabled, was widely misconfigured — a problem serious enough that Kubernetes deprecated PSP entirely in 1.21 (April 2021) and removed it in 1.25 (August 2022) in favor of the built-in Pod Security Standards.
How did unauthenticated kubelet access become a real-world attack path?
It became a path because internet-facing clusters left kubelet's API reachable without credentials, turning a "default" into an exposed service. Security researchers scanning IPv4 space in 2018-2019 (including work cited in the audit) repeatedly found thousands of kubelet endpoints answering unauthenticated requests on port 10250, several of which allowed the /exec and /run endpoints to execute arbitrary commands in running containers. This wasn't a bug in the strict sense — anonymous auth was a documented, intentional default for backward compatibility — but the audit called it out as a case where the secure path required operator knowledge that most teams didn't have. Post-audit, Kubernetes moved anonymous kubelet auth toward opt-in in hardening guides and CIS Benchmarks began flagging it directly, but the underlying lesson holds for any platform default: an attacker doesn't need a zero-day when the shipped configuration already grants access.
Why does Kubernetes' flat network model matter for lateral movement?
It matters because, without a NetworkPolicy resource applied, every pod in a cluster can reach every other pod on any port by default. The audit flagged this explicitly: Kubernetes ships no default-deny network posture, so a single compromised container in a low-value namespace can, in most out-of-the-box clusters, reach the metadata service, internal admin tools, or a database pod running in a completely unrelated namespace. This is the same class of issue that made the 2019 Capital One breach so damaging once an attacker got a foothold via a misconfigured web application firewall — lateral movement was gated by IAM policy scope, not network segmentation. In Kubernetes specifically, NetworkPolicy requires both a CNI plugin that enforces it (Calico, Cilium, or similar — not all CNIs do) and an explicit policy authored per namespace, which is why "we're on Kubernetes" and "we have network segmentation" remain two different claims.
What changed in Kubernetes after the audit?
The most concrete change was structural: the audit's recommendations helped seed the formation of Kubernetes SIG Security and the Security Response Committee, giving the project standing infrastructure for triaging vulnerabilities instead of ad hoc response. On the technical side, encryption at rest for Secrets became a documented, supported configuration (EncryptionConfiguration) rather than an obscure flag, kubelet's default authentication posture got locked down in setup tooling like kubeadm, and audit logging — called out as thin in 2019 — was expanded with structured audit policies in later 1.x releases. A second CNCF-funded review effort followed in subsequent years focused on the broader supply chain around Kubernetes distributions and build tooling, reflecting a shift in where the CNCF security program believes the highest-leverage risk now sits: not just in core control-plane code, but in everything that builds, packages, and deploys it.
What does the 2019 audit still tell us about container security today?
It tells us that the riskiest part of Kubernetes has never been a zero-day in etcd — it's the gap between what the platform supports and what a given cluster actually enforces. Every finding in that report — plaintext secrets, anonymous kubelet access, flat networking, permissive pod security — was a configuration choice available to fix at the time, not a code defect requiring a patch. That gap is exactly what shows up in real audits six years later: teams running Kubernetes 1.28+ with modern Pod Security Standards available but not enforced, NetworkPolicy-capable CNIs installed with zero policies applied, and Secrets encryption documented but never turned on. The lesson generalizes past Kubernetes: platform security capability and deployed security posture are different measurements, and only one of them is visible from a version number.
How Safeguard Helps
Safeguard maps these exact gaps continuously instead of leaving them for the next point-in-time audit. Our reachability analysis traces whether a vulnerable path in a container image or dependency is actually invoked by running workloads and exposed through the cluster's real network topology, so a permissive NetworkPolicy or an unauthenticated service isn't just flagged — it's connected to what it can actually reach. Griffin AI correlates Kubernetes configuration state (RBAC bindings, pod security context, encryption settings) against live CVE and exploit intelligence to prioritize the handful of misconfigurations that matter over the hundreds that don't. Safeguard generates and ingests SBOMs across image layers and Kubernetes manifests to give teams a durable inventory instead of a one-time snapshot, and where a fix is unambiguous — an anonymous auth flag, a missing default-deny policy, an unencrypted Secrets config — Safeguard opens an auto-fix PR so the remediation ships as fast as the finding does.