Skip to content

This tool is not affiliated with, endorsed by or sponsored by The Linux Foundation, the Cloud Native Computing Foundation (CNCF) or the Kubernetes project. Kubernetes and K8s are registered trademarks of The Linux Foundation. EKS, GKE, AKS and other names are trademarks of their respective owners.

API-server audit log analyzer

Was our Kubernetes cluster compromised?

Drop your API server audit logs — self-managed, EKS, GKE or AKS exports — and get a verdict, the findings, an attack timeline and what to do next. Analyzed in your browser with WebAssembly: nothing is uploaded.

  • MITRE ATT&CK for Containers
  • Self-managed, EKS, GKE, AKS
  • Runs locally in WebAssembly

Traced step by step in the sample incident

  1. 01Exposed token
  2. 02auth can-i recon
  3. 03Secrets listed
  4. 04Privileged DaemonSet
  5. 05chroot /host
  6. 06cluster-admin binding
  7. 07Miner CronJob

Drop Kubernetes audit logs here

API server audit.log (JSON lines), EKS CloudWatch exports, GKE Cloud Logging JSON, AKS diagnostic logs or Log Analytics JSON — plain, .gz, whole folders or ZIP archives. Falco JSON alerts can be added for correlation. Multi-GB exports are streamed.

The sample is a fictional incident: an exposed dashboard token turned into cluster-admin and a crypto-miner.

How to get these logs

Everything runs in this browser tab. Your logs are never uploaded.

How to get your audit logs

Pick where the cluster runs. The first tab is the fastest route: one command, one file to drop here.

  1. 1. Collectone command or export
  2. 2. Drop it herefile, folder or ZIP (.gz is fine)
  3. 3. Stays in your browsernothing is uploaded

Where does the cluster run?

Before you start: a shell on each control-plane node with sudo, and auditing enabled with --audit-log-path (kubeadm, RKE2, most on-prem installs). For k3s, see "Where it lives".

1. On the control-plane node: read the audit log path from the running API server (host process or static pod) and copy the log and its rotated files to ~/k8s-audit.

shell
PID=$(pgrep -o -f -- '--audit-log-path='); P=$(tr '\0' '\n' < /proc/$PID/cmdline | sed -n 's/^--audit-log-path=//p'); echo "$P"
mkdir -p ~/k8s-audit && sudo find "/proc/$PID/root$(dirname "$P")" -maxdepth 1 -type f -name "$(basename "${P%.*}")*" -exec cp -p {} ~/k8s-audit/ \;
sudo chown -R "$(id -u):$(id -g)" ~/k8s-audit && ls -lh ~/k8s-audit

2. From your workstation: fetch the folder, once per control-plane node, then drop the k8s-audit-* folders here.

shell
scp -r <user>@<control-plane-node>:k8s-audit ./k8s-audit-<node>

Gotchas

  • Audit logs only exist from the moment logging was enabled, and only for the retention window (rotated files, CloudWatch log group retention, 30 days for GKE Data Access by default). Collect now, before they age out.
  • Export JSON, never CSV: CSV files are rejected. Query results are size-capped, so split long ranges into several files and drop them together.
  • Self-managed: the audit log is readable by root only, and each API server logs only the requests it served. Use sudo and collect from every control-plane node. Timestamps are UTC.
Detailed EKS, GKE and AKS export guide

What the Kubernetes audit log tells you

Every request to the Kubernetes API server — from kubectl, controllers, kubelets or a stolen token — can be recorded as an audit event: who (user, groups, service account), from where (source IPs, user agent), what (verb, resource, namespace, name, subresource), whether it was allowed and why (the RBAC binding), and at higher levels the request body itself.

That makes it the primary evidence to answer "was our cluster compromised?": a stolen service-account token, a privileged pod mounting the node, a new cluster-admin binding or a crypto-miner CronJob all leave API calls behind, even when the workloads themselves are gone.

What this tool detects

  • Execution: pods/exec and pods/attach (especially by service accounts), port-forward, kubelet access through nodes/proxy.
  • Credential access: secrets listed across all namespaces, bursts of secret reads, service-account tokens minted with TokenRequest.
  • Privilege escalation and container escape: privileged containers, hostPID/hostNetwork/hostIPC, hostPath mounts of / or runtime sockets, DaemonSets in kube-system.
  • RBAC abuse: new bindings to cluster-admin, roles with escalate/bind/impersonate or wildcards, impersonation, access granted to anonymous users.
  • Recon: kubectl auth can-i bursts (SelfSubjectAccessReviews / RulesReviews), bursts of 403s, service-account tokens used with kubectl or curl or from public IPs, known attack-tool user agents.
  • Impact and persistence: crypto-miner images and commands, images from unusual registries, CronJobs, deleted Kubernetes events. Optional Falco alerts are correlated on the same timeline.
  • Detections are data: a reviewed JSON rule file (Sigma-like conditions) mapped to the MITRE ATT&CK Containers matrix, so they can be read, audited and reused.

How to export Kubernetes audit logs

Audit logging must be enabled before an incident to be useful. Export the whole period of interest (ideally a few days before the first suspicious event) as JSON; gzip and ZIP are fine.

