Ensure Kubeconfig File Permissions Are Set 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 Critical Security Controls v8
- CIS EKS
- 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:
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:
chmod 644 /etc/kubernetes/kubelet.conf -
Confirm the file is owned by the appropriate user and group (typically root:root). If needed, correct it:
chown root:root /etc/kubernetes/kubelet.conf -
Re-verify that the permissions are now 644 or more restrictive:
stat -c permissions=%a /etc/kubernetes/kubelet.conf
Using kubectl
kubectl cannot modify file permissions on worker node hosts, including /etc/kubernetes/kubelet.conf. This finding must be remediated directly on each worker node’s filesystem (host-level configuration); follow the Manual Steps section on those nodes to apply the fix.
Automation
#!/usr/bin/env bash
#
# Purpose: Ensure /etc/kubernetes/kubelet.conf permissions are 644 or more restrictive
# Scope: Run on every worker node (safe to re-run; idempotent)
set -euo pipefail
KUBECONFIG_PATH="/etc/kubernetes/kubelet.conf"
DESIRED_MODE="644"
echo "=== Kubelet kubeconfig permissions hardening ==="
if [ ! -e "$KUBECONFIG_PATH" ]; then
echo "File not found: $KUBECONFIG_PATH"
echo "Nothing to change on this node."
exit 0
fi
# Get current file mode (numeric, e.g., 600, 644)
CURRENT_MODE="$(stat -c '%a' "$KUBECONFIG_PATH")"
echo "Current permissions on $KUBECONFIG_PATH: $CURRENT_MODE"
echo "Desired minimum permissions: $DESIRED_MODE"
# Normalize to 3-digit modes for comparison
pad_mode() {
local m="$1"
printf "%03d" "$m"
}
CMODE="$(pad_mode "$CURRENT_MODE")"
DMODE="$(pad_mode "$DESIRED_MODE")"
# If current mode is already equal or more restrictive than 644, no change.
# "More restrictive" here means:
# - owner perms <= 6
# - group perms <= 4
# - other perms <= 4
# We enforce that, and then set to 644 if it's more permissive than that.
OWNER=${CMODE:0:1}
GROUP=${CMODE:1:1}
OTHER=${CMODE:2:1}
CHANGE_NEEDED=false
# If any class has permissions greater than allowed by 644, we must change.
if [ "$OWNER" -gt "${DMODE:0:1}" ] || \
[ "$GROUP" -gt "${DMODE:1:1}" ] || \
[ "$OTHER" -gt "${DMODE:2:1}" ]; then
CHANGE_NEEDED=true
fi
if ! $CHANGE_NEEDED; then
echo "Permissions are already 644 or more restrictive. No change required."
else
echo "Updating permissions on $KUBECONFIG_PATH to $DESIRED_MODE"
chmod "$DESIRED_MODE" "$KUBECONFIG_PATH"
fi
# Verification (same logic as audit, per node)
echo "=== Verification ==="
/bin/sh -c "if test -e '$KUBECONFIG_PATH'; then stat -c permissions=%a '$KUBECONFIG_PATH'; fi"