Back to Checks
kubernetes

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.

Prowler logoProwlerprowler-provider-kubernetes

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 Cloud
Run
prowler kubernetes --checks apiserver_service_account_plugin

Recommendation

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