Skip to main content

Ensure Kubeconfig File Permissions Are Restrictive

More Info:

Ensure that the kubelet.conf file has permissions of 644 or more restrictive

Risk Level

Medium

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS AKS
  • CIS Critical Security Controls v8
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • Essential 8
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

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

    sudo stat -c permissions=%a /etc/kubernetes/kubelet.conf
  2. If the permissions are more permissive than 644 (e.g., 664, 666, 600 is fine), set them to 644:

    sudo chmod 644 /etc/kubernetes/kubelet.conf
  3. (Optional but recommended) Ensure the file is owned by root:

    sudo chown root:root /etc/kubernetes/kubelet.conf
  4. Verify the permissions are now 644 on each worker node:

    sudo stat -c permissions=%a /etc/kubernetes/kubelet.conf
Using kubectl

kubectl cannot modify file permissions on node-local paths such as /etc/kubernetes/kubelet.conf, so this finding cannot be fixed through the Kubernetes API. The required changes must be made directly on every worker node’s host filesystem; see the Manual Steps section for the exact commands.

Automation
#!/usr/bin/env bash
#
# Automation: Ensure /etc/kubernetes/kubelet.conf permissions are 644 or more restrictive
# Scope: Run on every worker node (as root). Safe to re-run.

set -euo pipefail

KUBELET_KUBECONFIG="/etc/kubernetes/kubelet.conf"
DESIRED_MODE="644"
CHANGED=0

echo "==> Checking kubeconfig on this worker node: ${KUBELET_KUBECONFIG}"

if [ ! -e "${KUBELET_KUBECONFIG}" ]; then
echo "Kubeconfig file not found at ${KUBELET_KUBECONFIG}; nothing to do on this node."
else
# Get current permissions in numeric form (e.g. 640, 644)
CURRENT_MODE="$(stat -c '%a' "${KUBELET_KUBECONFIG}")"

# Normalize to 3 digits
CURRENT_MODE_PADDED="$(printf '%03d' "${CURRENT_MODE}")"
DESIRED_MODE_PADDED="$(printf '%03d' "${DESIRED_MODE}")"

echo "Current permissions: ${CURRENT_MODE_PADDED}; desired: ${DESIRED_MODE_PADDED}"

# Compare octal modes numerically; if current is more permissive than 644, tighten it.
# Permissions are treated as octal; 644 == 420 decimal.
if [ "$((8#${CURRENT_MODE_PADDED}))" -gt "$((8#${DESIRED_MODE_PADDED}))" ]; then
echo "Permissions are too permissive; tightening to ${DESIRED_MODE_PADDED}"
chmod "${DESIRED_MODE_PADDED}" "${KUBELET_KUBECONFIG}"
CHANGED=1
else
echo "Permissions are already ${DESIRED_MODE_PADDED} or more restrictive; no change needed."
fi
fi

echo
echo "==> Verification (CISAKS 3.1.1 audit) on this node:"
if [ -e "${KUBELET_KUBECONFIG}" ]; then
/bin/sh -c 'if test -e /etc/kubernetes/kubelet.conf; then stat -c permissions=%a /etc/kubernetes/kubelet.conf; fi'
echo
echo "Check that the reported permissions value is 644 or a more restrictive mode (e.g. 640, 600)."
else
echo "Kubeconfig file not present; control not applicable on this node."
fi

if [ "${CHANGED}" -eq 1 ]; then
echo "Permissions were updated on this node."
fi

Additional Reading: