Back to Checks
kubernetes

Kubelet service file on the node is owned by root:root

kubelet_service_file_ownership_root
Service: kubeletSeverity: high
OfficialBuilt-inVerified
Categories:node-security
Resource Type:Node

Kubernetes Kubelet service configuration on each node is expected to be owned by root. This assessment inspects the systemd drop-in at /etc/systemd/system/kubelet.service.d/kubeadm.conf and expects ownership root:root, ensuring only privileged users can modify kubelet startup settings.

Risk

Non-root ownership enables unauthorized changes to kubelet startup flags, degrading configuration integrity and service availability. Attackers could disable auth, expose ports, weaken TLS, or load rogue configs-leading to node compromise, credential theft (confidentiality), lateral movement, and cluster disruption.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler kubernetes --checks kubelet_service_file_ownership_root

Recommendation

Apply least privilege to node config: ensure the kubelet service file is root:root and writable only by root. Use configuration management to enforce permissions and detect drift, enable file integrity monitoring, harden the OS, and restrict privileged node access with separation of duties.

Remediation

CLI

sudo chown root:root /etc/systemd/system/kubelet.service.d/kubeadm.conf

Other

1SSH into the node with sudo privileges
2Run: sudo chown root:root /etc/systemd/system/kubelet.service.d/kubeadm.conf

Check Code

from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.lib.utils.utils import is_owned_by_root
from prowler.providers.kubernetes.services.core.core_client import core_client


class kubelet_service_file_ownership_root(Check):
    def execute(self) -> Check_Report_Kubernetes:
        findings = []
        for node in core_client.nodes.values():
            report = Check_Report_Kubernetes(metadata=self.metadata(), resource=node)
            # It can only be checked if Prowler is being executed inside a worker node or if the file is the default one
            if node.inside:
                if (
                    is_owned_by_root(
                        "/etc/systemd/system/kubelet.service.d/kubeadm.conf"
                    )
                    is None
                ):
                    report.status = "MANUAL"
                    report.status_extended = f"Kubelet service file not found in Node {node.name}, please verify Kubelet service file ownership manually."
                else:
                    report.status = "PASS"
                    report.status_extended = f"Kubelet service file ownership is set to root:root in Node {node.name}."
                    if not is_owned_by_root(
                        "/etc/systemd/system/kubelet.service.d/kubeadm.conf"
                    ):
                        report.status = "FAIL"
                        report.status_extended = f"Kubelet service file ownership is not set to root:root in Node {node.name}."
            else:
                report.status = "MANUAL"
                report.status_extended = f"Prowler is not being executed inside Node {node.name}, please verify Kubelet service file ownership manually."
            findings.append(report)
        return findings