Ensure Authorization Mode Argument Is Not Set Always Allow
More Info:
Do not allow all requests. Enable explicit authorization.
Risk Level
Medium
Address
Security
Compliance Standards
- APRA CPS 234 (Australia)
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS AKS
- CIS Critical Security Controls v8
- CMMC 2.0
- CSA Cloud Controls Matrix v4
- DPDPA
- Digital Operational Resilience Act (EU)
- Essential 8
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- MITRE ATT&CK (Cloud)
- NIS2 Directive
- NIST SP 800-171
- NYDFS 23 NYCRR 500
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every worker node, open the kubelet config file and set authorization mode to Webhook:
sudo sed -i 's/^authorization:.*$/authorization:\n mode: Webhook/' /var/lib/kubelet/config.yaml || {echo "authorization:" | sudo tee -a /var/lib/kubelet/config.yamlecho " mode: Webhook" | sudo tee -a /var/lib/kubelet/config.yaml} -
If the kubelet is started with flags instead of (or in addition to) the config file, edit the systemd drop-in on every worker node:
sudo nano /etc/systemd/system/kubelet.service.d/10-kubeadm.confIn the
Environment="KUBELET_AUTHZ_ARGS=..."line, ensure it contains:--authorization-mode=Webhookand remove any
--authorization-mode=AlwaysAllowif present. Save and exit. -
Reload systemd and restart kubelet on every worker node so changes take effect:
sudo systemctl daemon-reloadsudo systemctl restart kubelet.service -
Verify on every worker node that kubelet is no longer using AlwaysAllow and is using Webhook:
/bin/ps -fC kubeletConfirm the output does not contain
--authorization-mode=AlwaysAllowand shows--authorization-mode=Webhookor that the process is using/var/lib/kubelet/config.yamlwithauthorization: mode: Webhook.
Using kubectl
kubectl cannot change kubelet authorization settings because they are controlled by host-level configuration on each worker node (for example /var/lib/kubelet/config.yaml or the systemd unit). Make the changes directly on the nodes as described in the Manual Steps section.
Automation
#!/usr/bin/env bash
# Purpose: Ensure kubelet authorization mode is set to Webhook on every worker node.
# Scope: Run on EACH worker node as root.
# Idempotent: Safe to re-run.
set -euo pipefail
KUBELET_CONFIG="/var/lib/kubelet/config.yaml"
SYSTEMD_DROPIN="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
echo "[INFO] Updating kubelet authorization mode on worker node: $(hostname)"
if [[ ! -f "${KUBELET_CONFIG}" ]]; then
echo "[ERROR] Kubelet config file ${KUBELET_CONFIG} not found. Aborting."
exit 1
fi
# Backup once
if [[ ! -f "${KUBELET_CONFIG}.bak.cisaks-3.2.2" ]]; then
cp -p "${KUBELET_CONFIG}" "${KUBELET_CONFIG}.bak.cisaks-3.2.2"
echo "[INFO] Backup created at ${KUBELET_CONFIG}.bak.cisaks-3.2.2"
fi
# Ensure 'authorization:' block exists and set mode: Webhook
# This uses a conservative edit: remove any existing 'authorization:' block
# and append a clean one at the end.
tmp_cfg="$(mktemp)"
trap 'rm -f "${tmp_cfg}"' EXIT
in_auth_block=0
while IFS='' read -r line; do
# Detect start of authorization block
if [[ "${line}" =~ ^authorization:([[:space:]]*)$ ]]; then
in_auth_block=1
continue
fi
# If inside authorization block, skip lines indented under it
if [[ ${in_auth_block} -eq 1 ]]; then
if [[ "${line}" =~ ^[[:space:]] ]]; then
continue
else
in_auth_block=0
fi
fi
echo "${line}" >> "${tmp_cfg}"
done < "${KUBELET_CONFIG}"
# Append correct authorization block (2-space indent)
cat >> "${tmp_cfg}" <<'EOF'
authorization:
mode: Webhook
EOF
# Only replace if changed
if ! diff -q "${KUBELET_CONFIG}" "${tmp_cfg}" >/dev/null 2>&1; then
cp "${tmp_cfg}" "${KUBELET_CONFIG}"
echo "[INFO] Updated ${KUBELET_CONFIG} with authorization.mode=Webhook"
else
echo "[INFO] ${KUBELET_CONFIG} already has authorization.mode=Webhook"
fi
# Ensure systemd drop-in does NOT force an AlwaysAllow mode; set to Webhook if present.
if [[ -f "${SYSTEMD_DROPIN}" ]]; then
if ! grep -q 'KUBELET_AUTHZ_ARGS' "${SYSTEMD_DROPIN}"; then
# Add variable with Webhook
cat >> "${SYSTEMD_DROPIN}" <<'EOF'
Environment="KUBELET_AUTHZ_ARGS=--authorization-mode=Webhook"
EOF
echo "[INFO] Added KUBELET_AUTHZ_ARGS to ${SYSTEMD_DROPIN}"
else
# Replace any existing authorization-mode value with Webhook
sed -i \
-e 's/--authorization-mode=[^" ]*/--authorization-mode=Webhook/g' \
"${SYSTEMD_DROPIN}"
echo "[INFO] Ensured KUBELET_AUTHZ_ARGS uses --authorization-mode=Webhook in ${SYSTEMD_DROPIN}"
fi
else
echo "[WARN] ${SYSTEMD_DROPIN} not found; assuming kubelet uses only config file."
fi
echo "[INFO] Reloading systemd and restarting kubelet (this will restart the kubelet process)."
systemctl daemon-reload
systemctl restart kubelet.service
sleep 5
echo "[INFO] Verifying kubelet authorization mode (via process flags and config)..."
/bin/ps -fC kubelet || {
echo "[ERROR] kubelet process not found after restart."
exit 1
}
# Check process args for any AlwaysAllow
if /bin/ps -fC kubelet | grep -q -- '--authorization-mode=AlwaysAllow'; then
echo "[ERROR] kubelet still running with --authorization-mode=AlwaysAllow in process flags."
exit 1
fi
# Verify config file contains mode: Webhook
if ! grep -qE '^authorization:[[:space:]]*$' "${KUBELET_CONFIG}" || \
! grep -qE '^[[:space:]]+mode:[[:space:]]*Webhook[[:space:]]*$' "${KUBELET_CONFIG}"; then
echo "[ERROR] ${KUBELET_CONFIG} does not show authorization.mode=Webhook."
exit 1
fi
echo "[INFO] Verification complete: kubelet authorization mode is not AlwaysAllow and is configured as Webhook."