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

### 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 EKS
* 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 current kubelet configuration and systemd drop-in:

        ```bash theme={null}
        sudo cp -a /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%F-%H%M%S)
        sudo cp -a /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf.bak.$(date +%F-%H%M%S)
        ```

        2. On every worker node, edit the kubelet config file to enable certificate rotation:

        ```bash theme={null}
        sudo vi /var/lib/kubelet/config.yaml
        ```

        Ensure there is a line setting `rotateCertificates: true` (add or update as needed), for example:

        ```yaml theme={null}
        rotateCertificates: true
        ```

        3. On every worker node, ensure no systemd argument disables rotation:

        ```bash theme={null}
        sudo vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
        ```

        * Remove any occurrence of `--rotate-certificates=false`.
        * If you must use flags instead of config, make sure `KUBELET_ARGS` (or the ExecStart line) includes `--rotate-certificates=true` and not `false`.

        4. On every worker node, reload systemd and restart kubelet (this will briefly disrupt pods scheduled on that node):

        ```bash theme={null}
        sudo systemctl daemon-reload
        sudo systemctl restart kubelet
        ```

        5. On every worker node, verify the kubelet process is running with certificate rotation enabled and not disabled:

        ```bash theme={null}
        /bin/ps -fC kubelet
        ```

        Confirm the output does not contain `--rotate-certificates=false`; if the flag appears, it should be `--rotate-certificates=true`, or the flag can be absent while `rotateCertificates: true` is set in `/var/lib/kubelet/config.yaml`.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify kubelet process flags or its on-node configuration file `/var/lib/kubelet/config.yaml`, so this finding cannot be fixed via the Kubernetes API. Make the changes directly on every worker node’s host configuration and systemd unit as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Enable kubelet client certificate rotation on every worker node.
        # Run this script on EACH WORKER NODE as root (or with sudo).
        #
        # Idempotent: safe to re-run; only enforces rotateCertificates=true and
        # removes/overrides any conflicting --rotate-certificates flags.
        #
        set -euo pipefail

        SERVICE_DROPIN_DIR="/etc/systemd/system/kubelet.service.d"
        SERVICE_DROPIN_FILE="${SERVICE_DROPIN_DIR}/10-kubelet-args.conf"
        KUBELET_CONFIG_FILE="/var/lib/kubelet/config.yaml"

        echo "[INFO] Enabling kubelet client certificate rotation on this node"

        ###############################################################################
        # 1. Ensure kubelet config file sets rotateCertificates: true
        ###############################################################################
        if [[ -f "${KUBELET_CONFIG_FILE}" ]]; then
          echo "[INFO] Updating ${KUBELET_CONFIG_FILE} to set rotateCertificates: true"

          # Create a backup once per run
          cp -p "${KUBELET_CONFIG_FILE}" "${KUBELET_CONFIG_FILE}.bak.$(date +%s)"

          # If rotateCertificates key exists, set it to true; otherwise append it.
          if grep -qE '^[[:space:]]*rotateCertificates:' "${KUBELET_CONFIG_FILE}"; then
            # Replace existing line to ensure it is set to true
            sed -i 's/^[[:space:]]*rotateCertificates:.*/rotateCertificates: true/' \
              "${KUBELET_CONFIG_FILE}"
          else
            # Append at end of file
            printf '\nrotateCertificates: true\n' >> "${KUBELET_CONFIG_FILE}"
          fi
        else
          echo "[WARN] ${KUBELET_CONFIG_FILE} not found; skipping config.yaml update"
        fi

        ###############################################################################
        # 2. Ensure systemd drop-in does not disable rotation and sets it to true
        ###############################################################################
        echo "[INFO] Ensuring systemd drop-in does not disable --rotate-certificates"

        mkdir -p "${SERVICE_DROPIN_DIR}"

        if [[ -f "${SERVICE_DROPIN_FILE}" ]]; then
          cp -p "${SERVICE_DROPIN_FILE}" "${SERVICE_DROPIN_FILE}.bak.$(date +%s)"
        else
          # Create a minimal drop-in if it doesn't exist
          cat > "${SERVICE_DROPIN_FILE}" <<'EOF'
        [Service]
        Environment="KUBELET_ARGS="
        EOF
        fi

        # Remove any existing --rotate-certificates arguments (true or false)
        if grep -q -- "--rotate-certificates" "${SERVICE_DROPIN_FILE}"; then
          sed -i 's/--rotate-certificates=[^" ]*//g' "${SERVICE_DROPIN_FILE}"
        fi

        # Ensure KUBELET_ARGS line exists
        if ! grep -q '^Environment="KUBELET_ARGS=' "${SERVICE_DROPIN_FILE}"; then
          echo 'Environment="KUBELET_ARGS="' >> "${SERVICE_DROPIN_FILE}"
        fi

        # Append --rotate-certificates=true if not already present
        if ! grep -q -- "--rotate-certificates=true" "${SERVICE_DROPIN_FILE}"; then
          sed -i 's/^Environment="KUBELET_ARGS=\(.*\)"/Environment="KUBELET_ARGS=\1 --rotate-certificates=true"/' \
            "${SERVICE_DROPIN_FILE}"
        fi

        ###############################################################################
        # 3. Reload systemd and restart kubelet (OPERATIONAL IMPACT)
        ###############################################################################
        echo "[INFO] Reloading systemd daemon and restarting kubelet"
        systemctl daemon-reload
        systemctl restart kubelet

        ###############################################################################
        # 4. Verification (adapted from audit)
        /bin/ps -fC kubelet
        ###############################################################################
        echo "[INFO] Verification: checking kubelet process arguments and config"

        # Show kubelet process line with rotate-certificates flag (if present)
        ps -fC kubelet || true

        # Check for rotateCertificates: true in config file
        if [[ -f "${KUBELET_CONFIG_FILE}" ]]; then
          echo "[INFO] Checking ${KUBELET_CONFIG_FILE} for rotateCertificates: true"
          grep -n 'rotateCertificates' "${KUBELET_CONFIG_FILE}" || true
        fi

        echo "[INFO] Manual check expectations:"
        echo "  - kubelet should NOT be started with --rotate-certificates=false"
        echo "  - Either:"
        echo "      * kubelet has --rotate-certificates=true in its args, and/or"
        echo "      * ${KUBELET_CONFIG_FILE} contains: rotateCertificates: true"
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

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