> ## 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.

# Ensure Audit Log Path Argument Is Set

### More Info:

Enable auditing on the Kubernetes API Server and set the desired audit log path.

### 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, open the API server static pod manifest for editing:
           ```bash theme={null}
           sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
           ```

        2. In the container command/args section for `kube-apiserver`, add or update the audit log path argument so it is present as its own list item, for example:
           ```yaml theme={null}
           - --audit-log-path=/var/log/apiserver/audit.log
           ```
           Ensure it is aligned with the other `- --` arguments under the same list.

        3. Still on the same node, make sure the target directory exists and has appropriate permissions:
           ```bash theme={null}
           sudo mkdir -p /var/log/apiserver
           sudo chown root:root /var/log/apiserver
           sudo chmod 700 /var/log/apiserver
           ```

        4. Save the file and exit the editor. The kubelet will automatically detect the change to `/etc/kubernetes/manifests/kube-apiserver.yaml` and restart the API server static pod; expect a brief control-plane disruption during the restart.

        5. After 1–2 minutes, verify that the API server process now includes the `--audit-log-path` argument on every control plane node:
           ```bash theme={null}
           /bin/ps -ef | grep kube-apiserver | grep -v grep
           ```
           Confirm the output shows a segment similar to:\
           `--audit-log-path=/var/log/apiserver/audit.log`
      </Accordion>

      <Accordion title="Using kubectl">
        `kubectl` cannot configure API server process flags or edit the static pod manifest on disk, so it cannot be used to set `--audit-log-path`. This must be fixed directly on each control plane node by editing `/etc/kubernetes/manifests/kube-apiserver.yaml`; see the Manual Steps section for the exact procedure.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Remediation: Ensure kube-apiserver has --audit-log-path set
        # Scope: every control plane node
        # Usage: run as root on each control plane node
        #

        set -euo pipefail

        APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
        AUDIT_LOG_DIR="/var/log/apiserver"
        AUDIT_LOG_FILE="${AUDIT_LOG_DIR}/audit.log"
        BACKUP_SUFFIX=".pre_audit_log_path.bak"

        echo "[*] Ensuring kube-apiserver --audit-log-path is configured"

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

        if [[ ! -f "${APISERVER_MANIFEST}" ]]; then
          echo "ERROR: Manifest not found at ${APISERVER_MANIFEST}" >&2
          exit 1
        fi

        # Create log directory and file with safe permissions (idempotent)
        mkdir -p "${AUDIT_LOG_DIR}"
        touch "${AUDIT_LOG_FILE}"
        chmod 700 "${AUDIT_LOG_DIR}"
        chmod 600 "${AUDIT_LOG_FILE}"
        chown root:root "${AUDIT_LOG_DIR}" "${AUDIT_LOG_FILE}" || true

        # Backup once (idempotent)
        if [[ ! -f "${APISERVER_MANIFEST}${BACKUP_SUFFIX}" ]]; then
          cp "${APISERVER_MANIFEST}" "${APISERVER_MANIFEST}${BACKUP_SUFFIX}"
          echo "[*] Backup created at ${APISERVER_MANIFEST}${BACKUP_SUFFIX}"
        fi

        # Ensure yamlfix utility function
        ensure_audit_log_arg() {
          local manifest="$1"
          local arg="--audit-log-path=${AUDIT_LOG_FILE}"

          # If exact arg already present, nothing to do
          if grep -qE -- "[[:space:]]- ${arg}([[:space:]]|\$)" "${manifest}"; then
            echo "[*] ${arg} already present in ${manifest}"
            return 0
          fi

          # If any --audit-log-path exists with different value, replace it
          if grep -qE -- "[[:space:]]- --audit-log-path=" "${manifest}"; then
            sed -i "s#\([[:space:]]-\s*--audit-log-path=\).*#\1${AUDIT_LOG_FILE}#g" "${manifest}"
            echo "[*] Updated existing --audit-log-path to ${AUDIT_LOG_FILE}"
            return 0
          fi

          # Insert new arg under the kube-apiserver command args
          # Handles common kubeadm-style manifest with 'command:' and '-' args
          if grep -qE '^\s*command:\s*$' "${manifest}"; then
            # Insert after the last existing dash-arg under command:
            # Fallback: append to the first args list under containers if pattern differs
            if perl -0pe '' 2>/dev/null >/dev/null; then
              # Try to insert using perl for minimal structure disturbance
              perl -0pi -e '
                my $arg = q('"${arg}"');
                s{
                  (command:\s*\n(?:\s*-\s*[^\n]+\n)*)(\s*-\s*--)
                }{
                  my ($head, $firstarg) = ($1, $2);
                  my $ins = $head =~ /\Q$arg\E/ ? $head : $head . "    - $arg\n";
                  $ins . $firstarg
                }ex if !/\Q'"${arg}"'\E/;
              ' "${manifest}" || true
            fi
          fi

          # If still no arg, append to any args list under containers
          if ! grep -qE -- "[[:space:]]- ${arg}([[:space:]]|\$)" "${manifest}"; then
            # Append to the first list item under 'containers:' if args/command not easily parsed
            # Simple, safe append near other flags
            # This appends under the first occurrence of '- kube-apiserver'
            if grep -qE '^\s*- name:\s*kube-apiserver\s*$' "${manifest}"; then
              awk -v arg="${arg}" '
                $0 ~ /^\s*- name:\s*kube-apiserver\s*$/ && !inserted {
                  print $0
                  inserted=1
                  next
                }
                inserted && $0 ~ /^\s*image:\s*/ && !printed_arg {
                  print "    command:"
                  print "      - kube-apiserver"
                  print "      - " arg
                  printed_arg=1
                  print $0
                  next
                }
                { print $0 }
              ' "${manifest}" >"${manifest}.tmp" && mv "${manifest}.tmp" "${manifest}"
            fi
          fi

          # Final check; if still missing, fail loudly
          if ! grep -qE -- "[[:space:]]- ${arg}([[:space:]]|\$)" "${manifest}"; then
            echo "ERROR: Failed to ensure ${arg} in ${manifest}. Please edit manually." >&2
            return 1
          fi

          echo "[*] Ensured ${arg} is present in ${manifest}"
        }

        ensure_audit_log_arg "${APISERVER_MANIFEST}"

        echo "[*] kube-apiserver manifest updated. Note: editing a static pod manifest in /etc/kubernetes/manifests will cause the kubelet to restart the kube-apiserver pod automatically."

        echo "[*] Waiting for kube-apiserver to restart with new arguments (up to 120s)..."
        sleep 10

        # Simple wait loop for process to contain the new flag
        end=$((SECONDS + 120))
        while (( SECONDS < end )); do
          if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q -- "--audit-log-path=${AUDIT_LOG_FILE}"; then
            break
          fi
          sleep 5
        done

        echo "[*] Verification:"
        /bin/ps -ef | grep kube-apiserver | grep -v grep | sed 's/^/    /'

        if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q -- "--audit-log-path=${AUDIT_LOG_FILE}"; then
          echo "[*] PASS: kube-apiserver is running with --audit-log-path=${AUDIT_LOG_FILE}"
          exit 0
        else
          echo "ERROR: kube-apiserver is not running with the expected --audit-log-path flag." >&2
          exit 1
        fi
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/admin/kube-apiserver/](https://kubernetes.io/docs/admin/kube-apiserver/)
