Certificate Authorities File Permissions Are Restrictive
More Info:
Ensure that the certificate authorities file has permissions of 644 or more restrictive.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every worker node, identify the certificate authority file the kubelet is using:
CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)if test -z "$CAFILE"; then CAFILE=/etc/kubernetes/pki/ca.crt; fiprintf 'Using CA file: %s\n' "$CAFILE" -
On every worker node, review the current permissions and ownership of the CA file:
stat "$CAFILE" -
On every worker node, set the permissions of the CA file to 644 as required:
chmod 644 "$CAFILE" -
(Optional but recommended) On every worker node, ensure the CA file is owned by root:
chown root:root "$CAFILE" -
On every worker node, verify the permissions are now 644 or more restrictive:
stat -c permissions=%a "$CAFILE"
Using kubectl
kubectl cannot modify file permissions on worker node files such as /var/lib/kubelet/config.yaml or the kubelet --client-ca-file path; this must be fixed directly on every worker node via host-level access (SSH or similar). Refer to the Manual Steps section for the exact commands to correct the certificate authorities file permissions.
Automation
#!/usr/bin/env bash
#
# Automation: Restrict certificate authorities file permissions for kubelet
# Applies to: every worker node (run on each node, e.g. via SSH or Ansible shell)
# Idempotent: safe to re-run
set -euo pipefail
echo "=== Detecting kubelet client CA file ==="
# Try to detect --client-ca-file from kubelet process
CAFILE="$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq || true)"
# Fallback to default if not set
if [ -z "${CAFILE}" ]; then
CAFILE="/etc/kubernetes/pki/ca.crt"
fi
echo "Using client CA file path: ${CAFILE}"
# Check existence
if [ ! -e "${CAFILE}" ]; then
echo "ERROR: Client CA file does not exist: ${CAFILE}" >&2
exit 1
fi
# Show current permissions
CURRENT_PERMS="$(stat -c '%a' "${CAFILE}")"
echo "Current permissions on ${CAFILE}: ${CURRENT_PERMS}"
# Desired permissions: 644 (or more restrictive)
DESIRED_PERMS="644"
# Only relax permissions if they are less restrictive than 644
# (e.g., 666, 664, 777). If already 644 or more restrictive (e.g., 600),
# we leave them as-is to avoid weakening security.
# A simple numeric comparison works for typical cases; if in doubt, we always
# set to 644 for permissions > 644.
if [ "${CURRENT_PERMS}" -gt "${DESIRED_PERMS}" ]; then
echo "Updating permissions on ${CAFILE} to ${DESIRED_PERMS}"
chmod "${DESIRED_PERMS}" "${CAFILE}"
else
echo "Permissions are already 644 or more restrictive; no change needed."
fi
echo "=== Verifying result ==="
# Re-run the benchmark-style check for this node
CAFILE_VERIFY="$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq || true)"
if [ -z "${CAFILE_VERIFY}" ]; then
CAFILE_VERIFY="/etc/kubernetes/pki/ca.crt"
fi
if [ -e "${CAFILE_VERIFY}" ]; then
stat -c "Verified permissions=%a on ${CAFILE_VERIFY}" "${CAFILE_VERIFY}"
else
echo "WARNING: Verification failed; CA file not found at ${CAFILE_VERIFY}" >&2
exit 1
fi
echo "=== Completed on this node ==="
Usage:
- Run on every worker node, for example:
ssh worker-node-1 'bash -s' < ./fix_kubelet_ca_permissions.sh
ssh worker-node-2 'bash -s' < ./fix_kubelet_ca_permissions.sh
This script:
- Detects the kubelet
--client-ca-file(or defaults to/etc/kubernetes/pki/ca.crt). - Sets permissions to
644only if they are currently less restrictive than644. - Re-runs a verification similar to the audit command and prints the resulting permissions.