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

The kubelet --authorization-mode must not be AlwaysAllow, which would authorize every request. Use Webhook so requests are properly authorized.

### Risk Level

Critical

### Address

Security

### Compliance Standards

* CIS AKS

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, back up the existing kubelet config file:

        ```bash theme={null}
        sudo cp -p /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%F-%H%M%S)
        ```

        2. On every worker node, edit `/var/lib/kubelet/config.yaml` and set the authorization mode to `Webhook` (create the block if it does not exist). For example:

        ```bash theme={null}
        sudo sed -i 's/^authorization:.*//g' /var/lib/kubelet/config.yaml
        sudo sed -i '/^$/d' /var/lib/kubelet/config.yaml
        printf '\nauthorization:\n  mode: Webhook\n' | sudo tee -a /var/lib/kubelet/config.yaml
        ```

        (If your file already has an `authorization:` block, instead open it in an editor and change only the `mode:` line to `mode: Webhook`.)

        3. If the worker node also sets kubelet flags via systemd, ensure `--authorization-mode` is not set to `AlwaysAllow`. On each worker node:

        ```bash theme={null}
        sudo sed -i 's/--authorization-mode=AlwaysAllow//g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
        ```

        If you need to explicitly set Webhook via flags, append:

        ```bash theme={null}
        sudo sed -i 's#KUBELET_AUTHZ_ARGS="#KUBELET_AUTHZ_ARGS="--authorization-mode=Webhook #g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
        ```

        4. On every worker node, reload systemd and restart kubelet (this restarts the kubelet process and may briefly impact node readiness):

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

        5. On every worker node, verify kubelet is no longer using `AlwaysAllow`:

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

        Confirm the `kubelet` command line does not contain `--authorization-mode=AlwaysAllow` and, if present, uses `--authorization-mode=Webhook`.
      </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. Make the change directly on each worker node as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Fix CIS AKS 3.2.2: ensure kubelet authorization.mode is Webhook
        # Target: every worker node
        # Run on: each worker node (as root)
        #
        # Idempotent: safe to re-run.

        set -euo pipefail

        KUBELET_CONFIG="/var/lib/kubelet/config.yaml"
        SYSTEMD_UNIT="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"

        echo "[INFO] Starting kubelet authorization-mode remediation"

        ############################################
        # 1. Ensure kubelet config.yaml uses Webhook
        ############################################
        if [ -f "${KUBELET_CONFIG}" ]; then
          echo "[INFO] Detected kubelet config file at ${KUBELET_CONFIG}"

          # Ensure 'authorization:' block exists
          if ! grep -qE '^[[:space:]]*authorization:' "${KUBELET_CONFIG}"; then
            echo "[INFO] Adding authorization block to ${KUBELET_CONFIG}"
            cat <<'EOF' >> "${KUBELET_CONFIG}"

        authorization:
          mode: Webhook
        EOF
          else
            echo "[INFO] Updating authorization.mode to Webhook in ${KUBELET_CONFIG}"

            # If 'mode:' exists under authorization, change to Webhook; otherwise add it.
            # This uses a small awk program to be robust and idempotent.
            tmpfile="$(mktemp)"
            awk '
              BEGIN {
                in_auth = 0
              }
              /^[[:space:]]*authorization:[[:space:]]*$/ {
                in_auth = 1
                print
                next
              }
              /^[^[:space:]]/ {
                # new top-level section
                if (in_auth == 1) {
                  # we just left authorization block without seeing mode, so add it
                  print "  mode: Webhook"
                }
                in_auth = 0
                print
                next
              }
              {
                if (in_auth == 1 && $1 == "mode:" ) {
                  # replace mode line
                  sub(/mode:[[:space:]]*.*/, "mode: Webhook")
                  print
                } else {
                  print
                }
              }
              END {
                if (in_auth == 1) {
                  # file ended while still in authorization block; ensure mode present
                  print "  mode: Webhook"
                }
              }
            ' "${KUBELET_CONFIG}" > "${tmpfile}"
            cp "${tmpfile}" "${KUBELET_CONFIG}"
            rm -f "${tmpfile}"
          fi
        else
          echo "[WARN] ${KUBELET_CONFIG} not found; skipping config.yaml-based change"
        fi

        ###################################################
        # 2. Ensure kubelet systemd args do not force AlwaysAllow
        #    and prefer Webhook if using CLI flags
        ###################################################
        if [ -f "${SYSTEMD_UNIT}" ]; then
          echo "[INFO] Detected kubelet systemd drop-in at ${SYSTEMD_UNIT}"

          # Ensure KUBELET_AUTHZ_ARGS line exists
          if ! grep -q 'KUBELET_AUTHZ_ARGS' "${SYSTEMD_UNIT}"; then
            echo "[INFO] Adding KUBELET_AUTHZ_ARGS with --authorization-mode=Webhook"
            cat <<'EOF' >> "${SYSTEMD_UNIT}"
        Environment="KUBELET_AUTHZ_ARGS=--authorization-mode=Webhook"
        EOF
          else
            echo "[INFO] Updating KUBELET_AUTHZ_ARGS to use --authorization-mode=Webhook"
            # Remove any existing --authorization-mode argument
            sed -i \
              -e 's/\(--authorization-mode[= ][^" ]*\)//g' \
              "${SYSTEMD_UNIT}"

            # Normalize whitespace inside the line
            sed -i 's/Environment="KUBELET_AUTHZ_ARGS=\s*/Environment="KUBELET_AUTHZ_ARGS=/g' "${SYSTEMD_UNIT}"

            # Ensure Webhook is present
            if grep -q 'KUBELET_AUTHZ_ARGS=.*--authorization-mode=Webhook' "${SYSTEMD_UNIT}"; then
              echo "[INFO] KUBELET_AUTHZ_ARGS already contains --authorization-mode=Webhook"
            else
              # Append to existing value, taking care of quotes
              sed -i 's/^\(Environment="KUBELET_AUTHZ_ARGS=.*\)"/\1 --authorization-mode=Webhook"/' "${SYSTEMD_UNIT}"
            fi
          fi
        else
          echo "[WARN] ${SYSTEMD_UNIT} not found; skipping CLI-flag-based change"
        fi

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

        #####################################
        # 4. Verification (CIS audit adaptation)
        #####################################
        echo "[INFO] Verifying kubelet authorization-mode (via process flags and config.yaml)"

        # Original audit style: process listing
        /bin/ps -fC kubelet || {
          echo "[ERROR] kubelet process not found after restart"
          exit 1
        }

        # Show process args for manual confirmation
        echo "[INFO] kubelet process arguments:"
        /bin/ps -o pid,cmd -C kubelet

        # Check for AlwaysAllow in process args
        if /bin/ps -o cmd -C kubelet | grep -q -- '--authorization-mode=AlwaysAllow'; then
          echo "[ERROR] kubelet still running with --authorization-mode=AlwaysAllow"
          exit 1
        fi

        # If using config file, verify mode: Webhook
        if [ -f "${KUBELET_CONFIG}" ]; then
          if grep -qE '^[[:space:]]*authorization:[[:space:]]*$' "${KUBELET_CONFIG}" && \
             awk '
               /^[[:space:]]*authorization:[[:space:]]*$/ { in_auth=1; next }
               /^[^[:space:]]/ { in_auth=0 }
               in_auth && $1=="mode:" { print $2 }
             ' "${KUBELET_CONFIG}" | grep -q '^Webhook$'; then
            echo "[INFO] Verified ${KUBELET_CONFIG} has authorization.mode: Webhook"
          else
            echo "[ERROR] ${KUBELET_CONFIG} does not have authorization.mode: Webhook"
            exit 1
          fi
        fi

        echo "[INFO] Remediation complete on this node"
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
