Back to Checks
API server pod has AlwaysPullImages admission control plugin enabled
apiserver_always_pull_images_plugin
Service: apiserverSeverity: medium
OfficialBuilt-inVerified
Categories:cluster-security
Resource Type:Pod
Kubernetes API server admission configuration includes AlwaysPullImages, which mutates new Pods to set imagePullPolicy=Always so container images are fetched from the registry at startup using the pod's credentials.
Risk
Without AlwaysPullImages, nodes can run cached images without a fresh registry pull, bypassing credential checks.
- Unauthorized use of private images (confidentiality)
- Stale or tampered images deployed (integrity)
- Vulnerable images persist, widening attack surface (availability)
Run this check with Prowler
Run in Prowler CloudRun
prowler kubernetes --checks apiserver_always_pull_images_pluginRecommendation
Enable AlwaysPullImages on the API server.
Apply defense in depth: restrict pulls to trusted registries, enforce least-privilege image pull secrets, sign and scan images, and prefer immutable digests to prevent drift and ensure verified content.
Remediation
Other
1SSH to a control-plane node
2Edit /etc/kubernetes/manifests/kube-apiserver.yaml
3In spec.containers[0].command or args, ensure the flag includes AlwaysPullImages, e.g.: --enable-admission-plugins=<existing>,AlwaysPullImages
4Save the file; the kubelet will automatically restart the API server with the updated flag
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_always_pull_images_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"AlwaysPullImages admission control plugin is set in pod {pod.name}."
)
plugin_set = False
for container in pod.containers.values():
plugin_set = False
for command in container.command:
if command.startswith("--enable-admission-plugins"):
if "AlwaysPullImages" in command:
plugin_set = True
break
if not plugin_set:
break
if not plugin_set:
report.status = "FAIL"
report.status_extended = f"AlwaysPullImages admission control plugin is not set in pod {pod.name}."
findings.append(report)
return findingsReferences
- https://cjyabraham.gitlab.io/docs/reference/command-line-tools-reference/kube-apiserver/
- https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers
- https://blog.codefarm.me/2021/12/15/kubernetes-admission-controllers/
- https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages