Back to Checks
kubernetes

API server pod uses PodSecurityPolicy or has the SecurityContextDeny admission plugin enabled

apiserver_security_context_deny_plugin
Service: apiserverSeverity: high
OfficialBuilt-inVerified
Categories:cluster-security
Resource Type:Pod

Kubernetes API server admission configuration is reviewed for PodSecurityPolicy or SecurityContextDeny, indicating whether pods using high-risk securityContext fields (privileged, host access, extra capabilities) would be blocked during admission.

Risk

Without these controls, pods can request privileged mode, host namespaces, or excessive capabilities, enabling container escape, node compromise, and data exfiltration. This undermines integrity and confidentiality, and can impact availability via lateral movement or disruptive actions.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler kubernetes --checks apiserver_security_context_deny_plugin

Recommendation

Apply defense-in-depth at admission:

  • Prefer Pod Security Admission with restricted policies
  • For legacy clusters, enable SecurityContextDeny or an equivalent policy engine
  • Enforce least privilege: set allowPrivilegeEscalation=false, drop unnecessary capabilities, and avoid host namespaces.

Remediation

Other

1SSH to a control-plane node
2Edit /etc/kubernetes/manifests/kube-apiserver.yaml
3In spec.containers[0].command:
4- If --enable-admission-plugins=... exists, append ",SecurityContextDeny" to its list
5- If absent, add a new arg line: - --enable-admission-plugins=SecurityContextDeny
6Save; the kubelet will restart the API server

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_security_context_deny_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)
            security_context_deny_set = False
            pod_security_policy_set = False
            for container in pod.containers.values():
                pod_security_policy_set = False
                security_context_deny_set = False
                for command in container.command:
                    if command.startswith("--enable-admission-plugins"):
                        if "SecurityContextDeny" in (command.split("=")[1]):
                            security_context_deny_set = True
                        if "PodSecurityPolicy" in (command.split("=")[1]):
                            pod_security_policy_set = True
                if not pod_security_policy_set or not security_context_deny_set:
                    break

            if pod_security_policy_set:
                report.status = "PASS"
                report.status_extended = (
                    f"PodSecurityPolicy is in use in pod {pod.name}."
                )
            elif security_context_deny_set:
                report.status = "PASS"
                report.status_extended = f"SecurityContextDeny admission control plugin is set in pod {pod.name}."
            else:
                report.status = "FAIL"
                report.status_extended = f"Neither SecurityContextDeny nor PodSecurityPolicy admission control plugins are set in pod {pod.name}."

            findings.append(report)
        return findings