Pods

OperationDescriptionSampleRule
get-podsReads one pod's full spec and status. Elastic's new-terms rule alerts when the combination of decision, username, and user agent has not appeared in the prior 10 days.YY
list-podsLists pods matching a query. Splunk's EKS pod-scan rule flags an unauthenticated (system:anonymous) list of /api/v1/pods as pre-attack reconnaissance.YY
watch-podsOpens a long-lived watch stream for pod changes cluster-wide. Elastic's new-terms user-agent rule alerts on a not-previously-seen identity doing this.YY
create-podsPod created (execution, privilege escalation via hostPID/hostNetwork/hostIPC, privileged container).YY
update-podsModifies an existing pod's spec (image, command, env). Elastic flags this verb from an anonymous/unauthenticated caller as unauthorized API server access.YY
patch-podsPartially modifies a pod's spec. Elastic flags this verb from an anonymous/unauthenticated caller as unauthorized API server access, the same signal as update.YY
delete-podsYN
deletecollection-podsYN
get-pods-attachYY
create-pods-attachContainer attach (kubectl attach; interactive session).YY
create-pods-bindingYN
get-pods-ephemeralcontainersEphemeral debug containers injected into a running pod.YN
update-pods-ephemeralcontainersAdds an ephemeral debug container to a running pod via update. Elastic flags this from a non-system identity: it can inject tooling or reach mounted secrets.YY
patch-pods-ephemeralcontainersSame ephemeral-container injection as update, via patch. Elastic's rule excludes node/kube-system service accounts and expects only approved admins here.YY
create-pods-evictionYN
get-pods-execSome exec clients issue GET instead of create on pods/exec. Elastic's exec-to-pod rule matches verb (get, create), so a create-only watch misses it.YY
create-pods-execRemote command execution in a container (kubectl exec issues create on pods/exec subresource).YY
get-pods-logYY
get-pods-portforwardYY
create-pods-portforwardPort forwarding from a pod (kubectl port-forward).YY
get-pods-proxyNN
create-pods-proxyNN
update-pods-proxyNN
patch-pods-proxyNN
delete-pods-proxyNN
get-pods-resizeYN
update-pods-resizeYN
patch-pods-resizeYN
get-pods-statusYN
update-pods-statusYN
patch-pods-statusYN
any-podsSynthetic aggregation for rules that filter the pods resource with no specific verb. Not a distinct audit record; hosts rule listings that key on objectRef.resource alone.NY

get pods

#
Resource
pods

Description

Reads one pod's full spec and status. Elastic's new-terms rule alerts when the combination of decision, username, and user agent has not appeared in the prior 10 days.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods?timeout=3s",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:49.498026Z",
  "stageTimestamp": "2026-07-02T04:48:49.499767Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches list-pods: list pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, get-pods-attach: get pods/attach, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.
  • GKE Multi-Resource Discovery source medium: Adversaries who land credentials in a GKE cluster—or abuse an over-privileged token, often map the environment before exfiltration or privilege escalation. A practical first pass is to learn where workloads run, how the cluster is partitioned, and what RBAC exists at namespace vs cluster scope. Rapid get/list traffic across many distinct API resource kinds that answer those questions (namespaces, workloads, roles, cluster-wide roles) is a common setup and orientation pattern for both interactive attackers and automated recon scripts. This rule highlights that cross-resource burst from a single client fingerprint within a one-minute bucket when both cluster-layout and RBAC resource kinds are touched, so analysts can separate routine automation from potential discovery ahead of follow-on actions.T1613↳ also matches list-pods: list pods
    Investigation guide

    Triage and analysis#

    Investigating GKE Multi-Resource Discovery#

    The rule groups GKE audit get/list events on namespaces, nodes, pods, configmaps, serviceaccounts, roles, rolebindings, clusterroles, and clusterrolebindings into one-minute windows per client.user.email, source.ip, and user_agent.original. It alerts when five or more distinct resource kinds appear and the burst includes both cluster-layout kinds (namespaces, pods, or nodes) and RBAC kinds. Allowed and denied authorizations are both included: failures still signal probing.

    Possible investigation steps#

    • Review Esql.enumerated_resources, Esql.enumerated_namespaces, and Esql.enumerated_resource_names for ordering and targeted APIs.
    • Confirm whether source.ip and user_agent.original match expected admin or automation clients.
    • Correlate with follow-on secret reads, RoleBinding changes, pod exec, or unusual user agents from the same actor.

    False positive analysis#

    • Documented platform sync jobs that read layout and RBAC together; exclude known service accounts after validation.
    • Upgrade or install windows that briefly query many resource kinds; correlate with change records.

    Response and remediation#

    • If malicious, revoke or rotate the implicated credentials, tighten RBAC, and inspect for data access or persistence established after the burst.

References #

list pods

#
Resource
pods

Description

Lists pods matching a query. Splunk's EKS pod-scan rule flags an unauthenticated (system:anonymous) list of /api/v1/pods as pre-attack reconnaissance.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods?limit=500",
  "verb": "list",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:49.256022Z",
  "stageTimestamp": "2026-07-02T04:48:49.257796Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
objectRef.resource (splunk rule field)eqpods1 rulesplunk
user.username (splunk rule field)eqsystem:anonymous1 rulesplunk
verb (splunk rule field)eqlist1 rulesplunk

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, get-pods-attach: get pods/attach, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.
  • GKE Multi-Resource Discovery source medium: Adversaries who land credentials in a GKE cluster—or abuse an over-privileged token, often map the environment before exfiltration or privilege escalation. A practical first pass is to learn where workloads run, how the cluster is partitioned, and what RBAC exists at namespace vs cluster scope. Rapid get/list traffic across many distinct API resource kinds that answer those questions (namespaces, workloads, roles, cluster-wide roles) is a common setup and orientation pattern for both interactive attackers and automated recon scripts. This rule highlights that cross-resource burst from a single client fingerprint within a one-minute bucket when both cluster-layout and RBAC resource kinds are touched, so analysts can separate routine automation from potential discovery ahead of follow-on actions.T1613↳ also matches get-pods: get pods
    Investigation guide

    Triage and analysis#

    Investigating GKE Multi-Resource Discovery#

    The rule groups GKE audit get/list events on namespaces, nodes, pods, configmaps, serviceaccounts, roles, rolebindings, clusterroles, and clusterrolebindings into one-minute windows per client.user.email, source.ip, and user_agent.original. It alerts when five or more distinct resource kinds appear and the burst includes both cluster-layout kinds (namespaces, pods, or nodes) and RBAC kinds. Allowed and denied authorizations are both included: failures still signal probing.

    Possible investigation steps#

    • Review Esql.enumerated_resources, Esql.enumerated_namespaces, and Esql.enumerated_resource_names for ordering and targeted APIs.
    • Confirm whether source.ip and user_agent.original match expected admin or automation clients.
    • Correlate with follow-on secret reads, RoleBinding changes, pod exec, or unusual user agents from the same actor.

    False positive analysis#

    • Documented platform sync jobs that read layout and RBAC together; exclude known service accounts after validation.
    • Upgrade or install windows that briefly query many resource kinds; correlate with change records.

    Response and remediation#

    • If malicious, revoke or rotate the implicated credentials, tighten RBAC, and inspect for data access or persistence established after the burst.

Splunk #

  • Amazon EKS Kubernetes Pod scan detection source: The following analytic detects unauthenticated requests made against the Kubernetes Pods API, indicating potential unauthorized access attempts. It leverages the aws_cloudwatchlogs_eks data source, filtering for events where…T1526

References #

watch pods

#
Resource
pods

Description

Opens a long-lived watch stream for pod changes cluster-wide. Elastic's new-terms user-agent rule alerts on a not-previously-seen identity doing this.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods?allowWatchBookmarks=true&fieldSelector=metadata.name%3Ddw-harn-pod-evict&resourceVersionMatch=NotOlderThan&sendInitialEvents=true&timeoutSeconds=381&watch=true",
  "verb": "watch",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pod-evict",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:58.128429Z",
  "stageTimestamp": "2026-07-02T04:48:58.664505Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, get-pods-attach: get pods/attach, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.

References #

create pods

#
Resource
pods

Description

