API Server Audit Log Maxsize Should Be 100 Or More
More Info:
Verifies that --audit-log-maxsize is set to 100 MB or an appropriate value to control rotation of audit log files.
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 manifest before editing:
sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak -
On every control plane node, edit the API server manifest to set the audit log max size (example: 100 MB):
sudo sed -i 's@^\(\s*-\s*--audit-log-maxsize=\).*@\1100@' /etc/kubernetes/manifests/kube-apiserver.yamlIf the flag does not exist, add this line under the
command:section with the other- --flags:sudo sed -i '/kube-apiserver$/a\ \ \ \ - --audit-log-maxsize=100' /etc/kubernetes/manifests/kube-apiserver.yaml -
Wait for the kubelet on each control plane node to automatically restart the
kube-apiserverstatic pod after the manifest change (this happens automatically; no manual restart command is needed). Be aware this briefly restarts the API server on that node. -
Verify on every control plane node that the API server is running with the correct
--audit-log-maxsizevalue:/bin/ps -ef | grep kube-apiserver | grep -v grep | grep -- '--audit-log-maxsize=100'The command should return a line showing
--audit-log-maxsize=100in the kube-apiserver process arguments.
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 --audit-log-maxsize setting must be changed directly in /etc/kubernetes/manifests/kube-apiserver.yaml on every control plane node; follow the Manual Steps section to make and verify that change.
Automation
#!/usr/bin/env bash
#
# Automation: Ensure kube-apiserver --audit-log-maxsize >= 100
#
# Usage:
# Run on every control plane node as root:
# sudo bash ./fix-apiserver-audit-log-maxsize.sh
#
# This script is idempotent and safe to re-run.
set -euo pipefail
APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
MIN_SIZE=100
echo "==> Checking for kube-apiserver manifest at ${APISERVER_MANIFEST}"
if [[ ! -f "${APISERVER_MANIFEST}" ]]; then
echo "ERROR: ${APISERVER_MANIFEST} not found on this node. This script must run on a control plane node."
exit 1
fi
# Create a timestamped backup once per run (ok if re-run; multiple backups are fine)
BACKUP="${APISERVER_MANIFEST}.$(date +%Y%m%d%H%M%S).bak"
cp "${APISERVER_MANIFEST}" "${BACKUP}"
echo "==> Backup created: ${BACKUP}"
# Extract current value if present
CURRENT_VAL_RAW=$(grep -E -- '--audit-log-maxsize=' "${APISERVER_MANIFEST}" 2>/dev/null || true)
CURRENT_VAL=""
if [[ -n "${CURRENT_VAL_RAW}" ]]; then
# Handle forms like:
# - --audit-log-maxsize=100
# - - --audit-log-maxsize=100 (with leading YAML dash)
CURRENT_VAL=$(echo "${CURRENT_VAL_RAW}" | sed -E 's/.*--audit-log-maxsize=([0-9]+).*/\1/' | head -n1 || true)
fi
need_change=false
if [[ -z "${CURRENT_VAL}" ]]; then
echo "==> --audit-log-maxsize not currently set; will add with value ${MIN_SIZE}"
need_change=true
elif [[ "${CURRENT_VAL}" -lt "${MIN_SIZE}" ]]; then
echo "==> --audit-log-maxsize currently ${CURRENT_VAL}, which is < ${MIN_SIZE}; will update to ${MIN_SIZE}"
need_change=true
else
echo "==> --audit-log-maxsize currently ${CURRENT_VAL}, which is >= ${MIN_SIZE}; no change needed."
fi
if [[ "${need_change}" == true ]]; then
TMP_FILE="$(mktemp)"
echo "==> Updating ${APISERVER_MANIFEST}"
if grep -q -- '--audit-log-maxsize=' "${APISERVER_MANIFEST}"; then
# Replace existing value with MIN_SIZE
sed -E "s/(--audit-log-maxsize=)[0-9]+/\1${MIN_SIZE}/" "${APISERVER_MANIFEST}" > "${TMP_FILE}"
else
# Insert new flag on its own line under other --audit-log-* or generic args
#
# Strategy: append a new argument line right after the last existing --audit-log-* flag
# if present, otherwise after the last apiserver argument line (starting with ' - --').
if grep -qE '^\s*-\s*--audit-log-' "${APISERVER_MANIFEST}"; then
# After last --audit-log-* line
awk -v minsize="${MIN_SIZE}" '
/^\s*-\s*--audit-log-/ { last_audit_line=NR }
{ lines[NR]=$0 }
END {
for (i=1; i<=NR; i++) {
print lines[i]
if (i==last_audit_line) {
print gensub(/^( *).*/, "\\1- --audit-log-maxsize=" minsize, 1, lines[i])
}
}
}
' "${APISERVER_MANIFEST}" > "${TMP_FILE}"
else
# After last generic arg line
awk -v minsize="${MIN_SIZE}" '
/^\s*-\s*--/ { last_arg_line=NR }
{ lines[NR]=$0 }
END {
for (i=1; i<=NR; i++) {
print lines[i]
if (i==last_arg_line) {
print gensub(/^( *).*/, "\\1- --audit-log-maxsize=" minsize, 1, lines[i])
}
}
}
' "${APISERVER_MANIFEST}" > "${TMP_FILE}"
fi
fi
# Basic sanity check: ensure the resulting file still has apiServer container definition
if ! grep -q "kube-apiserver" "${TMP_FILE}"; then
echo "ERROR: Modified manifest does not contain kube-apiserver; refusing to overwrite."
rm -f "${TMP_FILE}"
exit 1
fi
mv "${TMP_FILE}" "${APISERVER_MANIFEST}"
echo "==> Updated ${APISERVER_MANIFEST} with --audit-log-maxsize=${MIN_SIZE}"
echo "==> kube-apiserver static pod will be restarted automatically by the kubelet."
fi
echo "==> Waiting for kube-apiserver process to reflect new arguments..."
sleep 10
echo "==> Verification (ps -ef | grep kube-apiserver | grep -v grep)"
ps -ef | grep kube-apiserver | grep -v grep || {
echo "ERROR: kube-apiserver process not found after change."
exit 1
}
echo
echo "==> Checking for --audit-log-maxsize >= ${MIN_SIZE} in running process:"
ps -ef | grep kube-apiserver | grep -v grep | tr ' ' '\n' | grep -- '--audit-log-maxsize=' || {
echo "ERROR: --audit-log-maxsize flag not found in running kube-apiserver."
exit 1
}
RUNNING_VAL=$(ps -ef | grep kube-apiserver | grep -v grep | tr ' ' '\n' | grep -- '--audit-log-maxsize=' | sed -E 's/.*--audit-log-maxsize=([0-9]+).*/\1/' | head -n1 || true)
if [[ -z "${RUNNING_VAL}" || "${RUNNING_VAL}" -lt "${MIN_SIZE}" ]]; then
echo "ERROR: Running kube-apiserver --audit-log-maxsize is '${RUNNING_VAL}', expected >= ${MIN_SIZE}."
exit 1
fi
echo "==> Success: running kube-apiserver has --audit-log-maxsize=${RUNNING_VAL} (>= ${MIN_SIZE})."