> ## 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 Anonymous Auth Argument Is Disabled

### More Info:

Disable anonymous requests to the Kubelet server.

### Risk Level

High

### 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, open the kubelet config file and ensure anonymous auth is disabled:

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

        Find or add the following block under `authentication`:

        ```yaml theme={null}
        authentication:
          anonymous:
            enabled: false
        ```

        Save and exit.

        2. If the node also uses a systemd drop-in with kubelet flags, ensure there is no conflicting `--anonymous-auth` flag. Open the file:

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

        In the `KUBELET_KUBEADM_ARGS` (or similar) line, remove any `--anonymous-auth=true` flag. If you must specify it, set:

        ```text theme={null}
        --anonymous-auth=false
        ```

        Save and exit.

        3. Reload systemd configuration on the worker node:

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

        4. Restart the kubelet on the worker node (this will temporarily impact node status and pod scheduling on this node):

        ```bash theme={null}
        sudo systemctl restart kubelet.service
        ```

        5. Verify the kubelet process no longer allows anonymous auth by inspecting its arguments:

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

        Confirm that either:

        * there is **no** `--anonymous-auth=true` flag present, and/or
        * if `--anonymous-auth` appears, it is `--anonymous-auth=false`.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot change the kubelet’s `--anonymous-auth` setting because it is configured on each worker node’s host (in `/var/lib/kubelet/config.yaml` or the kubelet systemd unit). To remediate this finding, follow the host-level instructions in the **Manual Steps** section on every worker node.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Remediation: Disable anonymous auth on kubelet via /var/lib/kubelet/config.yaml
        # Applies to: every worker node (run locally on each node, or via SSH/Ansible)
        # Idempotent: safe to run multiple times
        #

        set -euo pipefail

        CONFIG_FILE="/var/lib/kubelet/config.yaml"
        BACKUP_SUFFIX="$(date +%Y%m%d%H%M%S)"
        SYSTEMD_UNIT="kubelet.service"

        echo "[INFO] Ensuring kubelet anonymous auth is disabled on this node"

        if [ ! -f "$CONFIG_FILE" ]; then
          echo "[ERROR] Kubelet config file not found at $CONFIG_FILE"
          echo "[ERROR] This script expects kubelet to be configured via $CONFIG_FILE."
          echo "[ERROR] If your kubelet uses only command-line flags/systemd env, follow the Manual Steps for flag-based configuration."
          exit 1
        fi

        # Backup once per run
        cp -p "$CONFIG_FILE" "${CONFIG_FILE}.bak.${BACKUP_SUFFIX}"
        echo "[INFO] Backed up $CONFIG_FILE to ${CONFIG_FILE}.bak.${BACKUP_SUFFIX}"

        # Ensure the 'authentication:' block exists
        if ! grep -qE '^[[:space:]]*authentication:' "$CONFIG_FILE"; then
          cat <<'EOF' >>"$CONFIG_FILE"

        authentication:
          anonymous:
            enabled: false
        EOF
          echo "[INFO] Added authentication.anonymous.enabled: false block to $CONFIG_FILE"
        else
          # Ensure 'anonymous:' exists under 'authentication:'
          awk '
          BEGIN { in_auth=0; anon_present=0 }
          /^[[:space:]]*authentication:[[:space:]]*$/ { in_auth=1; print; next }
          in_auth && /^[^[:space:]]/ { in_auth=0 }
          in_auth && /^[[:space:]]*anonymous:[[:space:]]*$/ { anon_present=1 }
          { print }
          END {
            if (in_auth && !anon_present) {
              print "  anonymous:"
              print "    enabled: false"
            }
          }' "$CONFIG_FILE" >"${CONFIG_FILE}.tmp"

          mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
          echo "[INFO] Ensured authentication.anonymous block exists in $CONFIG_FILE"

          # Now explicitly set enabled: false (handle various existing values/indentation)
          python3 - "$CONFIG_FILE" <<'PYCODE'
        import sys, io
        from pathlib import Path

        cfg_path = Path(sys.argv[1])
        data = cfg_path.read_text()

        lines = data.splitlines()
        out = []
        in_auth = False
        in_anon = False
        auth_indent = None
        anon_indent = None

        for line in lines:
            stripped = line.lstrip()
            indent = len(line) - len(stripped)

            if stripped.startswith('authentication:'):
                in_auth = True
                auth_indent = indent
                in_anon = False
                out.append(line)
                continue

            if in_auth and indent <= (auth_indent or 0) and stripped and not stripped.startswith("#"):
                in_auth = False
                in_anon = False

            if in_auth and stripped.startswith('anonymous:'):
                in_anon = True
                anon_indent = indent
                out.append(line)
                continue

            if in_anon:
                # Leaving anonymous block?
                if stripped and indent <= (anon_indent or 0) and not stripped.startswith("#"):
                    # We already ensured block exists; just end tracking here
                    in_anon = False

            # Replace any "enabled:" under the anonymous block
            if in_anon and stripped.startswith('enabled:'):
                out.append(' ' * (anon_indent + 2) + 'enabled: false')
            else:
                out.append(line)

        cfg_path.write_text("\n".join(out) + "\n")
        PYCODE
          echo "[INFO] Set authentication.anonymous.enabled: false in $CONFIG_FILE"
        fi

        # Reload & restart kubelet to apply changes
        echo "[INFO] Reloading systemd and restarting kubelet"
        if command -v systemctl >/dev/null 2>&1; then
          systemctl daemon-reload
          systemctl restart "$SYSTEMD_UNIT"
        else
          echo "[WARN] systemctl not found; please restart kubelet manually to apply changes"
        fi

        # Verification (same host): ensure kubelet process is running and anonymous-auth is effectively disabled
        echo "[INFO] Verifying kubelet process and effective anonymous-auth setting"

        /bin/ps -fC kubelet || {
          echo "[ERROR] kubelet process not found after restart"
          exit 1
        }

        # Best-effort config verification: print the relevant section for human review
        echo "[INFO] Current authentication.anonymous section in $CONFIG_FILE:"
        grep -n -A3 -B1 'authentication:' "$CONFIG_FILE" | sed -n '1,40p'

        echo "[INFO] Verification step: kubelet is running. Confirm that the 'enabled' field under authentication.anonymous is set to false above."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/admin/kubelet-authentication-authorization/#kubelet-authentication](https://kubernetes.io/docs/admin/kubelet-authentication-authorization/#kubelet-authentication)