Pod created (execution, privilege escalation via hostPID/hostNetwork/hostIPC, privileged container).

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "a9157591-37ac-42da-8de5-713be7a08bbd",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/default/pods?fieldManager=kubectl-client-side-apply&fieldValidation=Strict",
  "verb": "create",
  "user": {
    "username": "kubernetes-admin",
    "uid": "aws-iam-authenticator",
    "groups": [
      "system:masters",
      "system:authenticated"
    ]
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.27.2 (darwin/arm64) kubernetes/7f6f68f",
  "objectRef": {
    "resource": "pods",
    "namespace": "default",
    "name": "privileged-the-pod",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 201
  },
  "requestObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "privileged-the-pod",
      "namespace": "default",
      "creationTimestamp": null,
      "annotations": {
        "kubectl.kubernetes.io/last-applied-configuration": {
          "apiVersion": "v1",
          "kind": "Pod",
          "metadata": {
            "annotations": {},
            "name": "privileged-the-pod",
            "namespace": "default"
          },
          "spec": {
            "containers": [
              {
                "image": "nginx:latest",
                "name": "privileged-the-pod",
                "ports": [
                  {
                    "containerPort": 80
                  }
                ],
                "securityContext": {
                  "privileged": true
                }
              }
            ],
            "hostNetwork": true,
            "hostPID": true
          }
        }
      }
    },
    "spec": {
      "containers": [
        {
          "name": "privileged-the-pod",
          "image": "nginx:latest",
          "ports": [
            {
              "hostPort": 80,
              "containerPort": 80,
              "protocol": "TCP"
            }
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "Always",
          "securityContext": {
            "privileged": true
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 30,
      "dnsPolicy": "ClusterFirst",
      "hostNetwork": true,
      "hostPID": true,
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "enableServiceLinks": true
    },
    "status": {}
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "privileged-the-pod",
      "namespace": "default",
      "uid": "53754112-d064-43bc-9d31-532ebca3afc3",
      "resourceVersion": "2614847",
      "creationTimestamp": "2023-12-13T15:48:34Z",
      "annotations": {
        "kubectl.kubernetes.io/last-applied-configuration": {
          "apiVersion": "v1",
          "kind": "Pod",
          "metadata": {
            "annotations": {},
            "name": "privileged-the-pod",
            "namespace": "default"
          },
          "spec": {
            "containers": [
              {
                "image": "nginx:latest",
                "name": "privileged-the-pod",
                "ports": [
                  {
                    "containerPort": 80
                  }
                ],
                "securityContext": {
                  "privileged": true
                }
              }
            ],
            "hostNetwork": true,
            "hostPID": true
          }
        }
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-42hr5",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "privileged-the-pod",
          "image": "nginx:latest",
          "ports": [
            {
              "hostPort": 80,
              "containerPort": 80,
              "protocol": "TCP"
            }
          ],
          "resources": {},
          "volumeMounts": [
            {
              "name": "kube-api-access-42hr5",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "Always",
          "securityContext": {
            "privileged": true
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 30,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "hostNetwork": true,
      "hostPID": true,
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "phase": "Pending",
      "qosClass": "BestEffort"
    }
  },
  "requestReceivedTimestamp": "2023-12-13T15:48:34.794464Z",
  "stageTimestamp": "2023-12-13T15:48:34.995656Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "",
    "mutation.webhook.admission.k8s.io/round_0_index_0": {
      "configuration": "pod-identity-webhook",
      "webhook": "iam-for-pods.amazonaws.com",
      "mutated": false
    },
    "mutation.webhook.admission.k8s.io/round_0_index_1": {
      "configuration": "vpc-resource-mutating-webhook",
      "webhook": "mpod.vpc.k8s.aws",
      "mutated": false
    },
    "pod-security.kubernetes.io/enforce-policy": "privileged:latest"
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
verbeqcreate15 rulesfalco, panther, sigma, splunk
objectRef.resourceeqpods13 rulesfalco, sigma, splunk
kubernetes.audit.objectRef.resource (elastic rule field)eqpods10 ruleselastic
kubernetes.audit.annotations.authorization_k8s_io/decision (elastic rule field)eqallow8 ruleselastic
objectRef.subresource (falco rule field)is_null7 rulesfalco
stage (falco rule field)eqresponsecomplete7 rulesfalco
username (panther rule field)containsserviceaccount7 rulespanther
kubernetes.audit.verb (elastic rule field)eqcreate4 ruleselastic
kubernetes.audit.verb (elastic rule field)increate6 ruleselastic
kubernetes.audit.verb (elastic rule field)inpatch6 ruleselastic
kubernetes.audit.verb (elastic rule field)inupdate6 ruleselastic
objectRef:resource (panther rule field)eqpods6 rulespanther
EventType (elastic rule field)inio.k8s.core.v1.pods.create5 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.patch5 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.update5 ruleselastic

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Sigma #

  • Container With A hostPath Mount Created source low: Detects creation of a container with a hostPath mount. A hostPath volume mounts a directory or a file from the node to the container. Attackers who have permissions to create a new pod in the cluster may create one with a writable hostPath volume and chroot to escape to the underlying node.T1611
  • Creation Of Pod In System Namespace source medium: Detects deployments of pods within the kube-system namespace, which could be intended to imitate system pods. System pods, created by controllers such as Deployments or DaemonSets have random suffixes in their names. Attackers can use this fact and name their backdoor pods as if they were created by these controllers to avoid detection. Deployment of such a backdoor container e.g. named kube-proxy-bv61v, could be attempted in the kube-system namespace alongside the other administrative containers.T1036, T1036.005
  • Privileged Container Deployed source low: Detects the creation of a "privileged" container, an action which could be indicative of a threat actor mounting a container breakout attacks. A privileged container is a container that can access the host with all of the root capabilities of the host machine. This allows it to view, interact and modify processes, network operations, IPC calls, the file system, mount points, SELinux configurations etc. as the root user on the host. Various versions of "privileged" containers can be specified, e.g. by setting the securityContext.privileged flag in the resource specification, setting non-standard Linux capabilities, or configuring the hostNetwork/hostPID fieldsT1611

Elastic #

  • GKE Anonymous Pod Create/Update/Patch source high: Detects create, update, or patch of pods by an unauthenticated anonymous GKE identity. Anonymous pod mutation is a critical misconfiguration signal and a common path for unauthenticated attackers to deploy workloads or maintain access. Includes "system:anonymous" / "system:unauthenticated" and GKE audit rows with a missing principal (seen on unauthenticated Unauthorized/forbidden pod writes).T1610↳ also matches update-pods: update pods, patch-pods: patch pods
    Investigation guide

    Triage and analysis#

    Investigating GKE Anonymous Pod Create/Update/Patch#

    Anonymous identities creating or mutating pods indicates the API server accepts unauthenticated workload changes. Failed unauthenticated creates may appear with an empty client.user.email and Unauthorized / forbidden status.

    Investigation steps#

    • Review client.user.email, event.action, event.outcome, orchestrator.resource.name, orchestrator.namespace, and source.ip.
    • Inspect the pod image, command, and volume mounts for credential theft or reverse shells.
    • Check whether anonymous authentication is enabled and remove RBAC grants to system:anonymous.

    False positives#

    • Essentially none in production; treat as high-priority misconfiguration until proven otherwise.
  • GKE Container Created with Excessive Linux Capabilities source medium: Detects GKE pod creation with dangerous Linux capabilities that are commonly abused in container escape techniques. Standalone pods are included; controller-owned ReplicaSet, DaemonSet, and StatefulSet workloads are excluded.T1610, T1611
    Investigation guide

    Triage and analysis#

    Investigating GKE Container Created with Excessive Linux Capabilities#

    Capabilities such as SYS_ADMIN, NET_ADMIN, and BPF can enable host escape. Review gcp.audit.request.spec.containers and the creating identity.

    Investigation steps#

    • Confirm which capability was added and whether the image requires it.
    • Review user.email, namespace, and follow-on API activity from the same actor.

    False positives#

    • Known DaemonSet or operator images may need capabilities; exclude after validation.

    Setup#

    The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule.

  • GKE Pod Created With HostIPC source medium: Detects GKE pod create, update, or patch events that enable host IPC namespace sharing. This exposes host inter-process communication mechanisms and can support privilege escalation. Controller-owned workloads are excluded.T1610, T1611↳ also matches update-pods: update pods, patch-pods: patch pods
    Investigation guide

    Triage and analysis#

    Investigating GKE Pod Created With HostIPC#

    Host IPC lets a pod interact with host IPC facilities. Review the pod spec, actor, and whether the change was expected.

    Investigation steps#

    • Confirm gcp.audit.request.spec.hostIPC and targeted namespace or pod.
    • Review user.email and correlate with other risky pod modifications.

    False positives#

    • Break-glass debugging on nodes; allowlist known admin identities.

    Setup#

    The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule.

Splunk #

Panther #

Falco #

References #

update pods

#
Resource
pods

Description

Modifies an existing pod's spec (image, command, env). Elastic flags this verb from an anonymous/unauthenticated caller as unauthorized API server access.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods?fieldManager=kubectl-replace&fieldValidation=Strict",
  "verb": "update",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "uid": "00000000-0000-0000-0000-000000000000",
    "apiVersion": "v1",
    "resourceVersion": "1328"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1328",
      "generation": 1,
      "creationTimestamp": "2026-07-02T22:48:39Z",
      "labels": {
        "app": "dw-harn",
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-6v2nh",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 1,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.11",
      "podIPs": [
        {
          "ip": "10.244.0.11"
        }
      ],
      "startTime": "2026-07-02T22:48:39Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:48:40Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://22a94e64e6b0f15416b36663b28abc4da5a9e92f9cc537badb41f3458a4ef2ef",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1328",
      "generation": 1,
      "creationTimestamp": "2026-07-02T22:48:39Z",
      "labels": {
        "app": "dw-harn",
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-6v2nh",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 1,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.11",
      "podIPs": [
        {
          "ip": "10.244.0.11"
        }
      ],
      "startTime": "2026-07-02T22:48:39Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:48:40Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://22a94e64e6b0f15416b36663b28abc4da5a9e92f9cc537badb41f3458a4ef2ef",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "requestReceivedTimestamp": "2026-07-02T22:48:44.249655Z",
  "stageTimestamp": "2026-07-02T22:48:44.255109Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\"",
    "pod-security.kubernetes.io/enforce-policy": "privileged:latest"
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
kubernetes.audit.objectRef.resource (elastic rule field)eqpods6 ruleselastic
kubernetes.audit.verb (elastic rule field)increate6 ruleselastic
kubernetes.audit.verb (elastic rule field)inpatch6 ruleselastic
kubernetes.audit.verb (elastic rule field)inupdate6 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.create5 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.patch5 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.update5 ruleselastic
kubernetes.audit.annotations.authorization_k8s_io/decision (elastic rule field)eqallow4 ruleselastic
objectRef:resource (panther rule field)eqpods4 rulespanther
verb (splunk rule field)equpdate2 rulessplunk
verb (panther rule field)increate4 rulespanther
verb (panther rule field)inupdate4 rulespanther
verb (panther rule field)inpatch3 rulespanther
objectRef.resource (splunk rule field)eqpods2 rulessplunk
client.user.email (elastic rule field)eqsystem:anonymous1 ruleelastic

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, watch-pods: watch pods, create-pods: create pods, patch-pods: patch pods, get-pods-attach: get pods/attach, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.
  • GKE Anonymous Pod Create/Update/Patch source high: Detects create, update, or patch of pods by an unauthenticated anonymous GKE identity. Anonymous pod mutation is a critical misconfiguration signal and a common path for unauthenticated attackers to deploy workloads or maintain access. Includes "system:anonymous" / "system:unauthenticated" and GKE audit rows with a missing principal (seen on unauthenticated Unauthorized/forbidden pod writes).T1610↳ also matches create-pods: create pods, patch-pods: patch pods
    Investigation guide

    Triage and analysis#

    Investigating GKE Anonymous Pod Create/Update/Patch#

    Anonymous identities creating or mutating pods indicates the API server accepts unauthenticated workload changes. Failed unauthenticated creates may appear with an empty client.user.email and Unauthorized / forbidden status.

    Investigation steps#

    • Review client.user.email, event.action, event.outcome, orchestrator.resource.name, orchestrator.namespace, and source.ip.
    • Inspect the pod image, command, and volume mounts for credential theft or reverse shells.
    • Check whether anonymous authentication is enabled and remove RBAC grants to system:anonymous.

    False positives#

    • Essentially none in production; treat as high-priority misconfiguration until proven otherwise.
  • GKE Pod Created With HostIPC source medium: Detects GKE pod create, update, or patch events that enable host IPC namespace sharing. This exposes host inter-process communication mechanisms and can support privilege escalation. Controller-owned workloads are excluded.T1610, T1611↳ also matches create-pods: create pods, patch-pods: patch pods
    Investigation guide

    Triage and analysis#

    Investigating GKE Pod Created With HostIPC#

    Host IPC lets a pod interact with host IPC facilities. Review the pod spec, actor, and whether the change was expected.

    Investigation steps#

    • Confirm gcp.audit.request.spec.hostIPC and targeted namespace or pod.
    • Review user.email and correlate with other risky pod modifications.

    False positives#

    • Break-glass debugging on nodes; allowlist known admin identities.

    Setup#

    The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule.

Splunk #

Panther #

References #

patch pods

#
Resource
pods

Description

Partially modifies a pod's spec. Elastic flags this verb from an anonymous/unauthenticated caller as unauthorized API server access, the same signal as update.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods?fieldManager=kubectl-patch",
  "verb": "patch",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "metadata": {
      "labels": {
        "dw-harn-patched": "1"
      }
    }
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1327",
      "generation": 1,
      "creationTimestamp": "2026-07-02T22:48:39Z",
      "labels": {
        "app": "dw-harn",
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-6v2nh",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 1,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.11",
      "podIPs": [
        {
          "ip": "10.244.0.11"
        }
      ],
      "startTime": "2026-07-02T22:48:39Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:48:40Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://22a94e64e6b0f15416b36663b28abc4da5a9e92f9cc537badb41f3458a4ef2ef",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "cpu": "10m",
          "memory": "16Mi"
        }
      }
    }
  },
  "requestReceivedTimestamp": "2026-07-02T22:48:43.987530Z",
  "stageTimestamp": "2026-07-02T22:48:44.014996Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\"",
    "pod-security.kubernetes.io/enforce-policy": "privileged:latest"
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
kubernetes.audit.objectRef.resource (elastic rule field)eqpods6 ruleselastic
kubernetes.audit.verb (elastic rule field)increate6 ruleselastic
kubernetes.audit.verb (elastic rule field)inpatch6 ruleselastic
kubernetes.audit.verb (elastic rule field)inupdate6 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.create5 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.patch5 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.update5 ruleselastic
kubernetes.audit.annotations.authorization_k8s_io/decision (elastic rule field)eqallow4 ruleselastic
objectRef:resource (panther rule field)eqpods3 rulespanther
verb (panther rule field)increate3 rulespanther
verb (panther rule field)inpatch3 rulespanther
verb (panther rule field)inupdate3 rulespanther
client.user.email (elastic rule field)eqsystem:anonymous1 ruleelastic
client.user.email (elastic rule field)eqsystem:unauthenticated1 ruleelastic
client.user.email (elastic rule field)is_null1 ruleelastic

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, get-pods-attach: get pods/attach, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.
  • GKE Anonymous Pod Create/Update/Patch source high: Detects create, update, or patch of pods by an unauthenticated anonymous GKE identity. Anonymous pod mutation is a critical misconfiguration signal and a common path for unauthenticated attackers to deploy workloads or maintain access. Includes "system:anonymous" / "system:unauthenticated" and GKE audit rows with a missing principal (seen on unauthenticated Unauthorized/forbidden pod writes).T1610↳ also matches create-pods: create pods, update-pods: update pods
    Investigation guide

    Triage and analysis#

    Investigating GKE Anonymous Pod Create/Update/Patch#

    Anonymous identities creating or mutating pods indicates the API server accepts unauthenticated workload changes. Failed unauthenticated creates may appear with an empty client.user.email and Unauthorized / forbidden status.

    Investigation steps#

    • Review client.user.email, event.action, event.outcome, orchestrator.resource.name, orchestrator.namespace, and source.ip.
    • Inspect the pod image, command, and volume mounts for credential theft or reverse shells.
    • Check whether anonymous authentication is enabled and remove RBAC grants to system:anonymous.

    False positives#

    • Essentially none in production; treat as high-priority misconfiguration until proven otherwise.
  • GKE Pod Created With HostIPC source medium: Detects GKE pod create, update, or patch events that enable host IPC namespace sharing. This exposes host inter-process communication mechanisms and can support privilege escalation. Controller-owned workloads are excluded.T1610, T1611↳ also matches create-pods: create pods, update-pods: update pods
    Investigation guide

    Triage and analysis#

    Investigating GKE Pod Created With HostIPC#

    Host IPC lets a pod interact with host IPC facilities. Review the pod spec, actor, and whether the change was expected.

    Investigation steps#

    • Confirm gcp.audit.request.spec.hostIPC and targeted namespace or pod.
    • Review user.email and correlate with other risky pod modifications.

    False positives#

    • Break-glass debugging on nodes; allowlist known admin identities.

    Setup#

    The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule.

Panther #

References #

delete pods

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods",
  "verb": "delete",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "kind": "DeleteOptions",
    "apiVersion": "meta.k8s.io/__internal",
    "gracePeriodSeconds": 0,
    "propagationPolicy": "Background"
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1808",
      "generation": 3,
      "creationTimestamp": "2026-07-02T04:48:48Z",
      "deletionTimestamp": "2026-07-02T04:48:58Z",
      "deletionGracePeriodSeconds": 0,
      "labels": {
        "app": "dw-harn"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-jx7nf",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-jx7nf",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "ephemeralContainers": [
        {
          "name": "debugger-j4cpn",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "true"
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent",
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 2,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:48Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:48Z"
        }
      ],
      "message": "dw-harn",
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.10",
      "podIPs": [
        {
          "ip": "10.244.0.10"
        }
      ],
      "startTime": "2026-07-02T04:48:48Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T04:48:49Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://cbb5514b60b38dcd34d9a3cd6d26f1f35a35af4f9a0abee6f98a0f1b682342c6",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-jx7nf",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "ephemeralContainerStatuses": [
        {
          "name": "debugger-j4cpn",
          "state": {
            "terminated": {
              "exitCode": 0,
              "reason": "Completed",
              "startedAt": "2026-07-02T04:48:57Z",
              "finishedAt": "2026-07-02T04:48:57Z",
              "containerID": "containerd://f7713901b9339c12233bfcdc7a1624b9d31c1838905a863c3d104c6acaa81553"
            }
          },
          "lastState": {},
          "ready": false,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://f7713901b9339c12233bfcdc7a1624b9d31c1838905a863c3d104c6acaa81553",
          "resources": {},
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:58.857582Z",
  "stageTimestamp": "2026-07-02T04:48:58.866520Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

deletecollection pods

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods",
  "verb": "deletecollection",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=3ffde68ef687218e01296d94b0aa59c81cc98de2bd73ab70e21510c8cd4b9cec"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "responseObject": {
    "kind": "PodList",
    "apiVersion": "v1",
    "metadata": {
      "resourceVersion": "1414"
    },
    "items": [
      {
        "metadata": {
          "name": "dw-harn-jobs-hjgj4",
          "generateName": "dw-harn-jobs-",
          "namespace": "dw-harn",
          "uid": "00000000-0000-0000-0000-000000000000",
          "resourceVersion": "868",
          "generation": 1,
          "creationTimestamp": "2026-07-02T23:13:04Z",
          "labels": {
            "batch.kubernetes.io/controller-uid": "00000000-0000-0000-0000-000000000000",
            "batch.kubernetes.io/job-name": "dw-harn-jobs",
            "controller-uid": "00000000-0000-0000-0000-000000000000",
            "job-name": "dw-harn-jobs"
          }
        },
        "spec": {
          "volumes": [
            {
              "name": "kube-api-access-v4bbn",
              "projected": {
                "sources": [
                  {
                    "serviceAccountToken": {
                      "expirationSeconds": 3607,
                      "path": "token"
                    }
                  },
                  {
                    "configMap": {
                      "name": "kube-root-ca.crt",
                      "items": [
                        {
                          "key": "ca.crt",
                          "path": "ca.crt"
                        }
                      ]
                    }
                  },
                  {
                    "downwardAPI": {
                      "items": [
                        {
                          "path": "namespace",
                          "fieldRef": {
                            "apiVersion": "v1",
                            "fieldPath": "metadata.namespace"
                          }
                        }
                      ]
                    }
                  }
                ],
                "defaultMode": 420
              }
            }
          ],
          "containers": [
            {
              "name": "c",
              "image": "docker.io/library/busybox:1.36",
              "command": [
                "true"
              ],
              "resources": {},
              "volumeMounts": [
                {
                  "name": "kube-api-access-v4bbn",
                  "readOnly": true,
                  "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
                }
              ],
              "terminationMessagePath": "/dev/termination-log",
              "terminationMessagePolicy": "File",
              "imagePullPolicy": "IfNotPresent"
            }
          ],
          "restartPolicy": "Never",
          "terminationGracePeriodSeconds": 30,
          "dnsPolicy": "ClusterFirst",
          "serviceAccountName": "default",
          "serviceAccount": "default",
          "nodeName": "node-control-plane",
          "securityContext": {},
          "schedulerName": "default-scheduler",
          "tolerations": [
            {
              "key": "node.kubernetes.io/not-ready",
              "operator": "Exists",
              "effect": "NoExecute",
              "tolerationSeconds": 300
            },
            {
              "key": "node.kubernetes.io/unreachable",
              "operator": "Exists",
              "effect": "NoExecute",
              "tolerationSeconds": 300
            }
          ],
          "priority": 0,
          "enableServiceLinks": true,
          "preemptionPolicy": "PreemptLowerPriority"
        },
        "status": {
          "observedGeneration": 1,
          "phase": "Succeeded",
          "conditions": [
            {
              "type": "PodReadyToStartContainers",
              "observedGeneration": 1,
              "status": "False",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:06Z"
            },
            {
              "type": "Initialized",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:04Z",
              "reason": "PodCompleted"
            },
            {
              "type": "Ready",
              "observedGeneration": 1,
              "status": "False",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:05Z",
              "reason": "PodCompleted"
            },
            {
              "type": "ContainersReady",
              "observedGeneration": 1,
              "status": "False",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:05Z",
              "reason": "PodCompleted"
            },
            {
              "type": "PodScheduled",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:04Z"
            }
          ],
          "hostIP": "172.19.0.2",
          "hostIPs": [
            {
              "ip": "172.19.0.2"
            }
          ],
          "podIP": "10.244.0.9",
          "podIPs": [
            {
              "ip": "10.244.0.9"
            }
          ],
          "startTime": "2026-07-02T23:13:04Z",
          "containerStatuses": [
            {
              "name": "c",
              "state": {
                "terminated": {
                  "exitCode": 0,
                  "reason": "Completed",
                  "startedAt": "2026-07-02T23:13:05Z",
                  "finishedAt": "2026-07-02T23:13:05Z",
                  "containerID": "containerd://cc0555bd5981d9fa11273115e18994573fa5de6c180a942ffda517e448b566ac"
                }
              },
              "lastState": {},
              "ready": false,
              "restartCount": 0,
              "image": "docker.io/library/busybox:1.36",
              "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
              "containerID": "containerd://cc0555bd5981d9fa11273115e18994573fa5de6c180a942ffda517e448b566ac",
              "started": false,
              "resources": {},
              "volumeMounts": [
                {
                  "name": "kube-api-access-v4bbn",
                  "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
                  "readOnly": true,
                  "recursiveReadOnly": "Disabled"
                }
              ],
              "user": {
                "linux": {
                  "uid": 0,
                  "gid": 0,
                  "supplementalGroups": [
                    0,
                    10
                  ]
                }
              }
            }
          ],
          "qosClass": "BestEffort",
          "resources": {}
        }
      },
      {
        "metadata": {
          "name": "dw-harn-pods",
          "namespace": "dw-harn",
          "uid": "00000000-0000-0000-0000-000000000000",
          "resourceVersion": "1403",
          "generation": 2,
          "creationTimestamp": "2026-07-02T23:15:29Z",
          "labels": {
            "app": "dw-harn",
            "dw-harn-patched": "1"
          }
        },
        "spec": {
          "volumes": [
            {
              "name": "kube-api-access-wffxk",
              "projected": {
                "sources": [
                  {
                    "serviceAccountToken": {
                      "expirationSeconds": 3607,
                      "path": "token"
                    }
                  },
                  {
                    "configMap": {
                      "name": "kube-root-ca.crt",
                      "items": [
                        {
                          "key": "ca.crt",
                          "path": "ca.crt"
                        }
                      ]
                    }
                  },
                  {
                    "downwardAPI": {
                      "items": [
                        {
                          "path": "namespace",
                          "fieldRef": {
                            "apiVersion": "v1",
                            "fieldPath": "metadata.namespace"
                          }
                        }
                      ]
                    }
                  }
                ],
                "defaultMode": 420
              }
            }
          ],
          "containers": [
            {
              "name": "c",
              "image": "docker.io/library/busybox:1.36",
              "command": [
                "sh",
                "-c",
                "sleep 3600"
              ],
              "resources": {
                "requests": {
                  "cpu": "10m",
                  "memory": "16Mi"
                }
              },
              "volumeMounts": [
                {
                  "name": "kube-api-access-wffxk",
                  "readOnly": true,
                  "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
                }
              ],
              "terminationMessagePath": "/dev/termination-log",
              "terminationMessagePolicy": "File",
              "imagePullPolicy": "IfNotPresent"
            }
          ],
          "ephemeralContainers": [
            {
              "name": "debugger-sb6mg",
              "image": "docker.io/library/busybox:1.36",
              "command": [
                "true"
              ],
              "resources": {},
              "terminationMessagePath": "/dev/termination-log",
              "terminationMessagePolicy": "File",
              "imagePullPolicy": "IfNotPresent",
              "securityContext": {
                "capabilities": {
                  "add": [
                    "SYS_PTRACE"
                  ]
                }
              }
            }
          ],
          "restartPolicy": "Always",
          "terminationGracePeriodSeconds": 0,
          "dnsPolicy": "ClusterFirst",
          "serviceAccountName": "default",
          "serviceAccount": "default",
          "nodeName": "node-control-plane",
          "securityContext": {},
          "schedulerName": "default-scheduler",
          "tolerations": [
            {
              "key": "node.kubernetes.io/not-ready",
              "operator": "Exists",
              "effect": "NoExecute",
              "tolerationSeconds": 300
            },
            {
              "key": "node.kubernetes.io/unreachable",
              "operator": "Exists",
              "effect": "NoExecute",
              "tolerationSeconds": 300
            }
          ],
          "priority": 0,
          "enableServiceLinks": true,
          "preemptionPolicy": "PreemptLowerPriority"
        },
        "status": {
          "observedGeneration": 2,
          "phase": "Running",
          "conditions": [
            {
              "type": "PodReadyToStartContainers",
              "observedGeneration": 2,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:15:29Z"
            },
            {
              "type": "Initialized",
              "observedGeneration": 2,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:15:29Z"
            },
            {
              "type": "Ready",
              "observedGeneration": 2,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:15:29Z"
            },
            {
              "type": "ContainersReady",
              "observedGeneration": 2,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:15:29Z"
            },
            {
              "type": "PodScheduled",
              "observedGeneration": 2,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:15:29Z"
            }
          ],
          "message": "dw-harn",
          "hostIP": "172.19.0.2",
          "hostIPs": [
            {
              "ip": "172.19.0.2"
            }
          ],
          "podIP": "10.244.0.12",
          "podIPs": [
            {
              "ip": "10.244.0.12"
            }
          ],
          "startTime": "2026-07-02T23:15:29Z",
          "containerStatuses": [
            {
              "name": "c",
              "state": {
                "running": {
                  "startedAt": "2026-07-02T23:15:29Z"
                }
              },
              "lastState": {},
              "ready": true,
              "restartCount": 0,
              "image": "docker.io/library/busybox:1.36",
              "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
              "containerID": "containerd://6c712e71c8533320855d14fcb4a35b0607ede3432ff4e0648f942f963a5e9295",
              "started": true,
              "allocatedResources": {
                "cpu": "10m",
                "memory": "16Mi"
              },
              "resources": {
                "requests": {
                  "cpu": "10m",
                  "memory": "16Mi"
                }
              },
              "volumeMounts": [
                {
                  "name": "kube-api-access-wffxk",
                  "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
                  "readOnly": true,
                  "recursiveReadOnly": "Disabled"
                }
              ],
              "user": {
                "linux": {
                  "uid": 0,
                  "gid": 0,
                  "supplementalGroups": [
                    0,
                    10
                  ]
                }
              }
            }
          ],
          "qosClass": "Burstable",
          "ephemeralContainerStatuses": [
            {
              "name": "debugger-sb6mg",
              "state": {
                "terminated": {
                  "exitCode": 0,
                  "reason": "Completed",
                  "startedAt": "2026-07-02T23:16:06Z",
                  "finishedAt": "2026-07-02T23:16:06Z",
                  "containerID": "containerd://a10672a7ba0453e05c9453d1957c1af1ea622a27e31fe947367de002123ec2f2"
                }
              },
              "lastState": {},
              "ready": false,
              "restartCount": 0,
              "image": "docker.io/library/busybox:1.36",
              "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
              "containerID": "containerd://a10672a7ba0453e05c9453d1957c1af1ea622a27e31fe947367de002123ec2f2",
              "resources": {},
              "user": {
                "linux": {
                  "uid": 0,
                  "gid": 0,
                  "supplementalGroups": [
                    0,
                    10
                  ]
                }
              }
            }
          ],
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "memory": "16Mi"
            }
          }
        }
      },
      {
        "metadata": {
          "name": "dw-harn-replicationcontrollers-4lkgq",
          "generateName": "dw-harn-replicationcontrollers-",
          "namespace": "dw-harn",
          "uid": "00000000-0000-0000-0000-000000000000",
          "resourceVersion": "990",
          "generation": 1,
          "creationTimestamp": "2026-07-02T23:13:38Z",
          "labels": {
            "app": "dw-harn"
          }
        },
        "spec": {
          "volumes": [
            {
              "name": "kube-api-access-zhflt",
              "projected": {
                "sources": [
                  {
                    "serviceAccountToken": {
                      "expirationSeconds": 3607,
                      "path": "token"
                    }
                  },
                  {
                    "configMap": {
                      "name": "kube-root-ca.crt",
                      "items": [
                        {
                          "key": "ca.crt",
                          "path": "ca.crt"
                        }
                      ]
                    }
                  },
                  {
                    "downwardAPI": {
                      "items": [
                        {
                          "path": "namespace",
                          "fieldRef": {
                            "apiVersion": "v1",
                            "fieldPath": "metadata.namespace"
                          }
                        }
                      ]
                    }
                  }
                ],
                "defaultMode": 420
              }
            }
          ],
          "containers": [
            {
              "name": "c",
              "image": "docker.io/library/busybox:1.36",
              "command": [
                "sh",
                "-c",
                "sleep 3600"
              ],
              "resources": {},
              "volumeMounts": [
                {
                  "name": "kube-api-access-zhflt",
                  "readOnly": true,
                  "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
                }
              ],
              "terminationMessagePath": "/dev/termination-log",
              "terminationMessagePolicy": "File",
              "imagePullPolicy": "IfNotPresent"
            }
          ],
          "restartPolicy": "Always",
          "terminationGracePeriodSeconds": 0,
          "dnsPolicy": "ClusterFirst",
          "serviceAccountName": "default",
          "serviceAccount": "default",
          "nodeName": "node-control-plane",
          "securityContext": {},
          "schedulerName": "default-scheduler",
          "tolerations": [
            {
              "key": "node.kubernetes.io/not-ready",
              "operator": "Exists",
              "effect": "NoExecute",
              "tolerationSeconds": 300
            },
            {
              "key": "node.kubernetes.io/unreachable",
              "operator": "Exists",
              "effect": "NoExecute",
              "tolerationSeconds": 300
            }
          ],
          "priority": 0,
          "enableServiceLinks": true,
          "preemptionPolicy": "PreemptLowerPriority"
        },
        "status": {
          "observedGeneration": 1,
          "phase": "Running",
          "conditions": [
            {
              "type": "PodReadyToStartContainers",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:39Z"
            },
            {
              "type": "Initialized",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:38Z"
            },
            {
              "type": "Ready",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:39Z"
            },
            {
              "type": "ContainersReady",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:39Z"
            },
            {
              "type": "PodScheduled",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:38Z"
            }
          ],
          "hostIP": "172.19.0.2",
          "hostIPs": [
            {
              "ip": "172.19.0.2"
            }
          ],
          "podIP": "10.244.0.10",
          "podIPs": [
            {
              "ip": "10.244.0.10"
            }
          ],
          "startTime": "2026-07-02T23:13:38Z",
          "containerStatuses": [
            {
              "name": "c",
              "state": {
                "running": {
                  "startedAt": "2026-07-02T23:13:39Z"
                }
              },
              "lastState": {},
              "ready": true,
              "restartCount": 0,
              "image": "docker.io/library/busybox:1.36",
              "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
              "containerID": "containerd://8c005ccf8124b12dda4d565bd8c93d4f2baac1d665e4be944537bbc33df5059b",
              "started": true,
              "resources": {},
              "volumeMounts": [
                {
                  "name": "kube-api-access-zhflt",
                  "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
                  "readOnly": true,
                  "recursiveReadOnly": "Disabled"
                }
              ],
              "user": {
                "linux": {
                  "uid": 0,
                  "gid": 0,
                  "supplementalGroups": [
                    0,
                    10
                  ]
                }
              }
            }
          ],
          "qosClass": "BestEffort",
          "resources": {}
        }
      },
      {
        "metadata": {
          "name": "dw-harn-replicationcontrollers-xhqqz",
          "generateName": "dw-harn-replicationcontrollers-",
          "namespace": "dw-harn",
          "uid": "00000000-0000-0000-0000-000000000000",
          "resourceVersion": "999",
          "generation": 1,
          "creationTimestamp": "2026-07-02T23:13:43Z",
          "labels": {
            "app": "dw-harn"
          }
        },
        "spec": {
          "volumes": [
            {
              "name": "kube-api-access-4954t",
              "projected": {
                "sources": [
                  {
                    "serviceAccountToken": {
                      "expirationSeconds": 3607,
                      "path": "token"
                    }
                  },
                  {
                    "configMap": {
                      "name": "kube-root-ca.crt",
                      "items": [
                        {
                          "key": "ca.crt",
                          "path": "ca.crt"
                        }
                      ]
                    }
                  },
                  {
                    "downwardAPI": {
                      "items": [
                        {
                          "path": "namespace",
                          "fieldRef": {
                            "apiVersion": "v1",
                            "fieldPath": "metadata.namespace"
                          }
                        }
                      ]
                    }
                  }
                ],
                "defaultMode": 420
              }
            }
          ],
          "containers": [
            {
              "name": "c",
              "image": "docker.io/library/busybox:1.36",
              "command": [
                "sh",
                "-c",
                "sleep 3600"
              ],
              "resources": {},
              "volumeMounts": [
                {
                  "name": "kube-api-access-4954t",
                  "readOnly": true,
                  "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
                }
              ],
              "terminationMessagePath": "/dev/termination-log",
              "terminationMessagePolicy": "File",
              "imagePullPolicy": "IfNotPresent"
            }
          ],
          "restartPolicy": "Always",
          "terminationGracePeriodSeconds": 0,
          "dnsPolicy": "ClusterFirst",
          "serviceAccountName": "default",
          "serviceAccount": "default",
          "nodeName": "node-control-plane",
          "securityContext": {},
          "schedulerName": "default-scheduler",
          "tolerations": [
            {
              "key": "node.kubernetes.io/not-ready",
              "operator": "Exists",
              "effect": "NoExecute",
              "tolerationSeconds": 300
            },
            {
              "key": "node.kubernetes.io/unreachable",
              "operator": "Exists",
              "effect": "NoExecute",
              "tolerationSeconds": 300
            }
          ],
          "priority": 0,
          "enableServiceLinks": true,
          "preemptionPolicy": "PreemptLowerPriority"
        },
        "status": {
          "observedGeneration": 1,
          "phase": "Running",
          "conditions": [
            {
              "type": "PodReadyToStartContainers",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:43Z"
            },
            {
              "type": "Initialized",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:43Z"
            },
            {
              "type": "Ready",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:43Z"
            },
            {
              "type": "ContainersReady",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:43Z"
            },
            {
              "type": "PodScheduled",
              "observedGeneration": 1,
              "status": "True",
              "lastProbeTime": null,
              "lastTransitionTime": "2026-07-02T23:13:43Z"
            }
          ],
          "hostIP": "172.19.0.2",
          "hostIPs": [
            {
              "ip": "172.19.0.2"
            }
          ],
          "podIP": "10.244.0.11",
          "podIPs": [
            {
              "ip": "10.244.0.11"
            }
          ],
          "startTime": "2026-07-02T23:13:43Z",
          "containerStatuses": [
            {
              "name": "c",
              "state": {
                "running": {
                  "startedAt": "2026-07-02T23:13:43Z"
                }
              },
              "lastState": {},
              "ready": true,
              "restartCount": 0,
              "image": "docker.io/library/busybox:1.36",
              "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
              "containerID": "containerd://e9401c60e561db88dd8e3eccee1cb9da508a2e3a9bc68a0a1a66cb3f4be11c4a",
              "started": true,
              "resources": {},
              "volumeMounts": [
                {
                  "name": "kube-api-access-4954t",
                  "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
                  "readOnly": true,
                  "recursiveReadOnly": "Disabled"
                }
              ],
              "user": {
                "linux": {
                  "uid": 0,
                  "gid": 0,
                  "supplementalGroups": [
                    0,
                    10
                  ]
                }
              }
            }
          ],
          "qosClass": "BestEffort",
          "resources": {}
        }
      }
    ]
  },
  "requestReceivedTimestamp": "2026-07-02T23:16:08.698127Z",
  "stageTimestamp": "2026-07-02T23:16:08.959450Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

get pods/attach

#
Resource
pods

The audit log records that this call happened, not the interactive session that followed; Falco or Tetragon add that in-session visibility.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/attach?container=c&stderr=true&stdout=true",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "attach"
  },
  "responseStatus": {
    "metadata": {},
    "code": 101
  },
  "requestReceivedTimestamp": "2026-07-02T22:48:44.678739Z",
  "stageTimestamp": "2026-07-02T22:48:52.632830Z",
  "annotations": {
    "apiserver.latency.k8s.io/authentication": "105.068µs",
    "apiserver.latency.k8s.io/authorization": "33.719µs",
    "apiserver.latency.k8s.io/etcd": "1.669812ms",
    "apiserver.latency.k8s.io/total": "7.954084922s",
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
objectRef.resource (falco rule field)eqpods1 rulefalco
objectRef.subresource (falco rule field)is_not_null1 rulefalco
verb (falco rule field)eqget1 rulefalco

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.

Falco #

References #

create pods/attach

#
Resource
pods

Description

Container attach (kubectl attach; interactive session).

The audit log records that this call happened, not the interactive session that followed; Falco or Tetragon add that in-session visibility.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/attach?container=c&stderr=true&stdout=true",
  "verb": "create",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "attach"
  },
  "responseStatus": {
    "metadata": {},
    "code": 101
  },
  "requestReceivedTimestamp": "2026-07-02T22:48:52.711282Z",
  "stageTimestamp": "2026-07-02T22:49:00.677343Z",
  "annotations": {
    "apiserver.latency.k8s.io/authentication": "106.127µs",
    "apiserver.latency.k8s.io/authorization": "31.005µs",
    "apiserver.latency.k8s.io/etcd": "2.32657ms",
    "apiserver.latency.k8s.io/total": "7.966054776s",
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
objectRef.resource (falco rule field)eqpods1 rulefalco
objectRef.subresource (falco rule field)is_not_null1 rulefalco
objectRef:resource (panther rule field)eqpods1 rulepanther
verb (falco rule field)eqget1 rulefalco

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.

Panther #

  • Kubernetes Pod Created in Pre-Configured or Default Name Spaces source medium linked query: Kubernetes Pod Created in Pre-Configured or Default Name Spaces: This detection monitors for any pod created in pre-configured or default namespaces. Only Cluster Admins should be creating pods in the kube-system namespace, and it is best practice not to run any cluster critical infrastructure here. The kube-public namespace is intended to be readable by unauthenticated users. The default namespace is shipped with the cluster and it is best practice not to deploy production workloads here. These namespaces may be used to evade defenses or hide attacker infrastructure.
  • Kubernetes Pod Created in Pre-Configured or Default Name Spaces source: This detection monitors for any pod created in pre-configured or default namespaces. Only Cluster Admins should be creating pods in the kube-system namespace, and it is best practice not to run any cluster critical infrastructure here. The kube-public namespace is intended to be readable by unauthenticated users. The default namespace is shipped with the cluster and it is best practice not to deploy production workloads here. These namespaces may be used to evade defenses or hide attacker infrastructure.

Falco #

References #

create pods/binding

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pod-bind/binding",
  "verb": "create",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pod-bind",
    "apiVersion": "v1",
    "subresource": "binding"
  },
  "responseStatus": {
    "metadata": {},
    "status": "Success",
    "code": 201
  },
  "requestObject": {
    "kind": "Binding",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pod-bind",
      "namespace": "dw-harn"
    },
    "target": {
      "kind": "Node",
      "name": "node-control-plane",
      "apiVersion": "v1"
    }
  },
  "responseObject": {
    "kind": "Status",
    "apiVersion": "v1",
    "metadata": {},
    "status": "Success",
    "code": 201
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:57.861172Z",
  "stageTimestamp": "2026-07-02T04:48:57.864867Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

get pods/ephemeralcontainers

#
Resource
pods

Description

Ephemeral debug containers injected into a running pod.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/ephemeralcontainers",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "ephemeralcontainers"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T22:49:17.168775Z",
  "stageTimestamp": "2026-07-02T22:49:17.170894Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

update pods/ephemeralcontainers

#
Resource
pods

Description

Adds an ephemeral debug container to a running pod via update. Elastic flags this from a non-system identity: it can inject tooling or reach mounted secrets.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/ephemeralcontainers",
  "verb": "update",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "uid": "00000000-0000-0000-0000-000000000000",
    "apiVersion": "v1",
    "resourceVersion": "1395",
    "subresource": "ephemeralcontainers"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1395",
      "generation": 2,
      "creationTimestamp": "2026-07-02T22:48:39Z",
      "labels": {
        "app": "dw-harn",
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-6v2nh",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "ephemeralContainers": [
        {
          "name": "debugger-qrp4k",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "true"
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent",
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 2,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.11",
      "podIPs": [
        {
          "ip": "10.244.0.11"
        }
      ],
      "startTime": "2026-07-02T22:48:39Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:48:40Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://22a94e64e6b0f15416b36663b28abc4da5a9e92f9cc537badb41f3458a4ef2ef",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "ephemeralContainerStatuses": [
        {
          "name": "debugger-qrp4k",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:49:16Z"
            }
          },
          "lastState": {},
          "ready": false,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://03cfd3d6a09e438581fdaebc43da96cdaf4031afd2385027089505a7715dd9e8",
          "resources": {},
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1395",
      "generation": 2,
      "creationTimestamp": "2026-07-02T22:48:39Z",
      "labels": {
        "app": "dw-harn",
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-6v2nh",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "ephemeralContainers": [
        {
          "name": "debugger-qrp4k",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "true"
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent",
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 2,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.11",
      "podIPs": [
        {
          "ip": "10.244.0.11"
        }
      ],
      "startTime": "2026-07-02T22:48:39Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:48:40Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://22a94e64e6b0f15416b36663b28abc4da5a9e92f9cc537badb41f3458a4ef2ef",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "ephemeralContainerStatuses": [
        {
          "name": "debugger-qrp4k",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:49:16Z"
            }
          },
          "lastState": {},
          "ready": false,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://03cfd3d6a09e438581fdaebc43da96cdaf4031afd2385027089505a7715dd9e8",
          "resources": {},
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "requestReceivedTimestamp": "2026-07-02T22:49:17.235993Z",
  "stageTimestamp": "2026-07-02T22:49:17.242118Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\"",
    "pod-security.kubernetes.io/enforce-policy": "privileged:latest"
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
azure.platformlogs.properties.log.objectRef.resource (elastic rule field)eqpods1 ruleelastic
azure.platformlogs.properties.log.verb (elastic rule field)inpatch1 ruleelastic
azure.platformlogs.properties.log.verb (elastic rule field)inupdate1 ruleelastic
objectRef.resource (falco rule field)eqpods1 rulefalco
objectRef.subresource (falco rule field)is_not_null1 rulefalco

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Azure AKS Ephemeral Container Added to Pod source medium: Detects an identity injecting an ephemeral (debug) container into a running AKS (Azure Kubernetes Service) pod via the pods/ephemeralcontainers subresource, excluding known AKS control-plane and platform identities. Ephemeral containers share the target pod's namespaces and give stealthy interactive access to its processes and mounted secrets without creating a new pod. Coverage includes workload service accounts (system:serviceaccount:*), so a compromised in-cluster token used to attach a debug container is not excluded.T1610↳ also matches patch-pods-ephemeralcontainers: patch pods/ephemeralcontainers
    Investigation guide

    Triage and analysis#

    Investigating Azure AKS Ephemeral Container Added to Pod#

    AKS kube-audit events are carried under the flattened azure.platformlogs.properties.log.* subtree and share the ARM operation event.action: Microsoft.ContainerService/managedClusters/diagnosticLogs/Read. An ephemeral container is attached to a running pod (via kubectl debug) and shares that pod's process and network namespaces. Adversaries use it as a stealthier alternative to exec to read mounted secrets and interact with the workload.

    Possible investigation steps#

    • Identify the acting identity in azure.platformlogs.properties.log.user.username (and its groups in azure.platformlogs.properties.log.user.groups) and whether it should debug pods. A username of masterclient with the system:masters group is the AKS local cluster-admin certificate (az aks get-credentials --admin); on clusters with local accounts disabled it should not appear at all, so its presence is itself notable. Entra-integrated admins appear as their UPN/objectId instead.
    • Inspect the injected container in the azure.platformlogs.properties.log.requestObject.spec.ephemeralContainers.* fields: the image, command, and targetContainerName show what was run and against which container, and securityContext.capabilities.add (e.g. SYS_PTRACE, SYS_ADMIN) or a privileged context indicates offensive debugging.
    • Review azure.platformlogs.properties.log.userAgent to distinguish an interactive kubectl debug from automation or custom tooling, and azure.platformlogs.properties.log.responseStatus.code to tell a successful injection (200) from a denied attempt (403) by an identity lacking RBAC.
    • Identify the target pod in azure.platformlogs.properties.log.objectRef.name / azure.platformlogs.properties.log.objectRef.namespace.
    • Evaluate the source in azure.platformlogs.properties.log.sourceIPs and pivot on it for related exec sessions, secret reads, or RBAC changes.

    False positive analysis#

    • Operators and support tooling use ephemeral containers for legitimate troubleshooting; baseline expected users and exclude verified break-glass or platform identities.

    Response and remediation#

    • If unauthorized, remove the ephemeral container (delete or replace the pod), revoke the acting identity's tokens, and review the RBAC that permitted the injection.
    • Inspect the target pod for accessed secrets or tampering and rotate any exposed credentials.
    • Collect kube-audit and identity artifacts per incident response procedures.
  • GKE Ephemeral Container Added to Pod source medium: Detects allowed updates or patches to the pods/ephemeralcontainers subresource on GKE by a non-system identity. Ephemeral containers are commonly used for debugging (kubectl debug) but can also be abused to inject tooling into a running pod, access mounted secrets, and execute commands in the target pod context. Attackers with sufficient RBAC may use ephemeral containers to escalate privileges, move laterally, or establish persistence without deploying a new workload.T1609, T1611↳ also matches patch-pods-ephemeralcontainers: patch pods/ephemeralcontainers
    Investigation guide

    Triage and analysis#

    Investigating GKE Ephemeral Container Added to Pod#

    Ephemeral containers allow adding a container to an existing pod for troubleshooting. When abused, they can gain interactive access to a workload, read sensitive files, and run tools that were not present in the original image.

    Possible investigation steps#

    • Review client.user.email, source.ip, and user_agent.original and confirm the identity is authorized to use ephemeral containers.
    • Inspect gcp.audit.resource_name to identify the targeted pod and owning workload.
    • If request bodies are captured, review the ephemeral container image, command, and securityContext for privilege indicators.
    • Correlate with follow-on audit activity such as pod exec, secret reads, TokenRequest, or RBAC modifications.

    False positive analysis#

    • Approved on-call debugging with kubectl debug may match. Allowlist known admin identities after review.

    Response and remediation#

    • If unauthorized, remove excessive RBAC that grants update or patch on pods/ephemeralcontainers and rotate exposed credentials.
    • Quarantine or redeploy impacted workloads and hunt for additional compromised pods or identities.
  • Kubernetes Ephemeral Container Added to Pod source medium: Detects allowed updates to the pods/ephemeralcontainers subresource by a non-system identity. Ephemeral containers are commonly used for debugging (kubectl debug) but can also be abused to inject tooling into a running pod, access mounted secrets, and execute commands in the target pod context. Attackers with sufficient RBAC may use ephemeral containers to escalate privileges, move laterally, or establish persistence without deploying a new workload.T1609, T1611↳ also matches patch-pods-ephemeralcontainers: patch pods/ephemeralcontainers
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Kubernetes Ephemeral Container Added to Pod#

    Ephemeral containers allow adding a container to an existing pod for troubleshooting. When abused, they can be used to gain interactive access to a workload, read sensitive files, and run tools that were not present in the original image.

    Possible investigation steps#

    • Review the actor (user.name, groups), source.ip, and user_agent.original and confirm the identity is authorized to use ephemeral containers.
    • Inspect kubernetes.audit.objectRef (namespace, name) to identify the targeted pod and workload owner.
    • If request bodies are captured, review the ephemeral container image, command, and securityContext for privilege indicators.
    • Correlate with follow-on audit activity such as pod exec, secret reads, TokenRequest, or RBAC modifications.

    Response and remediation#

    • If unauthorized, remove excessive RBAC that grants update/patch on pods/ephemeralcontainers and rotate exposed credentials.
    • Quarantine or redeploy impacted workloads and hunt for additional compromised pods or identities.

Falco #

References #

patch pods/ephemeralcontainers

#
Resource
pods

Description

Same ephemeral-container injection as update, via patch. Elastic's rule excludes node/kube-system service accounts and expects only approved admins here.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/ephemeralcontainers",
  "verb": "patch",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "ephemeralcontainers"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "spec": {
      "ephemeralContainers": [
        {
          "command": [
            "true"
          ],
          "image": "docker.io/library/busybox:1.36",
          "name": "debugger-j4cpn",
          "resources": {},
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          },
          "terminationMessagePolicy": "File"
        }
      ]
    }
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1781",
      "generation": 2,
      "creationTimestamp": "2026-07-02T04:48:48Z",
      "labels": {
        "app": "dw-harn"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-jx7nf",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-jx7nf",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "ephemeralContainers": [
        {
          "name": "debugger-j4cpn",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "true"
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent",
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 1,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:48Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 1,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:48Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.10",
      "podIPs": [
        {
          "ip": "10.244.0.10"
        }
      ],
      "startTime": "2026-07-02T04:48:48Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T04:48:49Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://cbb5514b60b38dcd34d9a3cd6d26f1f35a35af4f9a0abee6f98a0f1b682342c6",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-jx7nf",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "cpu": "10m",
          "memory": "16Mi"
        }
      }
    }
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:57.516952Z",
  "stageTimestamp": "2026-07-02T04:48:57.526224Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\"",
    "pod-security.kubernetes.io/enforce-policy": "privileged:latest"
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
azure.platformlogs.properties.log.objectRef.resource (elastic rule field)eqpods1 ruleelastic
objectRef.subresource (falco rule field)is_not_null1 rulefalco

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Azure AKS Ephemeral Container Added to Pod source medium: Detects an identity injecting an ephemeral (debug) container into a running AKS (Azure Kubernetes Service) pod via the pods/ephemeralcontainers subresource, excluding known AKS control-plane and platform identities. Ephemeral containers share the target pod's namespaces and give stealthy interactive access to its processes and mounted secrets without creating a new pod. Coverage includes workload service accounts (system:serviceaccount:*), so a compromised in-cluster token used to attach a debug container is not excluded.T1610↳ also matches update-pods-ephemeralcontainers: update pods/ephemeralcontainers
    Investigation guide

    Triage and analysis#

    Investigating Azure AKS Ephemeral Container Added to Pod#

    AKS kube-audit events are carried under the flattened azure.platformlogs.properties.log.* subtree and share the ARM operation event.action: Microsoft.ContainerService/managedClusters/diagnosticLogs/Read. An ephemeral container is attached to a running pod (via kubectl debug) and shares that pod's process and network namespaces. Adversaries use it as a stealthier alternative to exec to read mounted secrets and interact with the workload.

    Possible investigation steps#

    • Identify the acting identity in azure.platformlogs.properties.log.user.username (and its groups in azure.platformlogs.properties.log.user.groups) and whether it should debug pods. A username of masterclient with the system:masters group is the AKS local cluster-admin certificate (az aks get-credentials --admin); on clusters with local accounts disabled it should not appear at all, so its presence is itself notable. Entra-integrated admins appear as their UPN/objectId instead.
    • Inspect the injected container in the azure.platformlogs.properties.log.requestObject.spec.ephemeralContainers.* fields: the image, command, and targetContainerName show what was run and against which container, and securityContext.capabilities.add (e.g. SYS_PTRACE, SYS_ADMIN) or a privileged context indicates offensive debugging.
    • Review azure.platformlogs.properties.log.userAgent to distinguish an interactive kubectl debug from automation or custom tooling, and azure.platformlogs.properties.log.responseStatus.code to tell a successful injection (200) from a denied attempt (403) by an identity lacking RBAC.
    • Identify the target pod in azure.platformlogs.properties.log.objectRef.name / azure.platformlogs.properties.log.objectRef.namespace.
    • Evaluate the source in azure.platformlogs.properties.log.sourceIPs and pivot on it for related exec sessions, secret reads, or RBAC changes.

    False positive analysis#

    • Operators and support tooling use ephemeral containers for legitimate troubleshooting; baseline expected users and exclude verified break-glass or platform identities.

    Response and remediation#

    • If unauthorized, remove the ephemeral container (delete or replace the pod), revoke the acting identity's tokens, and review the RBAC that permitted the injection.
    • Inspect the target pod for accessed secrets or tampering and rotate any exposed credentials.
    • Collect kube-audit and identity artifacts per incident response procedures.
  • GKE Ephemeral Container Added to Pod source medium: Detects allowed updates or patches to the pods/ephemeralcontainers subresource on GKE by a non-system identity. Ephemeral containers are commonly used for debugging (kubectl debug) but can also be abused to inject tooling into a running pod, access mounted secrets, and execute commands in the target pod context. Attackers with sufficient RBAC may use ephemeral containers to escalate privileges, move laterally, or establish persistence without deploying a new workload.T1609, T1611↳ also matches update-pods-ephemeralcontainers: update pods/ephemeralcontainers
    Investigation guide

    Triage and analysis#

    Investigating GKE Ephemeral Container Added to Pod#

    Ephemeral containers allow adding a container to an existing pod for troubleshooting. When abused, they can gain interactive access to a workload, read sensitive files, and run tools that were not present in the original image.

    Possible investigation steps#

    • Review client.user.email, source.ip, and user_agent.original and confirm the identity is authorized to use ephemeral containers.
    • Inspect gcp.audit.resource_name to identify the targeted pod and owning workload.
    • If request bodies are captured, review the ephemeral container image, command, and securityContext for privilege indicators.
    • Correlate with follow-on audit activity such as pod exec, secret reads, TokenRequest, or RBAC modifications.

    False positive analysis#

    • Approved on-call debugging with kubectl debug may match. Allowlist known admin identities after review.

    Response and remediation#

    • If unauthorized, remove excessive RBAC that grants update or patch on pods/ephemeralcontainers and rotate exposed credentials.
    • Quarantine or redeploy impacted workloads and hunt for additional compromised pods or identities.
  • Kubernetes Ephemeral Container Added to Pod source medium: Detects allowed updates to the pods/ephemeralcontainers subresource by a non-system identity. Ephemeral containers are commonly used for debugging (kubectl debug) but can also be abused to inject tooling into a running pod, access mounted secrets, and execute commands in the target pod context. Attackers with sufficient RBAC may use ephemeral containers to escalate privileges, move laterally, or establish persistence without deploying a new workload.T1609, T1611↳ also matches update-pods-ephemeralcontainers: update pods/ephemeralcontainers
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Kubernetes Ephemeral Container Added to Pod#

    Ephemeral containers allow adding a container to an existing pod for troubleshooting. When abused, they can be used to gain interactive access to a workload, read sensitive files, and run tools that were not present in the original image.

    Possible investigation steps#

    • Review the actor (user.name, groups), source.ip, and user_agent.original and confirm the identity is authorized to use ephemeral containers.
    • Inspect kubernetes.audit.objectRef (namespace, name) to identify the targeted pod and workload owner.
    • If request bodies are captured, review the ephemeral container image, command, and securityContext for privilege indicators.
    • Correlate with follow-on audit activity such as pod exec, secret reads, TokenRequest, or RBAC modifications.

    Response and remediation#

    • If unauthorized, remove excessive RBAC that grants update/patch on pods/ephemeralcontainers and rotate exposed credentials.
    • Quarantine or redeploy impacted workloads and hunt for additional compromised pods or identities.

Falco #

References #

create pods/eviction

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pod-evict/eviction",
  "verb": "create",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pod-evict",
    "apiVersion": "v1",
    "subresource": "eviction"
  },
  "responseStatus": {
    "metadata": {},
    "status": "Success",
    "code": 201
  },
  "requestObject": {
    "kind": "Eviction",
    "apiVersion": "policy/v1",
    "metadata": {
      "name": "dw-harn-pod-evict",
      "namespace": "dw-harn"
    },
    "deleteOptions": {
      "gracePeriodSeconds": 0
    }
  },
  "responseObject": {
    "kind": "Status",
    "apiVersion": "v1",
    "metadata": {},
    "status": "Success",
    "code": 201
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:58.720084Z",
  "stageTimestamp": "2026-07-02T04:48:58.731234Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

get pods/exec

#
Resource
pods

Description

Some exec clients issue GET instead of create on pods/exec. Elastic's exec-to-pod rule matches verb (get, create), so a create-only watch misses it.

The audit log records that this call happened, not the interactive session that followed; Falco or Tetragon add that in-session visibility.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/exec?command=echo&command=dw-harn&container=c&stderr=true&stdout=true",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "exec"
  },
  "responseStatus": {
    "metadata": {},
    "code": 101
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:49.327201Z",
  "stageTimestamp": "2026-07-02T04:48:49.364478Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
EventType (elastic rule field)inio.k8s.core.v1.pods.exec.create5 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.exec.get5 ruleselastic
kubernetes.audit.objectRef.subresource (elastic rule field)eqexec5 ruleselastic
ServiceName (elastic rule field)eqk8s.io4 ruleselastic
kubernetes.audit.requestURI (elastic rule field)containscommand=4 ruleselastic
kubernetes.audit.stage (elastic rule field)inResponseComplete2 ruleselastic
kubernetes.audit.stage (elastic rule field)inResponseStarted2 ruleselastic
kubernetes.audit.verb (elastic rule field)inget2 ruleselastic
verb (panther rule field)increate2 rulespanther
verb (panther rule field)inget2 rulespanther
azure.platformlogs.category (elastic rule field)eqkube-audit1 ruleelastic
azure.platformlogs.properties.log.objectRef.resource (elastic rule field)eqpods1 ruleelastic
azure.platformlogs.properties.log.verb (elastic rule field)increate1 ruleelastic
azure.platformlogs.properties.log.verb (elastic rule field)inget1 ruleelastic
objectRef.resource (falco rule field)eqpods1 rulefalco

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Azure AKS Attempted User Exec into Pod source medium: Detects an AKS (Azure Kubernetes Service) identity establishing an exec session into a pod. Interactive command execution inside a workload via kubectl exec is a common post-compromise technique used to access secrets, run tooling, and expand access from a foothold container. Node, control-plane, and kube-system service account identities are excluded, so workload service accounts and users, the identities an adversary is most likely to abuse, remain in scope.T1609↳ also matches create-pods-exec: create pods/exec
    Investigation guide

    Triage and analysis#

    Investigating Azure AKS Attempted User Exec into Pod#

    AKS kube-audit events are carried under the flattened azure.platformlogs.properties.log.* subtree and share the ARM operation event.action: Microsoft.ContainerService/managedClusters/diagnosticLogs/Read. This rule alerts on a pods/exec request by an identity that is not node, control-plane, or kube-system infrastructure. Exec into a pod grants an interactive shell inside the workload, which adversaries use to read mounted secrets, pivot, and stage tooling.

    Possible investigation steps#

    • Review the acting identity in azure.platformlogs.properties.log.user.username and its groups in azure.platformlogs.properties.log.user.groups, and the target pod in azure.platformlogs.properties.log.objectRef.name / azure.platformlogs.properties.log.objectRef.namespace.
    • Determine whether the target pod holds sensitive data, cluster credentials, or a mounted service account token.
    • Inspect the exec request path and command context in azure.platformlogs.properties.log.requestURI and the client in azure.platformlogs.properties.log.userAgent (interactive kubectl vs a scripted client).
    • Evaluate the source in azure.platformlogs.properties.log.sourceIPs. Pivot on it for related API activity, secret reads, or RBAC changes from the same identity.

    False positive analysis#

    • Approved admin debugging; exclude stable operator or break-glass identities after review.
    • CI/CD or platform tooling that execs into workloads may match; exclude verified service accounts and namespaces.

    Response and remediation#

    • If unauthorized, revoke the identity's tokens and kubeconfig and terminate the exec session.
    • Inspect the target pod for tampering, dropped tooling, or accessed secrets, and rotate any credentials it exposed.
    • Collect kube-audit and identity artifacts per incident response procedures.
  • GKE Pod Exec Cloud Instance Metadata Access source high: Detects successful GKE pod exec sessions whose command references Google Cloud instance metadata endpoints, including metadata.google.internal, computeMetadata/v1, or the link-local metadata IP 169.254.169.254. Workloads that reach the GKE metadata service from an exec session are often attempting to harvest short-lived credentials or instance attributes from the node or workload identity boundary. That behavior is high risk because it can expose cloud credentials to code running inside a container. GKE records the command in gcp.audit.labels.command.gke.io/command when an explicit command is passed to exec.T1552, T1552.005, T1609↳ also matches create-pods-exec: create pods/exec
    Investigation guide

    Triage and analysis#

    Investigating GKE Pod Exec Cloud Instance Metadata Access#

    This alert fires when a successful pods/exec API call includes a command targeting GKE/GCP instance metadata. Review gcp.audit.labels.command.gke.io/command for the full command string.

    Possible investigation steps#

    • Confirm the actor (client.user.email), source IP, and user agent that performed exec.
    • Map gcp.audit.resource_name to the target pod/namespace and determine whether the workload should ever call metadata.
    • Correlate with GCP audit logs for token issuance or IAM activity around the same time from the node or workload identity.
    • Hunt adjacent activity from the same identity: secret reads, additional execs, or RBAC changes.

    False positive analysis#

    • Approved platform tooling or bootstrap scripts may query metadata during startup; baseline those images and identities.
    • Break-glass egress/metadata connectivity tests can match; document and allowlist those principals.

    Response and remediation#

    • If unauthorized, terminate the session, isolate the workload, revoke or rotate instance and workload credentials that could have been read, and tighten pods/exec RBAC plus network policies that deny link-local metadata from pods.
  • GKE Pod Exec Sensitive File or Credential Path Access source high: Detects successful GKE pod exec sessions where the executed command references high-value host or in-cluster paths: mounted service account or platform tokens, kubelet and control-plane configuration areas, host identity stores, root or home credential directories, common private-key and keystore extensions, process environment dumps, and configuration filenames suggestive of embedded secrets. Attackers with pods/exec often use these one-liners to steal credentials before lateral movement or privilege escalation. A narrow exclusion ignores benign resolv.conf reads. GKE records the command in gcp.audit.labels.command.gke.io/command when an explicit command is passed to exec.T1552, T1552.001, T1552.007, T1609↳ also matches create-pods-exec: create pods/exec
    Investigation guide

    Triage and analysis#

    Investigating GKE Pod Exec Sensitive File or Credential Path Access#

    This alert fires when a successful pods/exec API call includes a command matching sensitive path or filename patterns. Review gcp.audit.labels.command.gke.io/command for the reconstructed command string.

    Possible investigation steps#

    • Identify the actor (client.user.email), source IP, and user agent for the exec caller.
    • Map gcp.audit.resource_name (namespace/pod) to a workload owner, image, and change history.
    • Correlate adjacent activity from the same identity: secret reads, TokenRequest, RBAC writes, or additional execs.
    • If host-level paths appear, determine whether the workload is privileged, uses hostPath, or runs on break-glass nodes.

    False positive analysis#

    • Diagnostic images and vendor agents sometimes read kubeconfig-like or credential paths; baseline stable automation.
    • Training containers that deliberately demonstrate passwd reads can trigger; scope exceptions to those namespaces.

    Response and remediation#

    • If malicious, end the exec session, isolate the pod or node, rotate credentials that could have been read, and tighten pods/exec RBAC and admission controls.

Panther #

  • Kubernetes Exec Into Pod source medium: Detects when users exec into pods across Kubernetes clusters. Execing into pods should be monitored as it can be used for unauthorized access, privilege escalation, or persistent access to workloads. This detection is disabled by default and should be configured with inline filters in the Panther UI to exclude legitimate use cases (e.g., specific service accounts, namespaces, or authorized users).↳ also matches create-pods-exec: create pods/exec
  • Kubernetes Data Copy via kubectl cp source medium: This detection monitors for kubectl cp operations that copy files from pods to local machines, which can indicate data exfiltration. When kubectl cp is used to copy files from a pod, it executes a tar command with stdout output (tar cf -) inside the container and streams the data back through the Kubernetes API server. Attackers who gain cluster access can use this technique to steal application secrets, credentials, configuration files, or sensitive data from container filesystems without leaving obvious traces inside the pod itself. While kubectl cp has legitimate uses for debugging and backup, unexpected usage should be investigated.T1530, T1552↳ also matches create-pods-exec: create pods/exec
  • Unauthorized Kubernetes Pod Execution source medium linked query: Unauthorized Kubernetes Pod Execution: This detection monitors for any pod execution in a kubernetes cluster. Pod execution should never be done in a production cluster, and can indicate a user performing unauthorized actions.↳ also matches create-pods-exec: create pods/exec

Falco #

References #

create pods/exec

#
Resource
pods

Description

Remote command execution in a container (kubectl exec issues create on pods/exec subresource).

The audit log records that this call happened, not the interactive session that followed; Falco or Tetragon add that in-session visibility.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/exec?command=true&container=c&stderr=true&stdout=true",
  "verb": "create",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "exec"
  },
  "responseStatus": {
    "metadata": {},
    "code": 101
  },
  "requestReceivedTimestamp": "2026-07-02T22:48:44.469099Z",
  "stageTimestamp": "2026-07-02T22:48:44.514767Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
EventType (elastic rule field)inio.k8s.core.v1.pods.exec.create5 ruleselastic
EventType (elastic rule field)inio.k8s.core.v1.pods.exec.get5 ruleselastic
kubernetes.audit.objectRef.subresource (elastic rule field)eqexec5 ruleselastic
ServiceName (elastic rule field)eqk8s.io4 ruleselastic
kubernetes.audit.requestURI (elastic rule field)containscommand=4 ruleselastic
kubernetes.audit.stage (elastic rule field)inResponseComplete2 ruleselastic
kubernetes.audit.stage (elastic rule field)inResponseStarted2 ruleselastic
objectRef.resourceeqpods2 rulesfalco, sigma
username (panther rule field)containsserviceaccount2 rulespanther
verb (panther rule field)increate2 rulespanther
verb (panther rule field)inget2 rulespanther
azure.platformlogs.properties.log.objectRef.resource (elastic rule field)eqpods1 ruleelastic
azure.platformlogs.properties.log.verb (elastic rule field)increate1 ruleelastic
azure.platformlogs.properties.log.verb (elastic rule field)inget1 ruleelastic
objectRef.subresource (falco rule field)is_not_null1 rulefalco

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Sigma #

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.
  • Azure AKS Attempted User Exec into Pod source medium: Detects an AKS (Azure Kubernetes Service) identity establishing an exec session into a pod. Interactive command execution inside a workload via kubectl exec is a common post-compromise technique used to access secrets, run tooling, and expand access from a foothold container. Node, control-plane, and kube-system service account identities are excluded, so workload service accounts and users, the identities an adversary is most likely to abuse, remain in scope.T1609↳ also matches get-pods-exec: get pods/exec
    Investigation guide

    Triage and analysis#

    Investigating Azure AKS Attempted User Exec into Pod#

    AKS kube-audit events are carried under the flattened azure.platformlogs.properties.log.* subtree and share the ARM operation event.action: Microsoft.ContainerService/managedClusters/diagnosticLogs/Read. This rule alerts on a pods/exec request by an identity that is not node, control-plane, or kube-system infrastructure. Exec into a pod grants an interactive shell inside the workload, which adversaries use to read mounted secrets, pivot, and stage tooling.

    Possible investigation steps#

    • Review the acting identity in azure.platformlogs.properties.log.user.username and its groups in azure.platformlogs.properties.log.user.groups, and the target pod in azure.platformlogs.properties.log.objectRef.name / azure.platformlogs.properties.log.objectRef.namespace.
    • Determine whether the target pod holds sensitive data, cluster credentials, or a mounted service account token.
    • Inspect the exec request path and command context in azure.platformlogs.properties.log.requestURI and the client in azure.platformlogs.properties.log.userAgent (interactive kubectl vs a scripted client).
    • Evaluate the source in azure.platformlogs.properties.log.sourceIPs. Pivot on it for related API activity, secret reads, or RBAC changes from the same identity.

    False positive analysis#

    • Approved admin debugging; exclude stable operator or break-glass identities after review.
    • CI/CD or platform tooling that execs into workloads may match; exclude verified service accounts and namespaces.

    Response and remediation#

    • If unauthorized, revoke the identity's tokens and kubeconfig and terminate the exec session.
    • Inspect the target pod for tampering, dropped tooling, or accessed secrets, and rotate any credentials it exposed.
    • Collect kube-audit and identity artifacts per incident response procedures.
  • GKE Pod Exec Cloud Instance Metadata Access source high: Detects successful GKE pod exec sessions whose command references Google Cloud instance metadata endpoints, including metadata.google.internal, computeMetadata/v1, or the link-local metadata IP 169.254.169.254. Workloads that reach the GKE metadata service from an exec session are often attempting to harvest short-lived credentials or instance attributes from the node or workload identity boundary. That behavior is high risk because it can expose cloud credentials to code running inside a container. GKE records the command in gcp.audit.labels.command.gke.io/command when an explicit command is passed to exec.T1552, T1552.005, T1609↳ also matches get-pods-exec: get pods/exec
    Investigation guide

    Triage and analysis#

    Investigating GKE Pod Exec Cloud Instance Metadata Access#

    This alert fires when a successful pods/exec API call includes a command targeting GKE/GCP instance metadata. Review gcp.audit.labels.command.gke.io/command for the full command string.

    Possible investigation steps#

    • Confirm the actor (client.user.email), source IP, and user agent that performed exec.
    • Map gcp.audit.resource_name to the target pod/namespace and determine whether the workload should ever call metadata.
    • Correlate with GCP audit logs for token issuance or IAM activity around the same time from the node or workload identity.
    • Hunt adjacent activity from the same identity: secret reads, additional execs, or RBAC changes.

    False positive analysis#

    • Approved platform tooling or bootstrap scripts may query metadata during startup; baseline those images and identities.
    • Break-glass egress/metadata connectivity tests can match; document and allowlist those principals.

    Response and remediation#

    • If unauthorized, terminate the session, isolate the workload, revoke or rotate instance and workload credentials that could have been read, and tighten pods/exec RBAC plus network policies that deny link-local metadata from pods.

Panther #

  • Exec into Pod source medium: Alerts when users exec into pod. Possible to specify specific projects and allowed users.
  • Kubernetes Service Account Token Theft from Pod source high: This detection monitors for commands executed in pods that attempt to read service account tokens from /var/run/secrets/kubernetes.io/serviceaccount/token. Attackers who gain exec access to a pod can steal its service account token to authenticate as that service account to the Kubernetes API server. This enables privilege escalation and lateral movement within the cluster. This is a known attack technique documented by Stratus Red Team.T1078.004, T1550.001, T1552.007
  • Kubernetes Exec Into Pod source medium: Detects when users exec into pods across Kubernetes clusters. Execing into pods should be monitored as it can be used for unauthorized access, privilege escalation, or persistent access to workloads. This detection is disabled by default and should be configured with inline filters in the Panther UI to exclude legitimate use cases (e.g., specific service accounts, namespaces, or authorized users).↳ also matches get-pods-exec: get pods/exec

Falco #

References #

get pods/log

#
Resource
pods

The audit log records that this call happened, not the interactive session that followed; Falco or Tetragon add that in-session visibility.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/log?container=c",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "log"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:49.430544Z",
  "stageTimestamp": "2026-07-02T04:48:49.439154Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.

References #

get pods/portforward

#
Resource
pods

The audit log records that this call happened, not the interactive session that followed; Falco or Tetragon add that in-session visibility.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/portforward?timeout=3s",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "portforward"
  },
  "responseStatus": {
    "metadata": {},
    "code": 101
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:49.510891Z",
  "stageTimestamp": "2026-07-02T04:48:57.450547Z",
  "annotations": {
    "apiserver.latency.k8s.io/authentication": "98.409µs",
    "apiserver.latency.k8s.io/authorization": "26.763µs",
    "apiserver.latency.k8s.io/etcd": "1.56406ms",
    "apiserver.latency.k8s.io/total": "7.939650371s",
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.

Falco #

References #

create pods/portforward

#
Resource
pods

Description

Port forwarding from a pod (kubectl port-forward).

The audit log records that this call happened, not the interactive session that followed; Falco or Tetragon add that in-session visibility.

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/portforward?timeout=3s",
  "verb": "create",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "portforward"
  },
  "responseStatus": {
    "metadata": {},
    "code": 101
  },
  "requestReceivedTimestamp": "2026-07-02T22:49:08.775116Z",
  "stageTimestamp": "2026-07-02T22:49:16.727177Z",
  "annotations": {
    "apiserver.latency.k8s.io/authentication": "74.099µs",
    "apiserver.latency.k8s.io/authorization": "16.315µs",
    "apiserver.latency.k8s.io/etcd": "1.43771ms",
    "apiserver.latency.k8s.io/total": "7.952054383s",
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Direct Interactive Kubernetes API Request by Unusual Utilities source low: This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-pods: get pods, list-pods: list pods, watch-pods: watch pods, create-pods: create pods, update-pods: update pods, patch-pods: patch pods, and 6 more
    Investigation guide

    Triage and analysis#

    Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

    Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#

    This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

    Possible investigation steps#

    • Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
    • Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
    • Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
    • Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
    • If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

    False positive analysis#

    • An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
    • A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

    Response and remediation#

    • Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
    • Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
    • Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
    • Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
    • Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
    • Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.

Falco #

References #

get pods/proxy

#
Resource
pods

create pods/proxy

#
Resource
pods

update pods/proxy

#
Resource
pods

patch pods/proxy

#
Resource
pods

delete pods/proxy

#
Resource
pods

get pods/resize

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/resize",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "resize"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:57.668922Z",
  "stageTimestamp": "2026-07-02T04:48:57.670371Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

update pods/resize

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/resize",
  "verb": "update",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "uid": "00000000-0000-0000-0000-000000000000",
    "apiVersion": "v1",
    "resourceVersion": "1395",
    "subresource": "resize"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1395",
      "generation": 2,
      "creationTimestamp": "2026-07-02T22:48:39Z",
      "labels": {
        "app": "dw-harn",
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-6v2nh",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "ephemeralContainers": [
        {
          "name": "debugger-qrp4k",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "true"
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent",
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 2,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.11",
      "podIPs": [
        {
          "ip": "10.244.0.11"
        }
      ],
      "startTime": "2026-07-02T22:48:39Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:48:40Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://22a94e64e6b0f15416b36663b28abc4da5a9e92f9cc537badb41f3458a4ef2ef",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "ephemeralContainerStatuses": [
        {
          "name": "debugger-qrp4k",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:49:16Z"
            }
          },
          "lastState": {},
          "ready": false,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://03cfd3d6a09e438581fdaebc43da96cdaf4031afd2385027089505a7715dd9e8",
          "resources": {},
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1395",
      "generation": 2,
      "creationTimestamp": "2026-07-02T22:48:39Z",
      "labels": {
        "app": "dw-harn",
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-6v2nh",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "ephemeralContainers": [
        {
          "name": "debugger-qrp4k",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "true"
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent",
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 2,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.11",
      "podIPs": [
        {
          "ip": "10.244.0.11"
        }
      ],
      "startTime": "2026-07-02T22:48:39Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:48:40Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://22a94e64e6b0f15416b36663b28abc4da5a9e92f9cc537badb41f3458a4ef2ef",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "ephemeralContainerStatuses": [
        {
          "name": "debugger-qrp4k",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:49:16Z"
            }
          },
          "lastState": {},
          "ready": false,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://03cfd3d6a09e438581fdaebc43da96cdaf4031afd2385027089505a7715dd9e8",
          "resources": {},
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "requestReceivedTimestamp": "2026-07-02T22:49:17.097404Z",
  "stageTimestamp": "2026-07-02T22:49:17.106035Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\"",
    "pod-security.kubernetes.io/enforce-policy": "privileged:latest"
  }
}

References #

patch pods/resize

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/resize?fieldManager=kubectl-patch",
  "verb": "patch",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "resize"
  },
  "responseStatus": {
    "metadata": {},
    "status": "Failure",
    "message": "Pod \"dw-harn-pods\" is invalid: spec.containers[0].resources.requests: Forbidden: resource requests cannot be removed",
    "reason": "Invalid",
    "details": {
      "name": "dw-harn-pods",
      "kind": "Pod",
      "causes": [
        {
          "reason": "FieldValueForbidden",
          "message": "Forbidden: resource requests cannot be removed",
          "field": "spec.containers[0].resources.requests"
        }
      ]
    },
    "code": 422
  },
  "requestObject": {
    "spec": {
      "containers": [
        {
          "name": "c",
          "resources": {
            "requests": {
              "cpu": "20m"
            }
          }
        }
      ]
    }
  },
  "responseObject": {
    "kind": "Status",
    "apiVersion": "v1",
    "metadata": {},
    "status": "Failure",
    "message": "Pod \"dw-harn-pods\" is invalid: spec.containers[0].resources.requests: Forbidden: resource requests cannot be removed",
    "reason": "Invalid",
    "details": {
      "name": "dw-harn-pods",
      "kind": "Pod",
      "causes": [
        {
          "reason": "FieldValueForbidden",
          "message": "Forbidden: resource requests cannot be removed",
          "field": "spec.containers[0].resources.requests"
        }
      ]
    },
    "code": 422
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:57.671450Z",
  "stageTimestamp": "2026-07-02T04:48:57.675638Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

get pods/status

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/status",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "status"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:57.591897Z",
  "stageTimestamp": "2026-07-02T04:48:57.593497Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

update pods/status

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/status",
  "verb": "update",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "uid": "00000000-0000-0000-0000-000000000000",
    "apiVersion": "v1",
    "resourceVersion": "1392",
    "subresource": "status"
  },
  "responseStatus": {
    "metadata": {},
    "status": "Failure",
    "message": "Operation cannot be fulfilled on pods \"dw-harn-pods\": the object has been modified; please apply your changes to the latest version and try again",
    "reason": "Conflict",
    "details": {
      "name": "dw-harn-pods",
      "kind": "pods"
    },
    "code": 409
  },
  "requestObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1392",
      "generation": 2,
      "creationTimestamp": "2026-07-02T22:48:39Z",
      "labels": {
        "app": "dw-harn",
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-6v2nh",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "ephemeralContainers": [
        {
          "name": "debugger-qrp4k",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "true"
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent",
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 2,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:40Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T22:48:39Z"
        }
      ],
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.11",
      "podIPs": [
        {
          "ip": "10.244.0.11"
        }
      ],
      "startTime": "2026-07-02T22:48:39Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T22:48:40Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://22a94e64e6b0f15416b36663b28abc4da5a9e92f9cc537badb41f3458a4ef2ef",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-6v2nh",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "ephemeralContainerStatuses": [
        {
          "name": "debugger-qrp4k",
          "state": {
            "waiting": {
              "reason": "ContainerCreating"
            }
          },
          "lastState": {},
          "ready": false,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": ""
        }
      ],
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "responseObject": {
    "kind": "Status",
    "apiVersion": "v1",
    "metadata": {},
    "status": "Failure",
    "message": "Operation cannot be fulfilled on pods \"dw-harn-pods\": the object has been modified; please apply your changes to the latest version and try again",
    "reason": "Conflict",
    "details": {
      "name": "dw-harn-pods",
      "kind": "pods"
    },
    "code": 409
  },
  "requestReceivedTimestamp": "2026-07-02T22:49:16.959389Z",
  "stageTimestamp": "2026-07-02T22:49:16.966869Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

patch pods/status

#
Resource
pods

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "00000000-0000-0000-0000-000000000000",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/dw-harn/pods/dw-harn-pods/status?fieldManager=kubectl-patch",
  "verb": "patch",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "pods",
    "namespace": "dw-harn",
    "name": "dw-harn-pods",
    "apiVersion": "v1",
    "subresource": "status"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "status": {
      "message": "dw-harn"
    }
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-pods",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1785",
      "generation": 2,
      "creationTimestamp": "2026-07-02T04:48:48Z",
      "labels": {
        "app": "dw-harn"
      }
    },
    "spec": {
      "volumes": [
        {
          "name": "kube-api-access-jx7nf",
          "projected": {
            "sources": [
              {
                "serviceAccountToken": {
                  "expirationSeconds": 3607,
                  "path": "token"
                }
              },
              {
                "configMap": {
                  "name": "kube-root-ca.crt",
                  "items": [
                    {
                      "key": "ca.crt",
                      "path": "ca.crt"
                    }
                  ]
                }
              },
              {
                "downwardAPI": {
                  "items": [
                    {
                      "path": "namespace",
                      "fieldRef": {
                        "apiVersion": "v1",
                        "fieldPath": "metadata.namespace"
                      }
                    }
                  ]
                }
              }
            ],
            "defaultMode": 420
          }
        }
      ],
      "containers": [
        {
          "name": "c",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "sh",
            "-c",
            "sleep 3600"
          ],
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-jx7nf",
              "readOnly": true,
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
            }
          ],
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent"
        }
      ],
      "ephemeralContainers": [
        {
          "name": "debugger-j4cpn",
          "image": "docker.io/library/busybox:1.36",
          "command": [
            "true"
          ],
          "resources": {},
          "terminationMessagePath": "/dev/termination-log",
          "terminationMessagePolicy": "File",
          "imagePullPolicy": "IfNotPresent",
          "securityContext": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ],
      "restartPolicy": "Always",
      "terminationGracePeriodSeconds": 0,
      "dnsPolicy": "ClusterFirst",
      "serviceAccountName": "default",
      "serviceAccount": "default",
      "nodeName": "node-control-plane",
      "securityContext": {},
      "schedulerName": "default-scheduler",
      "tolerations": [
        {
          "key": "node.kubernetes.io/not-ready",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        },
        {
          "key": "node.kubernetes.io/unreachable",
          "operator": "Exists",
          "effect": "NoExecute",
          "tolerationSeconds": 300
        }
      ],
      "priority": 0,
      "enableServiceLinks": true,
      "preemptionPolicy": "PreemptLowerPriority"
    },
    "status": {
      "observedGeneration": 2,
      "phase": "Running",
      "conditions": [
        {
          "type": "PodReadyToStartContainers",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "Initialized",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:48Z"
        },
        {
          "type": "Ready",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "ContainersReady",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:49Z"
        },
        {
          "type": "PodScheduled",
          "observedGeneration": 2,
          "status": "True",
          "lastProbeTime": null,
          "lastTransitionTime": "2026-07-02T04:48:48Z"
        }
      ],
      "message": "dw-harn",
      "hostIP": "172.19.0.2",
      "hostIPs": [
        {
          "ip": "172.19.0.2"
        }
      ],
      "podIP": "10.244.0.10",
      "podIPs": [
        {
          "ip": "10.244.0.10"
        }
      ],
      "startTime": "2026-07-02T04:48:48Z",
      "containerStatuses": [
        {
          "name": "c",
          "state": {
            "running": {
              "startedAt": "2026-07-02T04:48:49Z"
            }
          },
          "lastState": {},
          "ready": true,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": "docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
          "containerID": "containerd://cbb5514b60b38dcd34d9a3cd6d26f1f35a35af4f9a0abee6f98a0f1b682342c6",
          "started": true,
          "allocatedResources": {
            "cpu": "10m",
            "memory": "16Mi"
          },
          "resources": {
            "requests": {
              "cpu": "10m",
              "memory": "16Mi"
            }
          },
          "volumeMounts": [
            {
              "name": "kube-api-access-jx7nf",
              "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
              "readOnly": true,
              "recursiveReadOnly": "Disabled"
            }
          ],
          "user": {
            "linux": {
              "uid": 0,
              "gid": 0,
              "supplementalGroups": [
                0,
                10
              ]
            }
          }
        }
      ],
      "qosClass": "Burstable",
      "ephemeralContainerStatuses": [
        {
          "name": "debugger-j4cpn",
          "state": {
            "waiting": {
              "reason": "ContainerCreating"
            }
          },
          "lastState": {},
          "ready": false,
          "restartCount": 0,
          "image": "docker.io/library/busybox:1.36",
          "imageID": ""
        }
      ],
      "allocatedResources": {
        "cpu": "10m",
        "memory": "16Mi"
      },
      "resources": {
        "requests": {
          "memory": "16Mi"
        }
      }
    }
  },
  "requestReceivedTimestamp": "2026-07-02T04:48:57.594404Z",
  "stageTimestamp": "2026-07-02T04:48:57.599788Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
  }
}

