Skip to main content

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

Remediation

Manual Steps
  1. On every control plane node, back up the API server static pod manifest and open it for editing:

    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:
      - --authorization-mode=RBAC
    • If multiple modes are configured, ensure AlwaysAllow is not among them, for example:
      - --authorization-mode=Node,RBAC
    • If the flag is missing, add a new line under the other -- flags:
      - --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):

    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:

    /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).

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.

Automation
#!/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."