Self-managed (kubeadm, k3s, RKE2, on-prem)

  1. The API server writes audit events when started with --audit-policy-file and --audit-log-path (for example /var/log/kubernetes/audit/audit.log).
  2. On each control-plane node, copy the current audit.log and its rotated files (audit-*.log, possibly .gz).
  3. If you ship audit events with the webhook backend (Fluent Bit, Vector, a SIEM), export them from there as JSON lines.
  4. Drop the files or the whole folder here.

Amazon EKS

  1. Control-plane logging must include the "audit" log type (EKS console → cluster → Observability → Control plane logging).
  2. Events are in CloudWatch Logs, log group /aws/eks/<cluster>/cluster, streams kube-apiserver-audit-*.
  3. Small ranges: aws logs filter-log-events --log-group-name /aws/eks/<cluster>/cluster --log-stream-name-prefix kube-apiserver-audit --start-time <ms> --end-time <ms> > eks-audit.json
  4. Large ranges: create an export task to S3 (aws logs create-export-task), download the .gz files and drop the folder. CloudWatch Logs Insights results exported as JSON also work.

Google GKE

  1. Admin Activity audit logs are always on; Data Access logs (get/list, secret reads) must be enabled for the Kubernetes Engine API in IAM → Audit Logs.
  2. Export with gcloud: gcloud logging read 'resource.type="k8s_cluster" AND logName:"cloudaudit.googleapis.com"' --project=<project> --freshness=30d --format=json > gke-audit.json
  3. Or download the results from Logs Explorer as JSON, or use a log sink to Cloud Storage / BigQuery for long periods (export BigQuery rows as JSON or newline-delimited JSON).
  4. Drop the JSON files here; entries from other services are ignored.

Azure AKS

  1. Create a diagnostic setting on the cluster with the kube-audit (or kube-audit-admin, which excludes get/list) category.
  2. Storage account destination: download the PT1H.json blobs under insights-logs-kube-audit/… and drop the folder.
  3. Log Analytics destination: query AKSAudit (or AzureDiagnostics | where Category startswith "kube-audit") and export the results as JSON, not CSV.
  4. Event Hubs exports ({"records": […]}) are supported too.

Make sure the evidence exists

  • Log at least Metadata for everything, and Request or RequestResponse for RBAC objects, pods, workloads, pods/exec and serviceaccounts/token: without request bodies, privileged pods and cluster-admin bindings cannot be recognised.
  • Never log secrets, configmaps or tokenreviews bodies (Metadata only): the log would become a credential store.
  • Keep audit logs outside the cluster, for at least 90 days: attackers with cluster-admin can tamper with anything inside it.

Limitations

  • The audit log only sees the API server: activity inside a container or on a node (a reverse shell, a miner started by hand) is invisible without runtime tools such as Falco.
  • What is detected depends on your audit policy: at Metadata level, request bodies (privileged flags, images, roleRef) are missing and several detections cannot fire.
  • Rules flag patterns, not intent: legitimate admins also run kubectl exec, and operators create DaemonSets. Every finding needs a human review.
  • Only JSON exports are read (CSV exports are not supported yet). Service-account names of your own platform components may need to be added to the rule allow-lists.

FAQ

Are my audit logs uploaded anywhere?

No. The analyzer is Rust compiled to WebAssembly and runs in a Web Worker in your browser; files are streamed from your disk in chunks. There is no upload endpoint.

How large an export can it handle?

Files are read and decompressed as a stream, so size is limited mostly by time: expect tens to a few hundred MB per minute depending on your machine. Small exports keep every event browsable; above 50,000 events only flagged events are kept, while counts, entities and findings still cover everything.

Which formats are supported?

Raw audit.k8s.io/v1 JSON lines, EKS CloudWatch exports (filter-log-events, Logs Insights JSON, S3 export files), GKE Cloud Logging JSON (gcloud logging read, Logs Explorer downloads, sinks), AKS diagnostic logs (storage account, Event Hubs, AKSAudit / AzureDiagnostics JSON), gzip and ZIP, plus Falco JSON alerts.

How do I detect kubectl exec in audit logs?

kubectl exec creates a request on the pods/exec subresource (verb create or get, objectRef.subresource exec); the command is in the requestURI as command= parameters. This tool lists every exec, attach and port-forward, and raises the severity when a service account does it.

Does "No sign of compromise" mean we are safe?

No. It means none of the rules matched in the logs you provided. Gaps in the audit policy, missing time ranges and in-container activity can all hide an intrusion. If you have other reasons to worry, get an expert review.

Can I see or reuse the detection rules?

Yes. They are a JSON file in the open repository (crates/k8s-audit-wasm/rules), with conditions, thresholds, MITRE ATT&CK technique ids and remediation steps, so they can be reviewed and reused in other tools.

The blind spots of Kubernetes audit logs: in-container activity, kubelet and etcd access, policy gaps, spoofable fields, and the evidence that fills them.
A fictional Kubernetes incident, step by step in the audit log: exposed dashboard token, can-i recon, secret theft, privileged DaemonSet, cluster-admin, XMRig.
Detect crypto-mining in Kubernetes clusters from audit logs: miner images and arguments, unusual registries, CronJob and DaemonSet persistence, and clean-up.

This tool is not affiliated with, endorsed by or sponsored by The Linux Foundation, the Cloud Native Computing Foundation (CNCF) or the Kubernetes project. Kubernetes and K8s are registered trademarks of The Linux Foundation. EKS, GKE, AKS and other names are trademarks of their respective owners.