> ## 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.

# Ensure Rotate Certificates Argument Is Not Set False

### More Info:

Enable kubelet client certificate rotation.

### Risk Level

Low

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CIS GKE
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, back up the kubelet config before editing:
           ```bash theme={null}
           sudo cp -a /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%F-%H%M%S)
           ```

        2. On every worker node, edit the kubelet config file and ensure `rotateCertificates` is not set to `false` (either set it to `true` or remove the line completely). For example, to force it to `true`:
           ```bash theme={null}
           sudo sed -i 's/^[[:space:]]*rotateCertificates:[[:space:]]*false/rotateCertificates: true/' /var/lib/kubelet/config.yaml
           ```
           Then open the file to confirm:
           ```bash theme={null}
           sudo vi /var/lib/kubelet/config.yaml
           ```
           and, if needed, manually add:
           ```yaml theme={null}
           rotateCertificates: true
           ```
           under the appropriate kubelet config section.

        3. If the kubelet is also configured via systemd flags, on every worker node check for an explicit `--rotate-certificates=false` argument:
           ```bash theme={null}
           sudo grep -R --color -n 'rotate-certificates' /etc/systemd/system/kubelet.service.d /etc/systemd/system/kubelet.service 2>/dev/null
           ```
           If found (commonly in `/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`), edit the file and remove the `--rotate-certificates=false` flag from the `KUBELET_CERTIFICATE_ARGS` (or similar) line:
           ```bash theme={null}
           sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
           ```
           Save the file after removing just that flag.

        4. On every worker node, reload systemd configuration and restart kubelet:
           ```bash theme={null}
           sudo systemctl daemon-reload
           sudo systemctl restart kubelet.service
           ```

        5. On every worker node, verify via the process list that kubelet is not running with `--rotate-certificates=false`:
           ```bash theme={null}
           /bin/ps -fC kubelet
           ```
           Inspect the output and confirm that:
           * there is no `--rotate-certificates=false` argument present, and
           * if a `--rotate-certificates` flag is present, it is not set to `false`.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify kubelet host-level configuration such as `/var/lib/kubelet/config.yaml` or systemd units on worker nodes. To remediate this finding, make the changes directly on each worker node as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Purpose: Ensure kubelet client certificate rotation is enabled (rotateCertificates != false)
        # Scope:   Run on EVERY WORKER NODE (as root). Safe to re-run.

        set -euo pipefail

        CONFIG_FILE="/var/lib/kubelet/config.yaml"
        SYSTEMD_DROPIN="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
        NEED_RESTART=0

        echo "[*] Ensuring kubelet rotateCertificates is enabled on this node..."

        # 1. Fix kubelet config file, if present
        if [ -f "$CONFIG_FILE" ]; then
          echo "[-] Found kubelet config file at $CONFIG_FILE"

          # Backup once per day
          BACKUP="${CONFIG_FILE}.$(date +%F-%H%M%S).bak"
          cp -p "$CONFIG_FILE" "$BACKUP"
          echo "    Backup created at $BACKUP"

          # If rotateCertificates is explicitly set to false, change to true
          if grep -qE '^[[:space:]]*rotateCertificates:[[:space:]]*false[[:space:]]*$' "$CONFIG_FILE"; then
            echo "    rotateCertificates: false found, changing to true"
            sed -i -E 's/^([[:space:]]*rotateCertificates:)[[:space:]]*false[[:space:]]*$/\1 true/' "$CONFIG_FILE"
            NEED_RESTART=1
          else
            # Ensure rotateCertificates: true is present if not set at all
            if ! grep -qE '^[[:space:]]*rotateCertificates:[[:space:]]*(true|false)[[:space:]]*$' "$CONFIG_FILE"; then
              echo "    rotateCertificates not set; adding rotateCertificates: true"
              # Append at end; kubelet config file is YAML, this adds a top-level key
              printf "\nrotateCertificates: true\n" >> "$CONFIG_FILE"
              NEED_RESTART=1
            else
              echo "    rotateCertificates is already not false; no change needed in config file"
            fi
          fi
        else
          echo "[-] No kubelet config file at $CONFIG_FILE; skipping config.yaml changes"
        fi

        # 2. Fix systemd kubelet arguments if present
        if [ -f "$SYSTEMD_DROPIN" ]; then
          echo "[-] Checking systemd drop-in at $SYSTEMD_DROPIN for --rotate-certificates=false"

          if grep -q -- '--rotate-certificates=false' "$SYSTEMD_DROPIN"; then
            BACKUP="${SYSTEMD_DROPIN}.$(date +%F-%H%M%S).bak"
            cp -p "$SYSTEMD_DROPIN" "$BACKUP"
            echo "    Backup created at $BACKUP"

            # Remove ONLY the --rotate-certificates=false argument (handles lists/whitespace)
            sed -i 's/--rotate-certificates=false//g' "$SYSTEMD_DROPIN"
            # Normalize multiple spaces left behind
            sed -i 's/[[:space:]]\+/ /g' "$SYSTEMD_DROPIN"
            NEED_RESTART=1
            echo "    Removed --rotate-certificates=false from kubelet systemd configuration"
          else
            echo "    No --rotate-certificates=false found in $SYSTEMD_DROPIN"
          fi
        else
          echo "[-] No systemd drop-in at $SYSTEMD_DROPIN; skipping systemd arg changes"
        fi

        # 3. Restart kubelet if needed
        if [ "$NEED_RESTART" -eq 1 ]; then
          echo "[-] Applying changes by restarting kubelet (this will restart the kubelet and may briefly affect pod scheduling on this node)..."
          systemctl daemon-reload
          systemctl restart kubelet.service
        else
          echo "[-] No changes made; kubelet restart not required"
        fi

        # 4. Verification (as per audit command)
        /bin/ps -fC kubelet || {
          echo "[!] kubelet process not found after changes" >&2
          exit 1
        }

        echo
        echo "[*] Verification: kubelet process command line (ensure --rotate-certificates=false is absent):"
        /bin/ps -fC kubelet

        if [ -f "$CONFIG_FILE" ]; then
          echo
          echo "[*] Verification: rotateCertificates setting in $CONFIG_FILE:"
          grep -nE 'rotateCertificates' "$CONFIG_FILE" || echo "    (rotateCertificates not explicitly set; default applies)"
        fi

        echo
        echo "[*] Completed. Run this script on every worker node."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://github.com/kubernetes/kubernetes/pull/41912](https://github.com/kubernetes/kubernetes/pull/41912)
