Skip to main content

Kubernetes PKI Key File Permissions Should Be 600

More Info:​

Verifies that Kubernetes PKI private key files have permissions of 600. Exposure of these keys would let an attacker impersonate cluster components.

Risk Level​

Medium

Address​

Security

Compliance Standards​

  • CIS Kubernetes

Triage and Remediation​

Remediation​

Manual Steps
  1. Log in to each control plane node
    Use SSH or your usual access method to connect to every control plane node where /etc/kubernetes/pki exists.

  2. Review current key file permissions
    On each control plane node, list all private key files and their permissions:

    sudo find /etc/kubernetes/pki/ -name '*.key' -exec stat -c '%n permissions=%a owner=%U group=%G' {} \;
  3. Set private key permissions to 600
    On each control plane node, restrict permissions on all Kubernetes PKI private keys:

    sudo chmod -R 600 /etc/kubernetes/pki/*.key
  4. Confirm ownership is root:root (review and adjust if needed)
    Still on each control plane node, check ownership:

    sudo find /etc/kubernetes/pki/ -name '*.key' -exec stat -c '%n owner=%U group=%G' {} \;

    If any key is not owned by root:root, adjust as appropriate for your environment, for example:

    sudo chown root:root /etc/kubernetes/pki/<specific-key-file>.key
  5. Verify final permissions match the benchmark
    On each control plane node, re-run the audit to confirm all keys are now 600:

    sudo find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a

    Ensure every reported permissions= value is 600.

Using kubectl

kubectl cannot modify file permissions on control plane node files such as /etc/kubernetes/pki/*.key; this must be fixed directly on every control plane node’s filesystem. Refer to the Manual Steps section for the exact commands to run over SSH on those nodes.

Automation
#!/usr/bin/env bash
#
# Harden Kubernetes PKI private key permissions on all control plane nodes.
# Target: run on every control plane node (as root or with sudo).
# Idempotent: safe to run multiple times.

set -euo pipefail

PKI_DIR="/etc/kubernetes/pki"
KEY_GLOB="${PKI_DIR}/*.key"

echo "==> Ensuring Kubernetes PKI key file permissions are 600 under ${PKI_DIR}"

if [ ! -d "${PKI_DIR}" ]; then
echo "PKI directory ${PKI_DIR} does not exist on this node; nothing to do."
exit 0
fi

# Find all .key files (if none, exit cleanly)
mapfile -t KEY_FILES < <(find "${PKI_DIR}" -maxdepth 1 -type f -name '*.key' 2>/dev/null || true)

if [ "${#KEY_FILES[@]}" -eq 0 ]; then
echo "No *.key files found in ${PKI_DIR}; nothing to do."
exit 0
fi

echo "Found ${#KEY_FILES[@]} key file(s):"
printf ' %s\n' "${KEY_FILES[@]}"

# Apply permissions 600 to each key file (idempotent)
for key_file in "${KEY_FILES[@]}"; do
if [ ! -f "${key_file}" ]; then
continue
fi
current_perm=$(stat -c '%a' "${key_file}")
if [ "${current_perm}" != "600" ]; then
echo " Setting permissions 600 on ${key_file} (was ${current_perm})"
chmod 600 "${key_file}"
else
echo " Permissions already 600 on ${key_file}; skipping"
fi
done

echo
echo "==> Verification (should show permissions=600 for each .key file)"
find "${PKI_DIR}/" -name '*.key' | xargs stat -c 'permissions=%a %n' || true