Skip to main content

Kubernetes PKI Certificate File Permissions Are Restrictive

More Info:

Ensure that Kubernetes PKI certificate files have permissions of 644 or more restrictive.

Risk Level

High

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. On every control plane node, list current certificate permissions for awareness:

    find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c '%n permissions=%a owner=%U group=%G'
  2. Still on each control plane node, restrict permissions on all Kubernetes PKI certificate files:

    chmod -R 644 /etc/kubernetes/pki/*.crt
  3. Ensure the certificate files are owned by root (adjust if needed):

    chown root:root /etc/kubernetes/pki/*.crt
  4. Recheck permissions, ownership, and group to confirm they are at most 644 and root-owned:

    find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c '%n permissions=%a owner=%U group=%G'
  5. On each control plane node, run the benchmark audit command to verify compliance:

    find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a
Using kubectl

kubectl cannot modify file permissions on control plane nodes, so this finding cannot be fixed through Kubernetes API objects. To remediate it, adjust the certificate file permissions directly on every control plane node’s filesystem (for example under /etc/kubernetes/pki) as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Harden Kubernetes PKI certificate file permissions on control plane nodes.
# Target: every control plane node
# Requirement: all /etc/kubernetes/pki/*.crt must be 644 or more restrictive.
#
# Usage:
# 1) Copy this script to each control plane node, e.g. /root/fix-pki-crt-perms.sh
# 2) Run as root: bash /root/fix-pki-crt-perms.sh
# 3) Safe to re-run; it is idempotent.

set -euo pipefail

PKI_DIR="/etc/kubernetes/pki"

echo "=== Kubernetes PKI certificate permissions hardening ==="
echo "Target directory: ${PKI_DIR}"
echo

# 1. Check directory exists
if [ ! -d "${PKI_DIR}" ]; then
echo "Directory ${PKI_DIR} does not exist on this node. Nothing to do."
exit 0
fi

# 2. Show current permissions
echo "Current permissions for *.crt under ${PKI_DIR}:"
find "${PKI_DIR}" -type f -name '*.crt' -print0 2>/dev/null | \
xargs -0 -I{} stat -c '%n permissions=%a' {} 2>/dev/null || \
echo "No .crt files found under ${PKI_DIR}."
echo

# 3. Apply remediation: set mode 644 on all .crt files (idempotent)
echo "Applying permissions: chmod 644 on all *.crt under ${PKI_DIR} ..."
# Only act if there are any matching files
if find "${PKI_DIR}" -type f -name '*.crt' -print -quit 2>/dev/null | grep -q .; then
find "${PKI_DIR}" -type f -name '*.crt' -print0 2>/dev/null | \
xargs -0 chmod 644
else
echo "No .crt files found; skipping chmod."
fi
echo "Permissions update complete."
echo

# 4. Verification (adapted from audit command)
echo "Verification: resulting permissions for *.crt under ${PKI_DIR}:"
if find "${PKI_DIR}" -type f -name '*.crt' -print -quit 2>/dev/null | grep -q .; then
find "${PKI_DIR}" -type f -name '*.crt' | xargs stat -c 'permissions=%a %n'
else
echo "No .crt files found under ${PKI_DIR}."
fi

# 5. Check for non-compliant files (permissions > 644)
echo
echo "Checking for any certificate files still more permissive than 644..."
NON_COMPLIANT=$(find "${PKI_DIR}" -type f -name '*.crt' -printf '%p %m\n' 2>/dev/null | awk '$2 > 644')

if [ -n "${NON_COMPLIANT}" ]; then
echo "WARNING: The following files remain more permissive than 644 and should be reviewed:"
echo "${NON_COMPLIANT}"
exit 1
else
echo "All Kubernetes PKI certificate files under ${PKI_DIR} are now 644 or more restrictive."
fi

Additional Reading: