> ## 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 Authorization Mode Argument Is Not AlwaysAllow

### More Info:

Do not allow all requests. Enable explicit authorization.

### Risk Level

Medium

### 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 current API server static pod manifest:
           ```bash theme={null}
           sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak.$(date +%F-%H%M%S)
           ```

        2. On every control plane node, edit the API server manifest to remove `AlwaysAllow` and enable RBAC (this edit will automatically restart the kube-apiserver when the file is saved):
           ```bash theme={null}
           sudo sed -i 's/--authorization-mode=AlwaysAllow/--authorization-mode=RBAC/' /etc/kubernetes/manifests/kube-apiserver.yaml
           ```
           If `--authorization-mode` is missing or contains a list including `AlwaysAllow`, edit the file manually:
           ```bash theme={null}
           sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
           ```
           and ensure there is a line under `containers: -> kube-apiserver -> command:` similar to:
           ```yaml theme={null}
             - --authorization-mode=RBAC
           ```

        3. Wait for the kubelet on the control plane node to detect the modified manifest and restart the kube-apiserver container (this is automatic and briefly disrupts API server availability).

        4. Verify on every control plane node that the kube-apiserver is no longer using `AlwaysAllow` and is using RBAC instead:
           ```bash theme={null}
           /bin/ps -ef | grep kube-apiserver | grep -v grep
           ```
           Confirm the `kube-apiserver` process includes `--authorization-mode=RBAC` and does not contain `--authorization-mode=AlwaysAllow`.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot change the API server’s `--authorization-mode` flag because it is configured via the static pod manifest on each control plane node, not through Kubernetes API objects. To fix this finding, edit `/etc/kubernetes/manifests/kube-apiserver.yaml` on every control plane node as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Automation: Fix kube-apiserver --authorization-mode so it is not AlwaysAllow
        #
        # Run on: every control plane node (with root privileges)
        #
        # This script:
        #   - Backs up /etc/kubernetes/manifests/kube-apiserver.yaml
        #   - Ensures --authorization-mode does not contain AlwaysAllow
        #   - Sets a sane default (--authorization-mode=RBAC) if none is present
        #   - Leaves other existing authorization modes intact (except AlwaysAllow)
        #   - Triggers kube-apiserver restart via static pod manifest update
        #   - Verifies the running process arguments no longer use AlwaysAllow
        #
        # Usage: sudo bash ./fix-authorization-mode.sh

        set -euo pipefail

        APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
        BACKUP_SUFFIX="$(date +%Y%m%d%H%M%S)"

        echo "[INFO] Starting kube-apiserver authorization-mode remediation"

        if [[ $EUID -ne 0 ]]; then
          echo "[ERROR] This script must be run as root." >&2
          exit 1
        fi

        if [[ ! -f "$APISERVER_MANIFEST" ]]; then
          echo "[ERROR] kube-apiserver manifest not found at $APISERVER_MANIFEST" >&2
          exit 1
        fi

        echo "[INFO] Backing up existing manifest to ${APISERVER_MANIFEST}.bak.${BACKUP_SUFFIX}"
        cp -p "$APISERVER_MANIFEST" "${APISERVER_MANIFEST}.bak.${BACKUP_SUFFIX}"

        TMP_MANIFEST="$(mktemp)"
        cp "$APISERVER_MANIFEST" "$TMP_MANIFEST"

        # Normalize line endings just in case
        dos2unix "$TMP_MANIFEST" >/dev/null 2>&1 || true

        # Function to update the authorization-mode line within a given file
        update_authorization_mode() {
          local file="$1"

          # 1) Remove any occurrence of AlwaysAllow from an existing --authorization-mode arg
          #    while preserving other modes and separators.
          #    Examples handled:
          #      --authorization-mode=AlwaysAllow
          #      --authorization-mode=AlwaysAllow,RBAC
          #      --authorization-mode=RBAC,AlwaysAllow,Webhook
          #
          #    Approach:
          #      - Extract value after '='
          #      - Split on comma, drop AlwaysAllow, rejoin
          #      - If result empty, set to RBAC

          # First, see if a --authorization-mode flag exists at all.
          if grep -q -- '--authorization-mode=' "$file"; then
            # Use a small awk program to safely transform the value.
            awk '
              {
                changed = 0
                for (i = 1; i <= NF; i++) {
                  if ($i ~ /--authorization-mode=/) {
                    split($i, kv, "=")
                    modes = kv[2]
                    n = split(modes, arr, ",")
                    newmodes = ""
                    for (j = 1; j <= n; j++) {
                      if (arr[j] != "AlwaysAllow" && arr[j] != "") {
                        if (newmodes == "") {
                          newmodes = arr[j]
                        } else {
                          newmodes = newmodes "," arr[j]
                        }
                      }
                    }
                    if (newmodes == "") {
                      newmodes = "RBAC"
                    }
                    $i = kv[1] "=" newmodes
                    changed = 1
                  }
                }
                print $0
              }
            ' "$file" > "${file}.tmp_auth" && mv "${file}.tmp_auth" "$file"
          else
            # No existing --authorization-mode; append a new argument line in the args list.
            # This is conservative and will work for standard kubeadm-style manifests.
            # We will add:
            #   - --authorization-mode=RBAC
            #
            # Insert it after the first occurrence of "kube-apiserver" container args list.
            awk '
              $0 ~ /- name: kube-apiserver/ { in_apiserver = 1 }
              in_apiserver && $0 ~ /args:/ { in_args = 1 }
              in_args && $0 ~ /^ *- --/ && !added {
                print $0
                print gensub(/.*/, "          - --authorization-mode=RBAC", 1)
                added = 1
                next
              }
              { print $0 }
            ' "$file" > "${file}.tmp_auth" && mv "${file}.tmp_auth" "$file"

            # As a fallback (if we somehow did not manage to add it in the block above),
            # ensure the flag exists somewhere in the file.
            if ! grep -q -- '--authorization-mode=' "$file"; then
              echo "[WARN] Could not detect args block structure; appending --authorization-mode=RBAC to manifest."
              printf '\n    - --authorization-mode=RBAC\n' >> "$file"
            fi
          fi
        }

        echo "[INFO] Updating --authorization-mode in manifest"
        update_authorization_mode "$TMP_MANIFEST"

        # Confirm we have no AlwaysAllow in the manifest anymore
        if grep -q 'authorization-mode=.*AlwaysAllow' "$TMP_MANIFEST"; then
          echo "[ERROR] Failed to remove AlwaysAllow from manifest; aborting." >&2
          rm -f "$TMP_MANIFEST"
          exit 1
        fi

        echo "[INFO] Writing updated manifest back to $APISERVER_MANIFEST"
        cp "$TMP_MANIFEST" "$APISERVER_MANIFEST"
        rm -f "$TMP_MANIFEST"

        echo "[INFO] kube-apiserver static pod manifest updated."
        echo "[INFO] NOTE: kubelet will restart the kube-apiserver pod automatically based on this change."

        # Wait for process to restart and stabilize
        echo "[INFO] Waiting for kube-apiserver to restart..."
        sleep 30

        # Verification: ensure running kube-apiserver process does not use AlwaysAllow
        echo "[INFO] Verifying that --authorization-mode is not AlwaysAllow in running process"
        if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q 'authorization-mode=.*AlwaysAllow'; then
          echo "[ERROR] kube-apiserver still running with AlwaysAllow in --authorization-mode." >&2
          echo "[ERROR] Inspect process with:" >&2
          echo "  /bin/ps -ef | grep kube-apiserver | grep -v grep" >&2
          exit 1
        fi

        # Also confirm we now have some authorization-mode flag present
        if ! /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q 'authorization-mode='; then
          echo "[WARN] kube-apiserver process does not show an --authorization-mode flag; check component configuration." >&2
        else
          echo "[INFO] kube-apiserver authorization-mode configured without AlwaysAllow."
        fi

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

### Additional Reading:

* [https://kubernetes.io/docs/admin/kubelet/](https://kubernetes.io/docs/admin/kubelet/)
