Back

K06: Broken Authentication Mechanisms - Overview

What is Broken Authentication?

Broken Authentication Mechanisms (K06 in the OWASP Kubernetes Top 10) is the condition of running a cluster where the question “who is making this request?” is answered weakly, incompletely, or not at all. Kubernetes does not authenticate requests by itself—it delegates the decision to a chain of pluggable methods (client certificates, bearer tokens, ServiceAccount tokens, OIDC, and authenticating proxies). When any link in that chain is disabled, misconfigured, overly trusting, or protected by long-lived shared secrets, an attacker can present as a legitimate identity—or as no identity at all—and still be let in.

Authentication is the first gate in the Kubernetes request pipeline. Every call to the API server passes through authentication, then authorization (RBAC, K03), then admission control. If authentication is broken, RBAC never gets a real subject to reason about: a request that arrives as system:anonymous or as a stolen system:serviceaccount:* identity is evaluated against that identity’s permissions, not the attacker’s. Break the first gate and every downstream control is reasoning about the wrong principal.

Authentication answers who you are; authorization (K03) answers what you may do. K06 is about the former. A perfect RBAC policy is worthless if an attacker can walk through the door wearing a valid badge—or with no badge at all because the guard was told to wave everyone through.

Core Concept

Cluster that verifies identity:
  API server     -> anonymous auth disabled; every request maps to a
                    real, named subject or is rejected 401
  Humans         -> OIDC / SSO with MFA, short-lived tokens, group claims
  Workloads      -> projected ServiceAccount tokens: short-lived, audience-
                    bound, auto-rotated (TokenRequest API)
  Kubelet        -> its own API (10250) requires auth + authz, no anonymous
  etcd           -> mutual TLS, client certs, never exposed to the network
  Certificates   -> scoped, rotated, revocable; no shared cluster-admin certs

Cluster with broken authentication:
  API server     -> --anonymous-auth=true: system:anonymous reaches the API
  Humans         -> one shared kubeconfig with an embedded cluster-admin cert
                    that never expires and cannot be revoked
  Workloads      -> legacy non-expiring SA token secrets, mounted everywhere
  Kubelet        -> 10250 open with --anonymous-auth=true: exec/logs to anyone
  etcd           -> plaintext or no client-cert auth, reachable on the network
  Certificates   -> one long-lived admin cert copied between laptops and CI

Why It’s Critical for Kubernetes

Kubernetes concentrates several conditions that make broken authentication uniquely dangerous:

Why Does This Matter?

Business Impact

Technical Impact

Technical Context

How Kubernetes Authenticates a Request

When a request reaches the API server, the authentication layer runs each configured method in turn until one succeeds. The result is a username and a set of groups; that identity is then handed to authorization. If no method succeeds, the request is either rejected with 401 or—if anonymous auth is enabled—treated as the anonymous identity.

Request --> [ Authentication ] --> username + groups --> [ Authorization (RBAC) ] --> [ Admission ] --> etcd

Authenticators the API server may try, in order:
  1. Client certificate    (CN -> username, O -> groups)
  2. Bearer token          (static token file, legacy; discouraged)
  3. ServiceAccount token  (JWT signed by the cluster; workload identity)
  4. OIDC id_token         (external IdP; for human SSO)
  5. Authenticating proxy  (trusted front proxy sets identity headers)
  6. Anonymous            (system:anonymous / system:unauthenticated)

Common Broken-Authentication Scenarios

1. Anonymous Authentication Enabled

# API server flag (dangerous when combined with any binding to
# system:anonymous or the system:unauthenticated group):
kube-apiserver --anonymous-auth=true

# An unauthenticated probe is accepted as system:anonymous:
$ curl -k https://API_SERVER:6443/api/v1/namespaces/default/pods
# If RBAC grants anything to system:unauthenticated, this returns data.

