Skip to main content

Kubelet Kubeconfig File Ownership Set To Root Root

More Info:

The kubelet kubeconfig file should be owned by root:root to ensure only privileged users can read or alter node authentication configuration.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS AKS

Triage and Remediation

Remediation

Manual Steps
  1. On every worker node, check the current ownership of the kubelet kubeconfig file:

    stat -c %n:%U:%G /var/lib/kubelet/kubeconfig 2>/dev/null || echo "kubeconfig not found at /var/lib/kubelet/kubeconfig"
  2. If the file exists and is not owned by root:root, change its ownership on that worker node:

    chown root:root /var/lib/kubelet/kubeconfig
  3. (Optional but recommended) Ensure parent directory permissions do not unintentionally expose the file on that worker node:

    ls -ld /var/lib/kubelet
  4. Repeat steps 1–3 on every worker node in the cluster.

  5. Verification on every worker node (ownership must show root:root):

    stat -c %U:%G /var/lib/kubelet/kubeconfig
Using kubectl

kubectl cannot change file ownership on the node filesystem; this finding must be fixed directly on each worker node’s host OS where /var/lib/kubelet/kubeconfig resides. Use SSH and follow the steps in the Manual Steps section to update ownership and re-run the audit command.

Automation
#!/usr/bin/env bash
#
# Purpose:
# Ensure the kubelet kubeconfig file is owned by root:root on every worker node.
#
# Usage:
# - Run on each worker node directly (e.g. via SSH, cloud-init, or a node bootstrap script), OR
# - From an admin machine, loop over your worker nodes with SSH and run this script remotely.
#
# Notes:
# - This is safe to re-run (idempotent).
# - No service restarts are required; ownership change is applied in-place.

set -euo pipefail

KUBELET_KUBECONFIG="/var/lib/kubelet/kubeconfig"

echo "==> Checking kubelet kubeconfig file at: ${KUBELET_KUBECONFIG}"

if [ ! -e "${KUBELET_KUBECONFIG}" ]; then
echo "WARNING: ${KUBELET_KUBECONFIG} does not exist on this node. Nothing to change."
exit 0
fi

current_owner_group="$(stat -c '%U:%G' "${KUBELET_KUBECONFIG}")"

if [ "${current_owner_group}" = "root:root" ]; then
echo "Already compliant: ${KUBELET_KUBECONFIG} ownership is root:root"
else
echo "Current ownership of ${KUBELET_KUBECONFIG} is ${current_owner_group}, updating to root:root ..."
chown root:root "${KUBELET_KUBECONFIG}"

# Verify immediately after change
new_owner_group="$(stat -c '%U:%G' "${KUBELET_KUBECONFIG}")"
if [ "${new_owner_group}" != "root:root" ]; then
echo "ERROR: Failed to set ownership of ${KUBELET_KUBECONFIG} to root:root (now: ${new_owner_group})"
exit 1
fi
echo "Updated: ${KUBELET_KUBECONFIG} ownership set to root:root"
fi

echo "==> Final verification (CIS audit style):"
/bin/sh -c "if test -e ${KUBELET_KUBECONFIG}; then stat -c %U:%G ${KUBELET_KUBECONFIG}; fi"
echo "Compliance check completed on this node."