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
- Remediation
Remediation
Manual Steps
-
On every control plane node, back up the current API server static pod manifest:
sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak.$(date +%F-%H%M%S) -
On every control plane node, edit the API server manifest to remove
AlwaysAllowand enable RBAC (this edit will automatically restart the kube-apiserver when the file is saved):sudo sed -i 's/--authorization-mode=AlwaysAllow/--authorization-mode=RBAC/' /etc/kubernetes/manifests/kube-apiserver.yamlIf
--authorization-modeis missing or contains a list includingAlwaysAllow, edit the file manually:sudo vi /etc/kubernetes/manifests/kube-apiserver.yamland ensure there is a line under
containers: -> kube-apiserver -> command:similar to:- --authorization-mode=RBAC -
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).
-
Verify on every control plane node that the kube-apiserver is no longer using
AlwaysAllowand is using RBAC instead:/bin/ps -ef | grep kube-apiserver | grep -v grepConfirm the
kube-apiserverprocess includes--authorization-mode=RBACand does not contain--authorization-mode=AlwaysAllow.
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.
Automation
#!/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."