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
Remediation
Manual Steps
-
On every worker node, check the current permissions of the kubeconfig file:
sudo stat -c permissions=%a /etc/kubernetes/kubelet.conf -
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 -
(Optional but recommended) Ensure the file is owned by root:
sudo chown root:root /etc/kubernetes/kubelet.conf -
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