References #

any verb on pods (synthetic aggregation)

#
Resource
pods

Description

Synthetic aggregation for rules that filter the pods resource with no specific verb. Not a distinct audit record; hosts rule listings that key on objectRef.resource alone.

Common Indicators #

Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.

FieldKindValueRulesVendors
kubernetes.audit.objectRef.resource (elastic rule field)innodes2 ruleselastic
kubernetes.audit.objectRef.resource (elastic rule field)inpods2 ruleselastic
EventType (elastic rule field)inget1 ruleelastic
EventType (elastic rule field)inlist1 ruleelastic

Detection Rules #

Full rule details for this event, including ATT&CK technique mappings and native queries →

Elastic #

  • Kubernetes Multi-Resource Discovery source medium: Adversaries who land credentials in a cluster—or abuse an over-privileged token—often map the environment before exfiltration or privilege escalation. A practical first pass is to learn where workloads run, how the cluster is partitioned, and what RBAC exists at namespace vs cluster scope. Rapid get/list traffic across distinct API resource kinds that answer those questions (namespaces, workloads, roles, cluster-wide roles) is a common setup and orientation pattern for both interactive attackers and automated recon scripts. It is less typical for steady-state controllers, which usually touch a narrow set of resources repeatedly. This rule highlights that cross-resource burst from a single client fingerprint within a one-minute bucket so analysts can separate routine automation from potential discovery and permission reconnaissance ahead of follow-on actions.T1613
  • Kubernetes Unusual Decision by User Agent source low: This rule detects unusual request responses in Kubernetes audit logs through the use of the "new_terms" rule type. In production environments, default API requests are typically made by system components or trusted users, who are expected to have a consistent user agent and allowed response annotations. By monitoring for anomalies in the username and response annotations, this rule helps identify potential unauthorized access or misconfigurations in the Kubernetes environment.T1078