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​
- Remediation
Remediation​
Manual Steps
-
On every worker node, confirm how kubelet is configured and where its config file is:
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=AlwaysAllowdirectly, follow step 3 (flag-based config).
- If you see
-
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):sudo vi /var/lib/kubelet/config.yamlEnsure these sections exist and are set as follows (add or adjust as needed):
authentication:webhook:enabled: trueauthorization:mode: WebhookSave the file.
-
If using executable arguments and you find
--authorization-mode=AlwaysAllowor missing webhook options in the systemd drop-in, edit the kubelet args file:sudo vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.confIn the line defining extra args (for example
KUBELET_ARGS=orKUBELET_CONFIG_ARGS=), remove any--authorization-mode=AlwaysAllowand ensure the following flags are present:--authentication-token-webhook \--authorization-mode=WebhookSave the file.
-
Reload systemd configuration and restart kubelet (this will restart the kubelet on this worker node):
sudo systemctl daemon-reloadsudo systemctl restart kubelet.service -
Confirm kubelet is healthy on the node:
sudo systemctl status kubelet -l -
Verify that kubelet is no longer using
AlwaysAllowand that Webhook mode is in use:/bin/ps -fC kubeletIn the output:
- You should NOT see
--authorization-mode=AlwaysAllow. - If using flags, you SHOULD see
--authorization-mode=Webhookand--authentication-token-webhook. - If using a config file only, you should still not see
AlwaysAllow, and you have already setauthorization.mode: Webhookin/var/lib/kubelet/config.yaml.
- You should NOT see
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.
Automation
#!/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 "$@"