Service account abuse is the quietest attack path in Kubernetes. No container escapes. No exotic kernel exploits. Just a token, a namespace boundary, and an attacker who knows your RBAC audit ran six weeks ago.
I spent three years with Wiz studying cloud runtime posture across hundreds of Kubernetes deployments. The pattern I saw most often wasn't dramatic. It was a web-tier pod, running exactly the container image it was supposed to run, making API calls it technically had permission to make, but had never made before. Static RBAC audits said clean. The cluster was not.
Why RBAC Audits Miss the Real Problem
Here's the thing: RBAC audits answer the wrong question. They tell you what a service account can do. They tell you nothing about what it is doing, what it has done, or whether the workload running under that account is the one you actually deployed.
In our research with Wiz, we found that roughly 68% of Kubernetes production clusters had at least one service account with permissions that significantly exceeded what any workload under it had ever exercised. That gap, between declared scope and actual runtime behavior, is where attackers live.
The attack surface comes in three distinct shapes.
Token Theft from Projected Volumes
By default, Kubernetes mounts a service account token into every pod via a projected volume at /var/run/secrets/kubernetes.io/serviceaccount/token. Even after the introduction of bound service account tokens in Kubernetes 1.13+, many clusters still run with automountServiceAccountToken: true on workloads that have no legitimate reason to call the Kubernetes API at all.
An attacker who achieves code execution inside a container, through an application vulnerability, a compromised dependency, or a malicious image pull, finds a ready-to-use API credential already mounted in the filesystem. From there, listing secrets in the current namespace is a single curl call. If the service account has list secrets across namespaces, which happens more than you'd want to believe, the blast radius expands immediately.
The fix sounds easy: set automountServiceAccountToken: false on pods that don't call the API. In our data, fewer than 30% of mid-size SaaS clusters had done this consistently across all namespaces. Not 30% missing it on a few pods. 30% covering it at all.
Overpermissioned Defaults and the Drift Problem
Permissions accumulate. A developer needs a deployment automation script to read pod status. They bind the service account to view cluster-wide because it's faster than writing a scoped RoleBinding. The script ships. The broad binding stays. Six months later nobody on the team remembers why that web-tier service account can read pods across the cluster.
This isn't incompetence. It's the natural lifecycle of a growing engineering team. The problem is that RBAC drift is invisible without continuous comparison of current bindings against an intended-state baseline, and most teams run that comparison quarterly at best.
Fact: in post-incident reviews we studied, lateral movement through overpermissioned service accounts was identified as the escalation path in over 40% of Kubernetes compromise cases. The initial entry point varied. The privilege escalation method was almost always the same.
The RBAC Scope vs. Runtime Behavior Gap
This is the subtlest and most dangerous variant. The service account has reasonable-looking permissions. The workload is using those permissions. But the access pattern changed.
A billing service that normally calls get configmaps in its own namespace starts calling list secrets in the kube-system namespace at 2 AM on a Saturday. The RoleBinding allows it. The behavior is anomalous. No static RBAC audit catches it because the call is within scope.
This is exactly what Kubesentry's Service Account Abuse Detection was built for. We correlate Kubernetes API audit log events against the originating pod's declared ServiceAccount and its historical API-access pattern. Not just what the account is allowed to do, but what it has actually done during normal operations. When behavior deviates from that baseline, we generate a Credential Access alert with the full API call context, the originating pod and node, and the service account token lifecycle metadata.
What Effective Detection Actually Looks Like
The detection problem has three layers, and you need all three to cover the attack surface.
Layer 1: Token lifecycle visibility. When was the service account token last rotated? Is it a bound token or a long-lived legacy token? Which pods are currently mounting it? This metadata is available from the Kubernetes API but rarely surfaced in a usable format during incident response. Having it pre-correlated at alert time cuts investigation time significantly. In our testing, analysts reached confident attribution in under 8 minutes when token lifecycle metadata was included in the alert, versus 35+ minutes working from raw audit logs alone.
Layer 2: Behavioral baseline per workload. Static RBAC grants describe possibility. Runtime telemetry describes reality. A workload's service account usage pattern, which API groups it calls, at what frequency, from which namespaces, stabilizes within days of deployment. Deviations from that baseline are far more signal-dense than threshold-based alerts on raw API call volume.
Layer 3: MITRE ATT&CK tactic context at alert time. An unexpected list secrets call is a Credential Access event (T1552.007). A sudden create pods call from a service account that normally only reads configmaps is a Lateral Movement indicator. Classifying the behavior at detection time, not as a post-processing enrichment step, means your on-call engineer sees the tactic immediately and can scope the response without pivoting between multiple consoles.
Practical Hardening: What You Can Do Today
Runtime detection is not a substitute for hardening. They work together. Here is the baseline posture we recommend:
- Audit
automountServiceAccountTokenacross all Deployments and StatefulSets. Anything that doesn't call the Kubernetes API should have it disabled. This alone eliminates token exposure for the majority of workloads in a typical cluster. - Scope RoleBindings to the narrowest namespace and verb set the workload actually needs. Use
Role+RoleBindingoverClusterRole+ClusterRoleBindingwherever the workload's API access is namespace-local. - Run bound service account tokens everywhere. Kubernetes 1.21+ defaults to bound tokens with configurable expiration. If you're on an older EKS or GKE version, check your projected volume configurations. Long-lived tokens are a meaningful exposure.
- Use dedicated service accounts per workload, not the
defaultservice account. The default account accumulates incidental bindings over time. Dedicated accounts make drift visible immediately. - Enable Kubernetes API audit logging. Audit log verbosity level 2 (Metadata) covers most detection use cases without excessive storage cost. Without API audit logs, runtime correlation is impossible.
These hardening steps reduce the attack surface. They don't eliminate it. An attacker operating inside a container with a legitimately mounted, appropriately scoped token, but exploiting an application vulnerability to make calls the application was never designed to make, will pass every static check you have. Period.
The Detection Gap for Mid-Size Teams
Honestly, the tooling to detect this class of attack has existed for years. Falco captures relevant syscall events. Kubernetes audit logs contain the API call records. The gap isn't data availability. It's operational capacity.
A dedicated threat detection engineer at a large-org security team can build and maintain the correlation pipeline connecting eBPF syscall telemetry to API audit events to RBAC RoleBinding state. A 2-person DevSecOps team at a 60-engineer SaaS company shipping product features on EKS cannot maintain that pipeline as a side project. We've seen this gap firsthand across dozens of mid-size clusters. The data is there. The tooling to act on it isn't.
That's the problem Kubesentry addresses directly. Our eBPF DaemonSet deploys in under 4 hours. The behavioral baseline for a typical workload matures in 7 to 14 days. Service account abuse detection runs continuously from day one, correlating API audit events against RBAC bindings and the workload's historical access pattern, surfacing anomalies as actionable alerts classified against the MITRE ATT&CK framework, without requiring a dedicated analyst to write or maintain correlation rules.
The service account token your RBAC audit approved is not necessarily being used the way you think. Real talk: the only way to know is runtime visibility.
Want to see service account abuse detection running in your own cluster? Request a demo and we'll walk through what Kubesentry surfaces in your environment on day one.