Back to Checks
API server pod has ServiceAccount admission control plugin enabled
apiserver_service_account_plugin
Service: apiserverSeverity: high
OfficialBuilt-inVerified
Categories:cluster-securityidentity-access
Resource Type:Pod
Kubernetes API server includes the ServiceAccount admission controller (ServiceAccount)-enabled via --enable-admission-plugins and not listed in --disable-admission-plugins.
It applies service account-related defaults and policies to Pods, such as assigning a service account and governing secret references.
Risk
Without ServiceAccount admission, Pods may reference unintended secrets and run with unpredictable identities. This enables token misuse and unauthorized API access, facilitating lateral movement and privilege abuse, degrading confidentiality and integrity of cluster resources.
Run this check with Prowler
Run in Prowler CloudRun
prowler kubernetes --checks apiserver_service_account_pluginRecommendation
Enable and keep the ServiceAccount admission controller active to enforce identity and secret policies.
- Apply least privilege: restrict secrets on each service account
- Disable token automount where not needed (
automountServiceAccountToken=false) - Isolate secrets by namespace and rotate tokens
- Keep the API server patched
Remediation
Other
1SSH to each control plane node
2Edit the API server static pod manifest:
3sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
4In the kube-apiserver container flags, add or update the line:
5- --enable-admission-plugins=ServiceAccount <!-- Critical: ensures ServiceAccount plugin is enabled -->
6If a --disable-admission-plugins flag exists, ensure ServiceAccount is NOT listed (remove it if present) <!-- Critical: prevents disabling the plugin -->
7Save the file; the kubelet will restart the API server automatically
Check Code
from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.apiserver.apiserver_client import (
apiserver_client,
)
class apiserver_service_account_plugin(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
for pod in apiserver_client.apiserver_pods:
report = Check_Report_Kubernetes(metadata=self.metadata(), resource=pod)
report.status = "PASS"
report.status_extended = (
f"ServiceAccount admission control plugin is set in pod {pod.name}."
)
service_account_plugin_set = False
for container in pod.containers.values():
service_account_plugin_set = False
# Check if "--enable-admission-plugins" includes "ServiceAccount"
# and "--disable-admission-plugins" does not include "ServiceAccount"
for command in container.command:
if command.startswith("--enable-admission-plugins"):
if "ServiceAccount" in (command.split("=")[1]):
service_account_plugin_set = True
elif command.startswith("--disable-admission-plugins"):
if "ServiceAccount" in (command.split("=")[1]):
service_account_plugin_set = False
if not service_account_plugin_set:
break
if not service_account_plugin_set:
report.status = "FAIL"
report.status_extended = f"ServiceAccount admission control plugin is not set in pod {pod.name}."
findings.append(report)
return findings