> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes PKI Certificate File Permissions Should Be 644 Or More Restrictive

### More Info:

Verifies that Kubernetes PKI certificate files have permissions of 644 or more restrictive to protect the clusters public certificates from tampering.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every control plane node, list current permissions for all PKI certificate files and review them for unexpected entries or ownership before changing anything:

        ```bash theme={null}
        sudo find /etc/kubernetes/pki/ -name '*.crt' -exec ls -l {} \;
        ```

        2. Still on each control plane node, back up the PKI directory (for recovery if needed):

        ```bash theme={null}
        sudo cp -a /etc/kubernetes/pki /etc/kubernetes/pki.backup.$(date +%F-%H%M%S)
        ```

        3. On each control plane node, set certificate file permissions to `644` (owner read/write, group and others read-only), which is “644 or more restrictive”:

        ```bash theme={null}
        sudo chmod -R 644 /etc/kubernetes/pki/*.crt
        ```

        4. On each control plane node, ensure the certificate files are owned by the expected Kubernetes user and group (commonly `root:root`); adjust if needed based on your environment’s standard:

        ```bash theme={null}
        sudo chown root:root /etc/kubernetes/pki/*.crt
        ```

        5. If your environment requires stricter permissions (for example, no world-read), you may optionally further restrict them, but only after confirming that all Kubernetes components that need to read these certificates will still have access:

        ```bash theme={null}
        # Example of stricter permissions, if validated as safe for your setup:
        # sudo chmod -R 640 /etc/kubernetes/pki/*.crt
        ```

        6. Verify on each control plane node that all `.crt` files now have permissions `644` or more restrictive (e.g., 640, 600):

        ```bash theme={null}
        sudo find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c 'permissions=%a %n'
        ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify file permissions on control plane nodes, so this finding cannot be fixed through the Kubernetes API. The required changes must be made directly on each control plane node’s filesystem (for `/etc/kubernetes/pki/*.crt`); follow the guidance in the Manual Steps section to remediate.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Purpose: Ensure Kubernetes PKI certificate files have permissions 644 or more restrictive.
        # Scope:   Run on every control plane node.
        # Safely re-runnable: only relaxes overly-permissive perms; leaves stricter perms as-is.

        set -euo pipefail

        PKI_DIR="/etc/kubernetes/pki"

        echo "=== [INFO] Ensuring PKI certificate permissions under ${PKI_DIR} ==="

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

        # Find all .crt files and fix permissions if they are more permissive than 0644
        while IFS= read -r crt; do
          # Skip if no file (defensive)
          [ -f "${crt}" ] || continue

          current_mode_oct=$(stat -c '%a' "${crt}")
          # Normalize to 4 digits (e.g., 644 -> 0644) for comparison
          current_mode_norm=$(printf "%04d" "${current_mode_oct}")

          # Compare current mode to 0644. We only reduce permissions, never relax.
          # Breakdown: owner/group/other digits (ignore sticky/setuid/setgid in this simple check).
          o=${current_mode_norm:1:1}
          g=${current_mode_norm:2:1}
          t=${current_mode_norm:3:1}

          change_needed=false

          # Owner should be <= 6 (r+w). If owner has execute (7) or unexpected bits, reduce to 6.
          if [ "${o}" -gt 6 ]; then
            change_needed=true
          fi

          # Group should be <= 4 (r). If group has write/exec, reduce.
          if [ "${g}" -gt 4 ]; then
            change_needed=true
          fi

          # Other should be <= 4 (r). If other has write/exec, reduce.
          if [ "${t}" -gt 4 ]; then
            change_needed=true
          fi

          if [ "${change_needed}" = true ]; then
            echo "Fixing permissions on ${crt} (was ${current_mode_oct}) -> 0644"
            chmod 0644 "${crt}"
          else
            # If mode is already 0644 or more restrictive (e.g., 0600, 0640, 0400, 0444), leave as-is.
            echo "Permissions already compliant or more restrictive on ${crt} (mode ${current_mode_oct}), skipping"
          fi
        done < <(find "${PKI_DIR}" -type f -name '*.crt' 2>/dev/null)

        echo "=== [VERIFY] Current permissions for PKI certificates ==="
        find "${PKI_DIR}" -name '*.crt' | xargs stat -c 'permissions=%a %n' 2>/dev/null || true

        echo "=== [CHECK] Verifying that no .crt file is more permissive than 644 ==="
        non_compliant=$(find "${PKI_DIR}" -type f -name '*.crt' -exec stat -c '%a %n' {} \; \
          | awk '$1 > 644 {print}')

        if [ -n "${non_compliant}" ]; then
          echo "=== [FAIL] The following certificate files are still more permissive than 644:"
          echo "${non_compliant}"
          exit 1
        fi

        echo "=== [SUCCESS] All Kubernetes PKI certificate files are 644 or more restrictive ==="
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