Risk: Every request that fails all other authenticators is silently downgraded to an anonymous identity instead of being rejected. A single over-broad ClusterRoleBinding to system:unauthenticated becomes cluster-wide unauthenticated access.

2. Unauthenticated Kubelet API (Port 10250)

# Kubelet started with anonymous auth on and authz set to AlwaysAllow:
kubelet --anonymous-auth=true --authorization-mode=AlwaysAllow

# Anyone who can reach the node can list pods and exec into them:
$ curl -sk https://NODE:10250/pods
$ curl -sk https://NODE:10250/run/// -d "cmd=id"

Risk: The kubelet is a second, node-local API. Left unauthenticated, it hands out Pod command execution and log access with no involvement from the API server or RBAC at all.

3. Exposed etcd Without Authentication or TLS

# etcd reachable on the network with no client-cert requirement:
$ etcdctl --endpoints=https://ETCD:2379 get / --prefix --keys-only
# Cluster state, including every Secret, is stored here.
# Secrets are base64-encoded, not encrypted, unless encryption-at-rest is on.

Risk: etcd is the cluster’s source of truth. Read access is total disclosure; write access is total control. It must require mutual TLS and never be network-reachable beyond the control plane.

4. Long-Lived / Legacy ServiceAccount Tokens

# Legacy: a non-expiring token stored in a Secret, mounted into pods.
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token   # never expires, not audience-bound
metadata:
  name: build-bot-token
  annotations:
    kubernetes.io/service-account.name: build-bot

Risk: A token that never expires and is valid for any audience is a permanent bearer credential. Steal it once from a compromised Pod, a log, or an environment variable, and replay it indefinitely from anywhere.

5. Shared, Long-Lived kubeconfigs and Client Certificates

# A kubeconfig with an embedded client cert whose CN maps to a
# powerful identity and whose validity is measured in years:
users:
- name: cluster-admin
  user:
    client-certificate-data:    # 5-year cert

Risk: Kubernetes has no built-in certificate revocation. A leaked client cert—especially one with O=system:masters—is valid until it expires. If it is long-lived and shared across a team or CI, a single leak is an unrevocable cluster-admin backdoor.

6. No OIDC/SSO for Humans

# Instead of federated identity, every engineer shares one kubeconfig,
# or each holds a personal long-lived cert with no central control:
#   - no MFA
#   - no central revocation when someone leaves
#   - no per-user audit attribution (everyone is "cluster-admin")

Risk: Without OIDC/SSO, human access relies on static credentials that cannot be centrally revoked, carry no MFA, and destroy audit attribution because everyone shares one identity.

Where Authentication Can Break

Component / LayerTypical Broken-Auth ConditionConsequence
API serverAnonymous auth enabled; static token/basic-auth fileUnauthenticated or shared-secret access to the control plane
Kubelet (10250)Anonymous auth on, authz AlwaysAllowPod exec/log access with no RBAC
etcd (2379)No mutual TLS, network-reachableFull cluster-state read/write, all Secrets exposed
ServiceAccount tokensLegacy non-expiring, broadly mountedReplayable workload credentials
Human accessShared kubeconfig / long-lived certs, no OIDC/MFANo revocation, no attribution, no MFA
Cloud IAM ↔ RBACWeak or over-broad identity mappingCloud foothold escalates to cluster-admin
Dashboards / add-onsKubernetes Dashboard exposed without authAnonymous UI-driven cluster control

Real-World Impact

Incident Class 1: Exposed Administrative Dashboards

Condition:

Impact:

Root Cause: An administrative interface deployed with no authentication and exposed publicly—a control-plane authentication failure rather than an application bug.

Incident Class 2: Unauthenticated Kubelet and etcd

Condition:

Impact:

Root Cause: Control-plane and node components deployed with their authentication turned off or never configured, on the assumption that the network was “internal.”

Incident Class 3: Leaked Long-Lived Credentials

Condition:

Impact:

