Ensure Admission Control Plugin AlwaysAdmit Is Not Set
More Info:
Do not allow all requests.
Risk Level
Low
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every control plane node, open the kube-apiserver static pod manifest in an editor:
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml -
In the
spec.containers[0].commandlist, locate any line containing--enable-admission-plugins=.- If the value contains
AlwaysAdmit, remove onlyAlwaysAdmitfrom the comma‑separated list (and any now-superfluous comma). - If
AlwaysAdmitis the only value, remove the entire--enable-admission-plugins=AlwaysAdmitargument line.
- If the value contains
-
Still in the same manifest, if there is a separate
--admission-control=argument and it containsAlwaysAdmit, remove onlyAlwaysAdmitfrom that comma‑separated list, or remove the whole argument if it only containsAlwaysAdmit. -
Save the file and exit the editor. The kubelet will automatically detect the manifest change and restart the
kube-apiserverstatic pod; expect a brief control-plane disruption while it restarts. -
Wait for the new
kube-apiserverprocess to be running:sudo crictl ps | grep kube-apiserver(If
crictlis not available, usesudo docker ps | grep kube-apiserverdepending on your container runtime.) -
Verify that
AlwaysAdmitis no longer configured in the API server arguments on each control plane node:/bin/ps -ef | grep kube-apiserver | grep -v grep | grep AlwaysAdmit || echo "AlwaysAdmit not present"
Using kubectl
kubectl cannot modify the kube-apiserver static pod manifest or its process flags, so this finding cannot be fixed via the Kubernetes API. The configuration must be changed directly on each control plane node at /etc/kubernetes/manifests/kube-apiserver.yaml; see the Manual Steps section for how to do this.
Automation
#!/usr/bin/env bash
#
# Automation: Remove AlwaysAdmit admission plugin from kube-apiserver
#
# Run on: every control plane node (as root)
# Safe to re-run: yes (idempotent)
set -euo pipefail
APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
BACKUP_DIR="/etc/kubernetes/manifests/backup-$(date +%Y%m%d-%H%M%S)"
echo "==> Checking for kube-apiserver manifest at ${APISERVER_MANIFEST}"
if [[ ! -f "${APISERVER_MANIFEST}" ]]; then
echo "ERROR: ${APISERVER_MANIFEST} not found on this node. Is this a control plane node?"
exit 1
fi
echo "==> Creating backup in ${BACKUP_DIR}"
mkdir -p "${BACKUP_DIR}"
cp -p "${APISERVER_MANIFEST}" "${BACKUP_DIR}/"
# Function: remove AlwaysAdmit from an --enable-admission-plugins flag value
sanitize_plugins_line() {
local line="$1"
# Extract the value after '='
local prefix value newvalue
prefix="${line%%--enable-admission-plugins=*}"
value="${line#*--enable-admission-plugins=}"
# If there are spaces after the value, keep only up to first space
value="${value%% *}"
# Convert comma-separated list to array, remove AlwaysAdmit, and rejoin
IFS=',' read -r -a plugins <<< "${value}"
newplugins=()
for p in "${plugins[@]}"; do
[[ "${p}" == "AlwaysAdmit" ]] && continue
[[ -z "${p}" ]] && continue
newplugins+=("${p}")
done
if [[ ${#newplugins[@]} -eq 0 ]]; then
# No plugins left; remove the flag entirely by returning the prefix only
printf '%s\n' "${prefix}"
else
local joined="${newplugins[*]}"
joined="${joined// /,}"
printf '%s--enable-admission-plugins=%s\n' "${prefix}" "${joined}"
fi
}
TMP_FILE="$(mktemp)"
trap 'rm -f "${TMP_FILE}"' EXIT
echo "==> Updating kube-apiserver manifest to ensure AlwaysAdmit is not configured"
changed=false
while IFS= read -r line; do
if [[ "${line}" == *"--enable-admission-plugins="* ]]; then
if [[ "${line}" == *"AlwaysAdmit"* ]]; then
new_line="$(sanitize_plugins_line "${line}")"
# Preserve original indentation by prefixing spaces from original line
indent="${line%%${line##+([[:space:]])}}"
# shellcheck disable=SC2254
new_line="${indent}${new_line#"${new_line%%[![:space:]]*}"}"
echo "${new_line}" >> "${TMP_FILE}"
changed=true
else
echo "${line}" >> "${TMP_FILE}"
fi
else
echo "${line}" >> "${TMP_FILE}"
fi
done < "${APISERVER_MANIFEST}"
if [[ "${changed}" == true ]]; then
echo "==> Applying changes to ${APISERVER_MANIFEST}"
cp "${TMP_FILE}" "${APISERVER_MANIFEST}"
else
echo "==> No occurrences of AlwaysAdmit in --enable-admission-plugins found; no change needed"
fi
# kubelet will automatically restart the kube-apiserver static pod
echo "==> Waiting for kube-apiserver process to reload..."
sleep 30
echo "==> Verification: ensuring kube-apiserver is not started with AlwaysAdmit"
if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q "AlwaysAdmit"; then
echo "VERIFICATION FAILED: kube-apiserver process still has AlwaysAdmit configured:"
/bin/ps -ef | grep kube-apiserver | grep -v grep
exit 1
fi
echo "VERIFICATION PASSED: kube-apiserver process does not include AlwaysAdmit in its arguments."