> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every control plane node, back up the current manifest before editing:

           ```bash theme={null}
           sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak
           ```

        2. On every control plane node, edit the API server manifest to set the audit log max size (example: 100 MB):

           ```bash theme={null}
           sudo sed -i 's@^\(\s*-\s*--audit-log-maxsize=\).*@\1100@' /etc/kubernetes/manifests/kube-apiserver.yaml
           ```

           If the flag does not exist, add this line under the `command:` section with the other `- --` flags:

           ```bash theme={null}
           sudo sed -i '/kube-apiserver$/a\ \ \ \ - --audit-log-maxsize=100' /etc/kubernetes/manifests/kube-apiserver.yaml
           ```

        3. Wait for the kubelet on each control plane node to automatically restart the `kube-apiserver` static 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.

        4. Verify on every control plane node that the API server is running with the correct `--audit-log-maxsize` value:

           ```bash theme={null}
           /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -- '--audit-log-maxsize=100'
           ```

           The command should return a line showing `--audit-log-maxsize=100` in the kube-apiserver process arguments.
      </Accordion>

      <Accordion title="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.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/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})."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