Root Cause: Static, shared, long-lived credentials treated as if they were disposable—combined with the absence of expiry and revocation.

Prevalence and Detectability

Broken authentication is consistently found in real clusters because so many of its causes are defaults or conveniences: anonymous auth has historically been on, legacy SA token Secrets were the norm, and sharing one kubeconfig is easier than wiring up OIDC. It is also highly detectable—an unauthenticated request to the API server, kubelet, or etcd either works or it does not, and internet-wide scanners probe these ports continuously.

Rather than cite precise breach counts (which vary by source), the defensible picture is:

Note: exact percentages and incident counts differ between reports and years. Treat any single figure as illustrative; the durable takeaway is that broken authentication is common, trivially detectable, and catastrophic when exploited.

Common Misunderstandings

Myth 1: “RBAC protects us, so authentication details don’t matter”

Reality: RBAC only decides what a known identity may do. If authentication is broken, RBAC is handed the wrong identity—system:anonymous, a stolen ServiceAccount, or a spoofed proxy header. Authorization cannot fix a false answer to “who are you?”

Myth 2: “Anonymous auth is harmless because nothing is bound to anonymous”

Reality: It is one accidental ClusterRoleBinding away from disaster, and it is a standing footgun. Some health endpoints aside, disabling anonymous auth removes the risk entirely rather than depending on RBAC never granting anonymous anything.

Myth 3: “Our cluster is on a private network, so the kubelet and etcd are safe”

Reality: Internal networks are routinely reached through SSRF, a compromised Pod, a misconfigured LoadBalancer, or a VPN pivot. An unauthenticated kubelet or etcd is one hop away from any foothold—authenticate them regardless of network position.

Myth 4: “ServiceAccount tokens are fine as-is”

Reality: Legacy tokens never expire and are valid for any audience, so a single leak is permanent. Projected, bound, short-lived tokens issued through the TokenRequest API expire quickly and are scoped to an audience—a stolen one is useful for minutes, not forever.

Myth 5: “A client certificate is more secure than a password, so long-lived certs are fine”

Reality: Kubernetes has no certificate revocation list. A long-lived cert—especially O=system:masters—is a bearer credential that stays valid until it expires, no matter how many times it leaks. Keep certs short-lived and rotate them.

Myth 6: “We use a cloud provider, so authentication is handled for us”

Reality: Managed control planes still let you enable anonymous auth, mount legacy tokens, expose dashboards, and map cloud IAM to cluster-admin too broadly. The provider secures the control plane it runs; the identity configuration is still yours to get right.

How Broken Authentication Differs from Related Issues

AspectBroken Authentication (K06)Overly Permissive RBAC (K03)Insecure Workload Config (K01)
Question it answersWho is this request from?What may this identity do?How is this workload allowed to run?
Root causeWeak/absent identity verificationOver-broad role bindingsPrivileged/unconstrained Pod settings
Typical fixDisable anonymous, OIDC, short-lived tokens, mTLSLeast-privilege roles, scoped bindingsSecurityContext, drop privileges
DetectionUnauthenticated probe, credential auditRBAC review (kubectl auth can-i)Manifest/admission scanning

Key Takeaways

  1. Authentication is the first gate—break it and every downstream control (RBAC, admission) reasons about the wrong principal.
  2. It is spread across components—the API server, every kubelet, and etcd authenticate independently; harden all three.
  3. Anonymous access should be off—never rely on RBAC to have granted system:anonymous nothing by accident.
  4. Prefer short-lived, scoped credentials—projected/bound SA tokens and short-lived certs limit the value of any theft.
  5. Long-lived shared secrets are backdoors—certs can’t be revoked and legacy tokens never expire, so a single leak is permanent.

How to Identify if You’re Vulnerable

Ask these questions about your cluster:

If you answered “no” or “not sure” to several of these, an attacker who reaches your control plane today could likely authenticate as someone—or as no one—and act.

Next Steps