ServiceAccount ServiceAccount/rbac-fixtures/sa-wildcard is mounted by live workloads and has dangerous permissions: secrets (cluster), create pods (cluster), mutate workloads (cluster), bind roles (cluster), bind/escalate (cluster), impersonate (cluster), nodes/proxy (cluster)
Scope · Namespace
ServiceAccount rbac-fixtures/sa-wildcard: namespace-scoped subject; mounted by pods in rbac-fixtures
Category: Privilege Escalation
Subject: ServiceAccount/rbac-fixtures/sa-wildcard
Resource: ServiceAccount/rbac-fixtures/sa-wildcard
ServiceAccount ServiceAccount/rbac-fixtures/sa-wildcard carries one or more dangerous RBAC capabilities (secrets (cluster), create pods (cluster), mutate workloads (cluster), bind roles (cluster), bind/escalate (cluster), impersonate (cluster), nodes/proxy (cluster)) *and* is actively mounted by workloads (Pod/rbac-fixtures/wildcard-app-85ff74597d-pr7l6, Deployment/rbac-fixtures/wildcard-app). The combination matters: a dangerous permission on an unused SA is latent risk; the same permission on an SA that ships in a running pod is a pre-positioned exploitation primitive. The attacker does not need to find the SA token, because the pod is the SA token.
The flagged capabilities map directly to known privesc paths:
- secrets → read service-account tokens of higher-privileged SAs (KUBE-PRIVESC-005).
- create pods → mount any SA in a new pod, run as root, or set hostPath: / to escape (KUBE-PRIVESC-001, KUBE-ESCAPE-*).
- mutate workloads → modify a Deployment to swap its image / SA, gaining the workload's identity (KUBE-PRIVESC-003).
- bind roles / bind/escalate → grant yourself or any SA arbitrary permissions, cluster-wide (KUBE-PRIVESC-009, KUBE-PRIVESC-010).
- impersonate → assume any user/group/SA, instantly bypassing RBAC (KUBE-PRIVESC-008).
- nodes/proxy → kubelet API access to read all pod logs/exec on a node (KUBE-PRIVESC-012).
Workloads using this SA: Pod/rbac-fixtures/wildcard-app-85ff74597d-pr7l6, Deployment/rbac-fixtures/wildcard-app. Each is a starting point: any RCE, any leaked container image layer, any logs accidentally containing the token are equivalent to the SA's RBAC.
Impact
Compromise of any workload using ServiceAccount/rbac-fixtures/sa-wildcard immediately grants the listed dangerous capabilities. In practice, this is a one- or two-hop chain to cluster-admin equivalent (see correlated KUBE-PRIVESC-* findings on the same subject).
How an attacker abuses this
BackgroundSubjectServiceAccount
A ServiceAccount is an in-cluster identity assigned to pods. Every pod gets a token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token, and that token is the credential. If an attacker reads that file from inside a compromised container (or creates a pod that mounts the token), they can call the API as the ServiceAccount, with whatever permissions the SA has been granted.
This is the most common pivot in real-world Kubernetes attacks: compromise one pod, steal its token, ride the token to wherever its RBAC allows.
Kubernetes docs ↗
- Attacker compromises any of the workloads (
Pod/rbac-fixtures/wildcard-app-85ff74597d-pr7l6, Deployment/rbac-fixtures/wildcard-app) via RCE in the application, a malicious image layer, or a leaked manifest with embedded token. - They read
/var/run/secrets/kubernetes.io/serviceaccount/token from the pod. - They use the token to invoke the dangerous capabilities (secrets (cluster), create pods (cluster), mutate workloads (cluster), bind roles (cluster), bind/escalate (cluster), impersonate (cluster), nodes/proxy (cluster)) directly. The token already authenticates as
ServiceAccount/rbac-fixtures/sa-wildcard, so no further escalation is needed. - For each capability they convert into the matching privesc path:
secrets→token theft → impersonate higher SA; bind→grant self cluster-admin; pods/create→privileged pod with hostPath /. - Within minutes they hold an identity equivalent to the most privileged subject reachable from this SA's chain, typically
cluster-admin if any privesc path connects.
Remediation
Split ServiceAccount/rbac-fixtures/sa-wildcard into one SA per workload, remove the dangerous capabilities that aren't actually used, and ensure each workload's SA holds only the minimum verbs.
- Audit which of the workloads (Pod/rbac-fixtures/wildcard-app-85ff74597d-pr7l6, Deployment/rbac-fixtures/wildcard-app) actually exercises each dangerous capability. Start with
audit2rbac over a 7-day window, then ask the workload's owner to confirm. - For each unique workload, create a dedicated SA and a least-privilege Role/ClusterRole with only the verbs that audit-2rbac observed. Bind only that Role to the new SA.
- Migrate workloads to the new dedicated SA (set
spec.serviceAccountName). Delete the bindings against the original ServiceAccount/rbac-fixtures/sa-wildcard and rotate its token. - For capabilities that *no* workload actually exercises, delete the binding entirely.
- Wire enforcement: a Kyverno policy that warns when
pods.spec.serviceAccountName references an SA whose RBAC binding includes any of [secrets:get, pods:create, rolebindings:create, escalate, impersonate, nodes/proxy:get].
Evidence
WorkloadsPod/wildcard-app-85ff74597d-pr7l6 in namespace rbac-fixtures
Deployment/wildcard-app in namespace rbac-fixtures
Dangerous permissionssecrets (cluster)create pods (cluster)mutate workloads (cluster)bind roles (cluster)bind/escalate (cluster)impersonate (cluster)nodes/proxy (cluster)
Show raw JSON
{
"dangerous_permissions": [
"secrets (cluster)",
"create pods (cluster)",
"mutate workloads (cluster)",
"bind roles (cluster)",
"bind/escalate (cluster)",
"impersonate (cluster)",
"nodes/proxy (cluster)"
],
"workloads": [
{
"kind": "Pod",
"name": "wildcard-app-85ff74597d-pr7l6",
"namespace": "rbac-fixtures"
},
{
"kind": "Deployment",
"name": "wildcard-app",
"namespace": "rbac-fixtures"
}
]
}