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

# Kubelet Authorization Mode Not Set To AlwaysAllow

### More Info:

An authorization mode of AlwaysAllow permits every authenticated request without further checks. Using Webhook authorization ensures requests to the kubelet are properly authorized.

### Risk Level

Critical

### 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, back up the API server static pod manifest and open it for editing:
           ```bash theme={null}
           sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak
           sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
           ```

        2. In the `kube-apiserver` container `command`/`args` section, locate any existing `--authorization-mode=` flag:
           * If present and set to `AlwaysAllow`, change it to a secure mode, for example:
             ```yaml theme={null}
             - --authorization-mode=RBAC
             ```
           * If multiple modes are configured, ensure `AlwaysAllow` is not among them, for example:
             ```yaml theme={null}
             - --authorization-mode=Node,RBAC
             ```
           * If the flag is missing, add a new line under the other `--` flags:
             ```yaml theme={null}
             - --authorization-mode=RBAC
             ```

        3. Save the file and exit the editor. The kubelet will automatically detect the change to `/etc/kubernetes/manifests/kube-apiserver.yaml` and restart the `kube-apiserver` static pod. Be aware this temporarily restarts the API server on that control plane node.

        4. Wait for the `kube-apiserver` pod to become Ready again (from any machine with `kubectl` access):
           ```bash theme={null}
           kubectl get pods -n kube-system -o wide | grep kube-apiserver
           ```

        5. Repeat steps 1–4 on every control plane node to ensure consistent authorization configuration across the cluster.

        6. Verify on each control plane node that the API server is no longer running with `--authorization-mode=AlwaysAllow`:
           ```bash theme={null}
           /bin/ps -ef | grep kube-apiserver | grep -v grep
           ```
           Confirm that the `kube-apiserver` process line includes `--authorization-mode=` and that `AlwaysAllow` does not appear in its value (e.g., it shows `RBAC` or `Node,RBAC` instead).
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify kube-apiserver startup flags or static pod manifests on the nodes, so this finding cannot be fixed through the Kubernetes API. To remediate it, edit `/etc/kubernetes/manifests/kube-apiserver.yaml` directly on every control plane node as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Automation for CIS Kubernetes 4.2.2
        # Fix: Ensure kube-apiserver --authorization-mode is not set to AlwaysAllow
        #
        # Usage (run on every control plane node, as root):
        #   bash fix-kube-apiserver-authorization-mode.sh
        #
        # Operational impact:
        # - Editing /etc/kubernetes/manifests/kube-apiserver.yaml will cause the
        #   kube-apiserver static pod to restart on this node.

        set -euo pipefail

        API_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
        BACKUP_DIR="/etc/kubernetes/manifests/backup-authorization-mode"
        DESIRED_MODE="RBAC"

        echo "[INFO] Running on host: $(hostname)"
        echo "[INFO] Target manifest: ${API_MANIFEST}"

        if [[ ! -f "${API_MANIFEST}" ]]; then
          echo "[ERROR] kube-apiserver manifest not found at ${API_MANIFEST}"
          echo "[ERROR] This script must be run on a control plane node that uses static pods."
          exit 1
        fi

        mkdir -p "${BACKUP_DIR}"

        BACKUP_FILE="${BACKUP_DIR}/kube-apiserver.yaml.$(date +%Y%m%d-%H%M%S)"
        cp -a "${API_MANIFEST}" "${BACKUP_FILE}"
        echo "[INFO] Backup created at ${BACKUP_FILE}"

        # Extract existing authorization-mode value (if any)
        CURRENT_MODE_LINE="$(grep -E -- '--authorization-mode=' "${API_MANIFEST}" || true)"
        CURRENT_MODE_VALUE=""
        if [[ -n "${CURRENT_MODE_LINE}" ]]; then
          CURRENT_MODE_VALUE="$(echo "${CURRENT_MODE_LINE}" | sed -E 's/.*--authorization-mode=([^" ]*).*/\1/')"
        fi

        if [[ "${CURRENT_MODE_VALUE}" == "${DESIRED_MODE}" ]]; then
          echo "[INFO] --authorization-mode already set to ${DESIRED_MODE}; no change required."
        else
          echo "[INFO] Updating --authorization-mode to ${DESIRED_MODE}"

          TMP_FILE="$(mktemp)"
          trap 'rm -f "${TMP_FILE}"' EXIT

          if grep -qE -- '--authorization-mode=' "${API_MANIFEST}"; then
            # Replace existing value
            sed -E "s/(--authorization-mode=)[^\" ]*/\1${DESIRED_MODE}/" "${API_MANIFEST}" > "${TMP_FILE}"
          else
            # Add flag under containers.args
            # This assumes standard kubeadm-style manifest with containers: and args: lists.
            # Insert the new arg right after the first occurrence of "--advertise-address" or at the end of args.
            if grep -q -- "--advertise-address" "${API_MANIFEST}"; then
              awk -v flag="        - --authorization-mode=${DESIRED_MODE}" '
                /--advertise-address/ && !inserted {
                  print $0
                  print flag
                  inserted=1
                  next
                }
                { print $0 }
                END {
                  if (!inserted) {
                    # Fallback: in case pattern was not matched (defensive)
                    print flag
                  }
                }
              ' "${API_MANIFEST}" > "${TMP_FILE}"
            else
              # Generic fallback: append to the args list of kube-apiserver container
              awk -v flag="        - --authorization-mode=${DESIRED_MODE}" '
                /name: kube-apiserver/ { in_container=1 }
                in_container && /args:/ { in_args=1 }
                in_container && in_args && $1 !~ /^-/ && $1 !~ /^args:/ && $1 !~ /^#/ && !inserted {
                  print flag
                  inserted=1
                }
                { print $0 }
                END {
                  if (!inserted) {
                    print flag
                  }
                }
              ' "${API_MANIFEST}" > "${TMP_FILE}"
            fi
          fi

          cp "${TMP_FILE}" "${API_MANIFEST}"
          sync
          echo "[INFO] Manifest updated. kubelet will restart kube-apiserver static pod automatically."
        fi

        echo "[INFO] Waiting 30 seconds for kube-apiserver to restart..."
        sleep 30

        echo "[INFO] Verification: checking running kube-apiserver process"
        if ! /bin/ps -ef | grep kube-apiserver | grep -v grep > /dev/null 2>&1; then
          echo "[ERROR] kube-apiserver process not found after change; check kubelet and pod status."
          exit 1
        fi

        AUTH_LINE="$(/bin/ps -ef | grep kube-apiserver | grep -v grep | tr -s ' ' | sed -E 's/.*kube-apiserver (.*)/\1/' | tr ' ' '\n' | grep '^--authorization-mode=' || true)"

        if [[ -z "${AUTH_LINE}" ]]; then
          echo "[WARN] --authorization-mode flag not visible in process arguments."
          echo "[WARN] Ensure authorization is configured via config file and not using AlwaysAllow."
        else
          AUTH_VALUE="${AUTH_LINE#--authorization-mode=}"
          if [[ "${AUTH_VALUE}" == "AlwaysAllow" ]]; then
            echo "[ERROR] kube-apiserver is still using --authorization-mode=AlwaysAllow"
            exit 1
          fi
          echo "[INFO] kube-apiserver --authorization-mode is now set to: ${AUTH_VALUE}"
        fi

        echo "[INFO] Remediation verification completed."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
