Skip to main content

Ensure Audit Log Maxage Argument Is Appropriate

More Info:

Retain the logs for at least 30 days or as appropriate.

Risk Level

Low

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. On every control plane node, open the kube-apiserver static pod manifest for editing:

    sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
  2. In the container command section, either add or update the --audit-log-maxage flag to use at least 30 days, for example:

    - --audit-log-maxage=30

    Ensure it is listed as a separate - item alongside the other -- flags.

  3. Save and close the file. The kube-apiserver static pod will be automatically restarted by the kubelet when the manifest changes. Expect a brief control plane disruption while it restarts.

  4. Wait for the kube-apiserver pod to come back to a Running state:

    # from any machine with kubectl access
    kubectl get pods -n kube-system -l component=kube-apiserver -o wide
  5. Verify that the new process is running with the correct --audit-log-maxage setting on each control plane node:

    /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -- '--audit-log-maxage=30'
Using kubectl

kubectl cannot modify the API server’s host-level static pod manifest or its process flags, so this finding cannot be fixed via kubectl. To remediate, you must edit /etc/kubernetes/manifests/kube-apiserver.yaml directly on every control plane node to set --audit-log-maxage=30 (or your chosen value); see the Manual Steps section for details.

Automation
#!/usr/bin/env bash
#
# Fix: Ensure kube-apiserver --audit-log-maxage is set to 30
# Scope: Run on every control plane node (as root)
# Effect: Editing /etc/kubernetes/manifests/kube-apiserver.yaml will restart kube-apiserver (static pod)

set -euo pipefail

MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
BACKUP_DIR="/etc/kubernetes/manifests/backup-$(date +%Y%m%d%H%M%S)"

echo "==> Ensuring kube-apiserver --audit-log-maxage is set to 30"
echo " Manifest: ${MANIFEST}"

if [[ $EUID -ne 0 ]]; then
echo "ERROR: This script must be run as root." >&2
exit 1
fi

if [[ ! -f "${MANIFEST}" ]]; then
echo "ERROR: ${MANIFEST} not found on this node; is this a control plane node?" >&2
exit 1
fi

# Backup manifest once per run
mkdir -p "${BACKUP_DIR}"
cp -p "${MANIFEST}" "${BACKUP_DIR}/"
echo "Backup created at ${BACKUP_DIR}/kube-apiserver.yaml"

# Idempotent edit:
# 1) If --audit-log-maxage exists, set its value to 30
# 2) If it does not exist, add it as a new - --audit-log-maxage=30 line under containers[].command
#
# Assumptions: typical kubeadm-style static pod manifest (command list with one arg per line).

# Step 1: Normalize any existing --audit-log-maxage to 30
if grep -q -- '--audit-log-maxage=' "${MANIFEST}"; then
echo "Found existing --audit-log-maxage, updating value to 30"
# Replace any existing value with 30
sed -i 's/--audit-log-maxage=[0-9][0-9]*/--audit-log-maxage=30/g' "${MANIFEST}"
fi

# Step 2: If argument not present at all, add it
if ! grep -q -- '--audit-log-maxage=' "${MANIFEST}"; then
echo "No --audit-log-maxage found, inserting --audit-log-maxage=30"

# Insert below the first existing command argument line under 'command:' for kube-apiserver container
# This is a YAML-sensitive insertion but robust for common kubeadm layouts.
# We match the line '- kube-apiserver' and insert the new arg right after it.
if grep -qE '^[[:space:]]*- kube-apiserver$' "${MANIFEST}"; then
# Determine indentation from the '- kube-apiserver' line
INDENT=$(grep -E '^[[:space:]]*- kube-apiserver$' "${MANIFEST}" | head -n1 | sed 's/\S.*//')
# Insert the new line after '- kube-apiserver'
# Use awk to remain idempotent and avoid duplicate insertion
awk -v indent="${INDENT}" '
BEGIN { inserted=0 }
{
print $0
if ($0 ~ "^[[:space:]]*- kube-apiserver$" && inserted==0) {
print indent " - --audit-log-maxage=30"
inserted=1
}
}
' "${MANIFEST}" > "${MANIFEST}.tmp"
mv "${MANIFEST}.tmp" "${MANIFEST}"
else
echo "WARNING: Could not locate '- kube-apiserver' command line to insert argument."
echo "Please review ${MANIFEST} manually to ensure --audit-log-maxage=30 is set."
fi
fi

echo "Change applied (or already in desired state)."
echo "kube-apiserver static pod will be restarted automatically by kubelet if the manifest changed."

# Verification: confirm running kube-apiserver process has --audit-log-maxage=30
echo "==> Verifying running kube-apiserver arguments"

# Wait briefly for static pod restart if needed
sleep 10

if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q -- '--audit-log-maxage=30'; then
echo "VERIFIED: kube-apiserver is running with --audit-log-maxage=30"
exit 0
else
echo "WARNING: kube-apiserver process does not show --audit-log-maxage=30 yet."
echo "Current kube-apiserver processes:"
/bin/ps -ef | grep kube-apiserver | grep -v grep || true
echo "Check ${MANIFEST} and kubelet status on this control plane node."
exit 1
fi

Additional Reading: