Client Certificate Authorities File Ownership Set To
More Info:
The kubelet client certificate authorities file should be owned by root:root so only privileged users can modify the trust store. Incorrect ownership could allow tampering with client authentication.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every worker node, identify the kubelet client CA file path (if set explicitly):
ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file=If no
--client-ca-fileflag is present, use the default path/etc/kubernetes/pki/ca.crt. -
On every worker node, set the ownership of the client CA file to
root:root(replace the path if you found a different one in step 1):sudo chown root:root /etc/kubernetes/pki/ca.crt -
On every worker node, confirm the ownership is now correct:
stat -c %U:%G /etc/kubernetes/pki/ca.crtThe output must be:
root:root
Using kubectl
kubectl cannot change file ownership on worker node filesystems, including /etc/kubernetes/pki/ca.crt, because this is a host-level configuration. To remediate this finding, you must run the appropriate chown command directly on every worker node; see the Manual Steps section for the exact commands.
Automation
#!/usr/bin/env bash
#
# Fix ownership of kubelet client CA file (CIS Kubernetes 4.1.8)
# Scope: run on every worker node (can be run on control planes as well; it is safe)
# Idempotent: yes
set -euo pipefail
echo "[INFO] Detecting kubelet --client-ca-file path (if specified)..."
# Try to detect the client CA file from kubelet process args
CAFILE="$(ps -ef \
| grep kubelet \
| grep -v apiserver \
| grep -- '--client-ca-file=' \
| awk -F '--client-ca-file=' '{print $2}' \
| awk '{print $1}' \
| uniq || true)"
# Fall back to default if not set
if [ -z "${CAFILE}" ]; then
CAFILE="/etc/kubernetes/pki/ca.crt"
echo "[INFO] --client-ca-file flag not found, using default: ${CAFILE}"
else
echo "[INFO] Detected --client-ca-file: ${CAFILE}"
fi
# Ensure the file exists
if [ ! -e "${CAFILE}" ]; then
echo "[WARN] Client CA file does not exist: ${CAFILE}"
echo "[WARN] Nothing to change on this node."
exit 0
fi
echo "[INFO] Current ownership of ${CAFILE}:"
stat -c '%n %U:%G %a' "${CAFILE}"
# Apply required ownership (idempotent)
echo "[INFO] Setting ownership of ${CAFILE} to root:root ..."
chown root:root "${CAFILE}"
echo "[INFO] Ownership updated. Verifying..."
OWNER_GROUP="$(stat -c '%U:%G' "${CAFILE}")"
echo "[INFO] Post-change ownership of ${CAFILE}: ${OWNER_GROUP}"
if [ "${OWNER_GROUP}" != "root:root" ]; then
echo "[ERROR] Failed to set ownership of ${CAFILE} to root:root"
exit 1
fi
echo "[INFO] Verification passed: ${CAFILE} is owned by root:root"
# Re-run the benchmark audit logic for explicit confirmation
echo "[INFO] Running audit-style verification..."
CAFILE_AUDIT="$(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_AUDIT}" ]; then
CAFILE_AUDIT="/etc/kubernetes/pki/ca.crt"
fi
if [ -e "${CAFILE_AUDIT}" ]; then
echo -n "[INFO] Audit ownership for ${CAFILE_AUDIT}: "
stat -c '%U:%G' "${CAFILE_AUDIT}"
else
echo "[WARN] Audit path ${CAFILE_AUDIT} does not exist."
fi
echo "[INFO] Completed ownership remediation on this node."
Usage (run on every worker node over SSH):
ssh <worker-node> 'bash -s' < fix_client_ca_ownership.sh