> ## 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 That The --authorization-mode Argument Is Not Set To AlwaysAllow

### More Info:

Setting the kubelet authorization mode to AlwaysAllow permits every authenticated request without checking permissions. Use Webhook mode so requests are authorized against the API server.

### Risk Level

Critical

### Address

Security

### Compliance Standards

* CIS EKS

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, confirm how kubelet is configured and where its config file is:
           ```bash theme={null}
           ps -ef | grep kubelet
           ```
           * If you see `--config=/var/lib/kubelet/config.yaml` (or another path), note that path.
           * If you instead see flags like `--authorization-mode=AlwaysAllow` directly, follow step 3 (flag-based config).

        2. If using the kubelet config file (e.g. `/var/lib/kubelet/config.yaml`), edit it to enable webhook authn/z (YAML form of the benchmark’s JSON example):
           ```bash theme={null}
           sudo vi /var/lib/kubelet/config.yaml
           ```
           Ensure these sections exist and are set as follows (add or adjust as needed):
           ```yaml theme={null}
           authentication:
             webhook:
               enabled: true

           authorization:
             mode: Webhook
           ```
           Save the file.

        3. If using executable arguments and you find `--authorization-mode=AlwaysAllow` or missing webhook options in the systemd drop-in, edit the kubelet args file:
           ```bash theme={null}
           sudo vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
           ```
           In the line defining extra args (for example `KUBELET_ARGS=` or `KUBELET_CONFIG_ARGS=`), remove any `--authorization-mode=AlwaysAllow` and ensure the following flags are present:
           ```text theme={null}
           --authentication-token-webhook \
           --authorization-mode=Webhook
           ```
           Save the file.

        4. Reload systemd configuration and restart kubelet (this will restart the kubelet on this worker node):
           ```bash theme={null}
           sudo systemctl daemon-reload
           sudo systemctl restart kubelet.service
           ```

        5. Confirm kubelet is healthy on the node:
           ```bash theme={null}
           sudo systemctl status kubelet -l
           ```

        6. Verify that kubelet is no longer using `AlwaysAllow` and that Webhook mode is in use:
           ```bash theme={null}
           /bin/ps -fC kubelet
           ```
           In the output:
           * You should NOT see `--authorization-mode=AlwaysAllow`.
           * If using flags, you SHOULD see `--authorization-mode=Webhook` and `--authentication-token-webhook`.
           * If using a config file only, you should still not see `AlwaysAllow`, and you have already set `authorization.mode: Webhook` in `/var/lib/kubelet/config.yaml`.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot change the kubelet’s `--authorization-mode` or the contents of `/var/lib/kubelet/config.yaml`, because these are host-level settings managed on each worker node’s OS and systemd units. To remediate this finding, make the changes directly on every worker node as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Fix CISEKS 3.2.2:
        # Ensure kubelet authorization mode is not AlwaysAllow and Webhook is enabled.
        #
        # Run on: every worker node (as root or with sudo).
        # Safe to re-run (idempotent).

        set -euo pipefail

        log() { printf '[%s] %s\n' "$(date -u +%FT%TZ)" "$*"; }

        require_root() {
          if [ "$(id -u)" -ne 0 ]; then
            log "ERROR: This script must be run as root (or via sudo)."
            exit 1
          fi
        }

        find_kubelet_config_from_process() {
          # Try to get --config from running kubelet
          if ! pgrep -x kubelet >/dev/null 2>&1; then
            log "ERROR: kubelet process not found; cannot auto-detect config. Aborting."
            return 1
          fi

          local cmdline
          cmdline=$(tr '\0' ' ' < /proc/"$(pgrep -x kubelet | head -n1)"/cmdline)

          # Extract value of --config=... or --config <path>
          if grep -q -- '--config=' <<<"$cmdline"; then
            awk '
              {
                for (i=1; i<=NF; i++) {
                  if ($i ~ /^--config=/) {
                    sub(/^--config=/, "", $i);
                    print $i;
                    exit;
                  }
                }
              }' <<<"$cmdline"
          elif grep -q -- '--config ' <<<"$cmdline"; then
            # Handle "--config /path"
            awk '
              {
                for (i=1; i<=NF; i++) {
                  if ($i == "--config") {
                    print $(i+1);
                    exit;
                  }
                }
              }' <<<"$cmdline"
          else
            echo ""
          fi
        }

        ensure_kubelet_yaml_authz_webhook() {
          local cfg="$1"

          if [ ! -f "$cfg" ]; then
            log "ERROR: kubelet config file '$cfg' not found."
            return 1
          fi

          log "Using kubelet config file: $cfg"

          # Backup once per run
          if [ ! -f "${cfg}.cis-3.2.2.bak" ]; then
            cp -p "$cfg" "${cfg}.cis-3.2.2.bak"
            log "Backup created at ${cfg}.cis-3.2.2.bak"
          fi

          # Ensure authentication.webhook.enabled: true
          if ! grep -qE '^[[:space:]]*authentication:' "$cfg"; then
            cat >>"$cfg" <<'EOF'

        authentication:
          webhook:
            enabled: true
        EOF
            log "Added authentication.webhook.enabled: true block."
          elif ! grep -qE '^[[:space:]]*webhook:' "$cfg" || \
               ! grep -qE '^[[:space:]]*enabled:[[:space:]]*true' "$cfg"; then
            # Use a temporary edited file to avoid complex inline YAML tooling
            local tmp
            tmp=$(mktemp)
            awk '
              BEGIN {in_auth=0}
              /^[[:space:]]*authentication:/ {in_auth=1}
              {
                if (in_auth && $0 ~ /^[[:space:]]*authorization:/) {
                  # Insert webhook block before authorization or next section
                  print "authentication:"
                  print "  webhook:"
                  print "    enabled: true"
                  in_auth=0
                }
                print
              }
            ' "$cfg" >"$tmp" || { rm -f "$tmp"; return 1; }
            mv "$tmp" "$cfg"
            log "Ensured authentication.webhook.enabled: true in existing block."
          else
            log "authentication.webhook.enabled: true already present."
          fi

          # Ensure authorization: mode: Webhook
          if ! grep -qE '^[[:space:]]*authorization:' "$cfg"; then
            cat >>"$cfg" <<'EOF'

        authorization:
          mode: Webhook
        EOF
            log "Added authorization.mode: Webhook block."
          else
            # Normalize mode under authorization
            local tmp
            tmp=$(mktemp)
            awk '
              BEGIN {in_authz=0}
              /^[[:space:]]*authorization:/ {in_authz=1}
              /^[[:space:]]*[A-Za-z]/ && !/^[[:space:]]*authorization:/ && in_authz==1 {
                # Next top-level starts, close block
                in_authz=0
              }
              {
                if (in_authz && $0 ~ /^[[:space:]]*mode:/) {
                  sub(/mode:[[:space:]]*.*/, "mode: Webhook");
                }
                print
              }
            ' "$cfg" >"$tmp" || { rm -f "$tmp"; return 1; }
            mv "$tmp" "$cfg"
            log "Set authorization.mode: Webhook in existing block."
          fi
        }

        ensure_kubelet_systemd_args() {
          local dropin="/etc/systemd/system/kubelet.service.d/10-kubelet-args.conf"

          if [ ! -f "$dropin" ]; then
            log "No kubelet systemd args drop-in at $dropin; assuming config file method."
            return 0
          fi

          log "Ensuring webhook auth/authorization flags in $dropin"

          if ! grep -q -- '--authentication-token-webhook' "$dropin"; then
            sed -i 's#KUBELET_ARGS="#KUBELET_ARGS="--authentication-token-webhook #g' "$dropin" || true
            if ! grep -q -- '--authentication-token-webhook' "$dropin"; then
              echo 'KUBELET_ARGS="--authentication-token-webhook ${KUBELET_ARGS}"' >>"$dropin"
            fi
            log "Ensured --authentication-token-webhook in KUBELET_ARGS."
          else
            log "--authentication-token-webhook already present."
          fi

          if grep -q -- '--authorization-mode=' "$dropin"; then
            sed -i 's#--authorization-mode=[^" ]*#--authorization-mode=Webhook#g' "$dropin"
            log "Replaced existing --authorization-mode with Webhook."
          else
            sed -i 's#KUBELET_ARGS="#KUBELET_ARGS="--authorization-mode=Webhook #g' "$dropin" || true
            if ! grep -q -- '--authorization-mode=Webhook' "$dropin"; then
              echo 'KUBELET_ARGS="--authorization-mode=Webhook ${KUBELET_ARGS}"' >>"$dropin"
            fi
            log "Ensured --authorization-mode=Webhook in KUBELET_ARGS."
          fi
        }

        restart_kubelet() {
          log "Reloading systemd and restarting kubelet..."
          systemctl daemon-reload
          systemctl restart kubelet.service
          systemctl status kubelet -l --no-pager || true
        }

        verify() {
          log "Verification: checking kubelet process flags and config..."

          /bin/ps -fC kubelet || {
            log "ERROR: kubelet process not found after restart."
            return 1
          }

          local cmdline
          cmdline=$(tr '\0' ' ' < /proc/"$(pgrep -x kubelet | head -n1)"/cmdline)
          log "kubelet cmdline: $cmdline"

          if echo "$cmdline" | grep -q -- '--authorization-mode=AlwaysAllow'; then
            log "ERROR: kubelet still running with --authorization-mode=AlwaysAllow"
            return 1
          fi

          if echo "$cmdline" | grep -q -- '--authorization-mode=Webhook'; then
            log "OK: kubelet uses --authorization-mode=Webhook flag."
          else
            log "INFO: kubelet may be using Webhook via config file (no explicit flag)."
          fi

          # If config file is in use and exists, inspect it for sanity
          local cfg
          cfg=$(find_kubelet_config_from_process || echo "")
          if [ -n "$cfg" ] && [ -f "$cfg" ]; then
            log "Inspecting kubelet config file at $cfg"
            grep -nE 'authentication:|webhook|authorization:|mode:' "$cfg" || true
          fi

          log "Verification completed."
        }

        main() {
          require_root

          # Prefer config file if present
          local cfg
          cfg=$(find_kubelet_config_from_process || echo "")

          if [ -z "$cfg" ]; then
            log "No --config argument detected; using systemd executable-args remediation."
            ensure_kubelet_systemd_args
          else
            ensure_kubelet_yaml_authz_webhook "$cfg"
            # Also ensure flags if the environment uses them; harmless if not used.
            ensure_kubelet_systemd_args
          fi

          restart_kubelet
          verify
        }

        main "$@"
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
