Ensure Audit Logs Are Collected And Managed
More Info:
Define an audit policy and forward audit logs to a centralized logging system such as CloudWatch or Elasticsearch. Without collection and management, audit records cannot be retained or reviewed.
Risk Level
High
Address
Security
Compliance Standards
- CIS EKS
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Verify EKS control plane audit logging is enabled and scoped correctly
- On any admin machine with AWS CLI access, list EKS clusters and describe the target cluster:
aws eks list-clustersaws eks describe-cluster --name <CLUSTER_NAME> --query "cluster.logging"
- Confirm
cluster.logging.clusterLogginghastypesincluding"api","audit"(or"all"types, depending on region support) with"enabled": trueand that logs are being sent to CloudWatch.
- On any admin machine with AWS CLI access, list EKS clusters and describe the target cluster:
-
Confirm audit policy configuration exists and matches organizational requirements
- On any machine with
kubectlaccess, check for an audit policy ConfigMap or file (common patterns):kubectl get configmap -n kube-system | grep -i auditkubectl get configmap cluster-audit-policy -n kube-system -o yaml - Compare the contents against the required policy (e.g., at minimum capturing
Metadatafor pods and other critical resources), and have security/operations sign off that scope, retention, and sensitivity are appropriate.
- On any machine with
-
Check that audit logs are being generated and delivered to CloudWatch
- On any admin machine with AWS CLI access, identify the CloudWatch log groups associated with the cluster:
aws logs describe-log-groups --log-group-name-prefix "/aws/eks/"
- Inspect a sample of recent audit log events:
aws logs describe-log-streams \--log-group-name "/aws/eks/<CLUSTER_NAME>/cluster" \--order-by LastEventTime --descending --limit 5aws logs get-log-events \--log-group-name "/aws/eks/<CLUSTER_NAME>/cluster" \--log-stream-name "<LOG_STREAM_NAME_FROM_ABOVE>" \--limit 20
- Confirm that Kubernetes API calls (create/update/delete, authN/Z events, etc.) are present and timestamps are recent.
- On any admin machine with AWS CLI access, identify the CloudWatch log groups associated with the cluster:
-
Validate forwarding to any additional centralized logging/SIEM system
- If you use a log forwarder (e.g., Fluent Bit/Fluentd/Vector/Custom):
kubectl get pods -n kube-system | egrep -i 'fluent|vector|log|audit'kubectl logs <POD_NAME> -n kube-system --tail=100
- Confirm configuration forwards CloudWatch (or node-level audit logs, if used) to the designated backend (Elasticsearch, OpenSearch, Splunk, etc.) and that events from this cluster are visible there (verify by querying on a known pod/namespace/user and recent timestamp).
- If you use a log forwarder (e.g., Fluent Bit/Fluentd/Vector/Custom):
-
Review retention, access control, and integrity protections for audit logs
- On any admin machine with AWS CLI access, verify CloudWatch retention and access:
aws logs describe-log-groups \--log-group-name-prefix "/aws/eks/<CLUSTER_NAME>/cluster" \--query "logGroups[].{name:logGroupName,retentionInDays:retentionInDays}"
- Confirm retention meets policy (e.g., 90/180/365 days), that IAM policies on the log group restrict write/delete/reader access appropriately, and that any downstream system (e.g., S3 archive, SIEM) also meets retention and integrity requirements.
- On any admin machine with AWS CLI access, verify CloudWatch retention and access:
-
If gaps are found, update configuration and re‑verify
- Enable/adjust EKS control plane logging (via console,
aws eks update-cluster-config, or IaC) to include the required log types and CloudWatch destination. - Update the audit policy ConfigMap or backing IaC to meet your logging scope, then redeploy.
- Re-run the commands from steps 1–3 to confirm that audit logs are enabled, correctly scoped, delivered to CloudWatch, and visible in your central logging solution.
- Enable/adjust EKS control plane logging (via console,
Using kubectl
kubectl cannot configure EKS control plane audit logging or host-level audit settings on control plane nodes; these are managed via the cloud provider console/CLI/IaC and node-level configuration. Refer to the Manual Steps section for how to review and configure audit policies and centralized log forwarding.
Automation
#!/usr/bin/env bash
# Purpose: Report EKS control plane audit logging configuration and
# basic in-cluster audit log forwarding setup.
# Runs on: any machine with kubectl access and AWS CLI configured.
set -euo pipefail
echo "=== 1. EKS CONTROL PLANE AUDIT LOGGING (CLOUDTRAIL / CLOUDWATCH) ==="
# List all clusters and show which have audit logging enabled
aws eks list-clusters --output text | awk '{print $2}' | while read -r CLUSTER; do
if [ -z "$CLUSTER" ]; then
continue
fi
echo "Cluster: $CLUSTER"
aws eks describe-cluster --name "$CLUSTER" \
--query 'cluster.logging.clusterLogging[?types!=`[]`]' \
--output table || echo " ERROR: unable to describe cluster $CLUSTER"
echo
done
cat <<'EOF'
Interpretation (control plane logging):
- Problem indicators:
- No entry where "types" contains "audit".
- "enabled" is false for the logging entry that includes "audit".
- Healthy indicators:
- At least one entry with "types" containing "audit" and "enabled" = true.
NOTE: Enabling EKS control plane audit logging is done via AWS console/CLI/IaC,
not via kubectl or node-level changes.
EOF
echo "=== 2. IN-CLUSTER AUDIT POLICY CONFIGMAP (kube-system) ==="
# Check for a commonly used audit policy ConfigMap name
CM_NAMES=("cluster-audit-policy" "audit-policy" "kube-audit-policy")
for CM in "${CM_NAMES[@]}"; do
echo "Checking for ConfigMap: $CM in kube-system..."
if kubectl get configmap "$CM" -n kube-system >/dev/null 2>&1; then
echo " FOUND: $CM"
echo " --- audit-policy.yaml from $CM ---"
kubectl get configmap "$CM" -n kube-system -o jsonpath='{.data.audit-policy\.yaml}' 2>/dev/null \
|| echo " WARN: ConfigMap exists but does not contain key 'audit-policy.yaml'"
echo
else
echo " MISSING: $CM"
fi
echo
done
cat <<'EOF'
Interpretation (policy ConfigMap):
- Problem indicators:
- No ConfigMap found that contains an audit policy (e.g. cluster-audit-policy).
- ConfigMap exists but has no 'audit-policy.yaml' key or is effectively empty.
- Healthy indicators:
- A ConfigMap exists with an 'audit-policy.yaml' key containing a non-trivial
policy (appropriate levels and resources as per your org standard).
EOF
echo "=== 3. IN-CLUSTER AUDIT LOG FORWARDER PODS (kube-system) ==="
# Look for pods that appear to forward audit logs (by name or label)
echo "Pods in kube-system potentially related to audit log forwarding:"
kubectl get pods -n kube-system -o wide | egrep -i 'audit|log|forward|fluent|filebeat|logstash' || \
echo " No obvious audit/log forwarder pods detected by name pattern."
echo
echo "Checking for example 'audit-logging' pod from benchmark remediation:"
kubectl get pod audit-logging -n kube-system -o yaml 2>/dev/null || \
echo " Pod 'audit-logging' not found in kube-system."
cat <<'EOF'
Interpretation (forwarder pods):
- Problem indicators:
- No pods in kube-system with names suggesting log forwarding
(e.g., fluentd, fluent-bit, filebeat, log-forwarder, audit-logging).
- The 'audit-logging' pod (if used) is missing or not Running/Ready.
- Healthy indicators:
- A dedicated log forwarder DaemonSet/Deployment is present and Running,
and is known (by your ops standards) to ship audit logs to a central
system (CloudWatch, Elasticsearch, etc.).
EOF
echo "=== 4. NODE-LEVEL INSPECTION (KUBELET / APISERVER AUDIT FLAGS) ==="
cat <<'EOF'
This part cannot be automated cluster-wide with kubectl alone because:
- EKS control plane is managed; you cannot inspect API server flags via nodes.
- Worker nodes usually do not run the control plane and have no direct access
to control plane audit logs.
Manual checks to perform on each control plane node (for non-managed clusters):
- Verify that the API server is started with:
--audit-policy-file=</path/to/audit-policy.yaml>
--audit-log-path=</path/to/audit.log>
--audit-log-maxage / --audit-log-maxbackup / --audit-log-maxsize set properly.
- Confirm audit log files exist and are being written.
- Confirm your node or sidecar agents (e.g., Fluent Bit, Filebeat) are
configured to ship these audit logs to your centralized logging system.
EOF