Services

OperationDescriptionSampleRule
get-servicesYN
list-servicesYN
watch-servicesYN
create-servicesService created (NodePort/LoadBalancer exposure = persistence or C2 channel).YY
update-servicesChanges an existing Service, e.g. switching its type to NodePort for external exposure. Elastic covers update alongside create and patch.YY
patch-servicesSame NodePort exposure signal as update, via patch, applied to an already-approved Service rather than a new, more visible one.YY
delete-servicesYY
deletecollection-servicesYN
get-services-proxyNN
create-services-proxyNN
update-services-proxyNN
patch-services-proxyNN
delete-services-proxyNN
get-services-statusYN
update-services-statusYN
patch-services-statusYN
any-servicesSynthetic aggregation for rules that filter the services resource with no specific verb. Not a distinct audit record; hosts rule listings that key on objectRef.resource alone.NN

get services

#
Resource
services

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/services/dw-harn-services",
  "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": "services",
    "namespace": "dw-harn",
    "name": "dw-harn-services",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:47:04.318724Z",
  "stageTimestamp": "2026-07-02T04:47:04.320323Z",
  "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 #

list services

#
Resource
services

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/services?limit=500&timeout=3s",
  "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": "services",
    "namespace": "dw-harn",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:47:04.445621Z",
  "stageTimestamp": "2026-07-02T04:47:04.449541Z",
  "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 #

watch services

#
Resource
services

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/services?resourceVersion=1404&timeout=3s&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": "services",
    "namespace": "dw-harn",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T04:47:04.451062Z",
  "stageTimestamp": "2026-07-02T04:47:07.452795Z",
  "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 #

create services

#
Resource
services

Description

Service created (NodePort/LoadBalancer exposure = persistence or C2 channel).

Example Audit Event #

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "bf70c113-4df3-407e-8804-6c9363498fe0",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/default/services?fieldManager=kubectl-client-side-apply&fieldValidation=Strict",
  "verb": "create",
  "user": {
    "username": "kubernetes-admin",
    "uid": "aws-iam-authenticator:591511147606:AIDAYTOGP2RLJGRCUIGJZ",
    "groups": [
      "system:masters",
      "system:authenticated"
    ]
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.27.2 (darwin/arm64) kubernetes/7f6f68f",
  "objectRef": {
    "resource": "services",
    "namespace": "default",
    "name": "nginx",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 201
  },
  "requestObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "nginx",
      "namespace": "default",
      "creationTimestamp": null,
      "labels": {
        "name": "nginx"
      },
      "annotations": {
        "kubectl.kubernetes.io/last-applied-configuration": {
          "apiVersion": "v1",
          "kind": "Service",
          "metadata": {
            "annotations": {},
            "labels": {
              "name": "nginx"
            },
            "name": "nginx",
            "namespace": "default"
          },
          "spec": {
            "ports": [
              {
                "name": "http",
                "nodePort": 30080,
                "port": 80
              }
            ],
            "selector": {
              "name": "nginx"
            },
            "type": "NodePort"
          }
        }
      }
    },
    "spec": {
      "ports": [
        {
          "name": "http",
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80,
          "nodePort": 30080
        }
      ],
      "selector": {
        "name": "nginx"
      },
      "type": "NodePort",
      "sessionAffinity": "None",
      "externalTrafficPolicy": "Cluster",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "responseObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "nginx",
      "namespace": "default",
      "uid": "f5348e0d-31d1-4407-9114-ca124798397b",
      "resourceVersion": "2618495",
      "creationTimestamp": "2023-12-13T16:12:47Z",
      "labels": {
        "name": "nginx"
      },
      "annotations": {
        "kubectl.kubernetes.io/last-applied-configuration": {
          "apiVersion": "v1",
          "kind": "Service",
          "metadata": {
            "annotations": {},
            "labels": {
              "name": "nginx"
            },
            "name": "nginx",
            "namespace": "default"
          },
          "spec": {
            "ports": [
              {
                "name": "http",
                "nodePort": 30080,
                "port": 80
              }
            ],
            "selector": {
              "name": "nginx"
            },
            "type": "NodePort"
          }
        }
      }
    },
    "spec": {
      "ports": [
        {
          "name": "http",
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80,
          "nodePort": 30080
        }
      ],
      "selector": {
        "name": "nginx"
      },
      "clusterIP": "10.100.131.54",
      "clusterIPs": [
        "10.100.131.54"
      ],
      "type": "NodePort",
      "sessionAffinity": "None",
      "externalTrafficPolicy": "Cluster",
      "ipFamilies": [
        "IPv4"
      ],
      "ipFamilyPolicy": "SingleStack",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "requestReceivedTimestamp": "2023-12-13T16:12:47.977900Z",
  "stageTimestamp": "2023-12-13T16:12:48.027898Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": ""
  }
}

Common Indicators #

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

FieldKindValueRulesVendors
verbeqcreate4 rulesfalco, panther, splunk
objectRef.resourceeqservices3 rulesfalco, splunk
stage (falco rule field)eqresponsecomplete2 rulesfalco

Detection Rules #

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

Elastic #

  • GKE Exposed Service Created With Type NodePort source medium: Detects creation or modification of a GKE Service with type NodePort. NodePort exposes a static port on every worker node that hosts matching pods, which widens the cluster's external attack surface and can bypass load-balancer and firewall controls. Attackers may create NodePort Services to intercept traffic or establish a direct path into the cluster.T1133↳ also matches update-services: update services, patch-services: patch services
    Investigation guide

    Triage and analysis#

    Investigating GKE Exposed Service Created With Type NodePort#

    NodePort opens a port on each worker node hosting the service and forwards external traffic to labeled pods. Confirm whether the exposure was approved and which workloads are reachable.

    Possible investigation steps#

    • Review client.user.email, source.ip, and user_agent.original.
    • Inspect gcp.audit.resource_name and gcp.audit.request for the service name, namespace, selector, and port.
    • Identify the backing pods and whether the NodePort is required for a legitimate external entrypoint.
    • Correlate with recent Service or networking changes from the same actor.

    False positive analysis#

    • Approved NodePort Services for lab frontends or custom load balancing may match. Allowlist known automation or namespaces after review.
    • GKE addon reconciliation via system:addon-manager patch is excluded; unexpected create or update from that actor should still be investigated.

    Response and remediation#

    • Remove or change unauthorized NodePort Services, revoke excess RBAC for Services writes, and review firewall exposure for the opened node ports.
  • Kubernetes Exposed Service Created With Type NodePort source medium: This rule detects an attempt to create or modify a service as type NodePort. The NodePort service allows a user to externally expose a set of labeled pods to the internet. This creates an open port on every worker node in the cluster that has a pod for that service. When external traffic is received on that open port, it directs it to the specific pod through the service representing it. A malicious user can configure a service as type Nodeport in order to intercept traffic from other pods or nodes, bypassing firewalls and other network security measures configured for load balancers within a cluster. This creates a direct method of communication between the cluster and the outside world, which could be used for more malicious behavior and certainly widens the attack surface of your cluster.T1133↳ also matches update-services: update services, patch-services: patch services
    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 Exposed Service Created With Type NodePort#

    Kubernetes NodePort services enable external access to cluster pods by opening a port on each worker node. This can be exploited by attackers to bypass network security, intercept traffic, or establish unauthorized communication channels. The detection rule identifies suspicious NodePort service creation or modification by monitoring Kubernetes audit logs for specific actions and authorization decisions, helping to mitigate potential security risks.

    Possible investigation steps#

    • Review the Kubernetes audit logs to identify the specific service that was created or modified with the type NodePort. Focus on entries where kubernetes.audit.objectRef.resource is "services" and kubernetes.audit.verb is "create", "update", or "patch".
    • Check the kubernetes.audit.annotations.authorization_k8s_io/decision field to confirm that the action was allowed, ensuring that the service creation or modification was authorized.
    • Identify the user or service account responsible for the action by examining the relevant fields in the audit logs, such as the user identity or service account name.
    • Investigate the context of the NodePort service by reviewing the associated pods and their labels to understand what applications or services are being exposed externally.
    • Assess the network security implications by determining if the NodePort service could potentially bypass existing firewalls or security controls, and evaluate the risk of unauthorized access or data interception.
    • Verify if the NodePort service is necessary for legitimate business purposes or if it was created without proper justification, indicating potential malicious intent.

    False positive analysis#

    • Routine service updates or deployments may trigger the rule if NodePort services are part of standard operations. To manage this, create exceptions for specific namespaces or service accounts that are known to perform these actions regularly.
    • Development or testing environments often use NodePort services for ease of access. Exclude these environments from the rule by filtering based on labels or annotations that identify non-production clusters.
    • Automated deployment tools or scripts that configure services as NodePort for legitimate reasons can cause false positives. Identify these tools and add their service accounts to an exception list to prevent unnecessary alerts.
    • Internal services that require external access for legitimate business needs might be flagged. Document these services and apply exceptions based on their specific labels or annotations to avoid false alarms.
    • Temporary configurations during incident response or troubleshooting might involve NodePort services. Ensure that these activities are logged and approved, and consider temporary exceptions during the incident resolution period.

    Response and remediation#

    • Immediately isolate the affected NodePort service by removing or disabling it to prevent further unauthorized access or traffic interception.
    • Review and revoke any unauthorized access or permissions granted to users or service accounts that created or modified the NodePort service.
    • Conduct a thorough audit of network traffic logs to identify any suspicious or unauthorized external connections made through the NodePort service.
    • Implement network segmentation and firewall rules to restrict external access to critical services and ensure that only necessary ports are exposed.
    • Escalate the incident to the security operations team for further investigation and to assess potential impacts on the cluster's security posture.
    • Apply security patches and updates to Kubernetes components and worker nodes to mitigate any known vulnerabilities that could be exploited.
    • Enhance monitoring and alerting mechanisms to detect future unauthorized NodePort service creations or modifications promptly.

    Setup#

    The Kubernetes Fleet integration with Audit Logs enabled or similarly structured data is required to be compatible with this rule.

Splunk #

  • Kubernetes Node Port Creation source: The following analytic detects the creation of a Kubernetes NodePort service, which exposes a service to the external network. It identifies this activity by monitoring Kubernetes Audit logs for the creation of NodePort services. This…T1204

Panther #

  • GCP K8S Service Type NodePort Deployed source high: This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to the outside network.T1190
  • Kubernetes NodePort Service Deployed source high: This detection monitors for any Kubernetes service deployed with type NodePort. A NodePort service allows an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to the outside network.T1190
  • Kubernetes Service with Type Node Port Deployed source medium linked query: Kubernetes Service with Type Node Port Deployed: This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to the outside network.

Falco #

References #

update services

#
Resource
services

Description

Changes an existing Service, e.g. switching its type to NodePort for external exposure. Elastic covers update alongside create and patch.

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/services/dw-harn-services?fieldManager=kubectl-replace&fieldValidation=Strict",
  "verb": "update",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=4cf95d11cbd90036bab41cdc6b88cc8f91550e9135ed4bb61495b02f647812ff"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "services",
    "namespace": "dw-harn",
    "name": "dw-harn-services",
    "uid": "00000000-0000-0000-0000-000000000000",
    "apiVersion": "v1",
    "resourceVersion": "555"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-services",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "555",
      "creationTimestamp": "2026-07-02T21:30:27Z",
      "labels": {
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "ports": [
        {
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80
        }
      ],
      "selector": {
        "app": "dw-harn"
      },
      "clusterIP": "10.96.242.55",
      "clusterIPs": [
        "10.96.242.55"
      ],
      "type": "ClusterIP",
      "sessionAffinity": "None",
      "ipFamilies": [
        "IPv4"
      ],
      "ipFamilyPolicy": "SingleStack",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "responseObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-services",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "555",
      "creationTimestamp": "2026-07-02T21:30:27Z",
      "labels": {
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "ports": [
        {
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80
        }
      ],
      "selector": {
        "app": "dw-harn"
      },
      "clusterIP": "10.96.242.55",
      "clusterIPs": [
        "10.96.242.55"
      ],
      "type": "ClusterIP",
      "sessionAffinity": "None",
      "ipFamilies": [
        "IPv4"
      ],
      "ipFamilyPolicy": "SingleStack",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "requestReceivedTimestamp": "2026-07-02T21:30:31.122255Z",
  "stageTimestamp": "2026-07-02T21:30:31.125073Z",
  "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 #

  • GKE Exposed Service Created With Type NodePort source medium: Detects creation or modification of a GKE Service with type NodePort. NodePort exposes a static port on every worker node that hosts matching pods, which widens the cluster's external attack surface and can bypass load-balancer and firewall controls. Attackers may create NodePort Services to intercept traffic or establish a direct path into the cluster.T1133↳ also matches create-services: create services, patch-services: patch services
    Investigation guide

    Triage and analysis#

    Investigating GKE Exposed Service Created With Type NodePort#

    NodePort opens a port on each worker node hosting the service and forwards external traffic to labeled pods. Confirm whether the exposure was approved and which workloads are reachable.

    Possible investigation steps#

    • Review client.user.email, source.ip, and user_agent.original.
    • Inspect gcp.audit.resource_name and gcp.audit.request for the service name, namespace, selector, and port.
    • Identify the backing pods and whether the NodePort is required for a legitimate external entrypoint.
    • Correlate with recent Service or networking changes from the same actor.

    False positive analysis#

    • Approved NodePort Services for lab frontends or custom load balancing may match. Allowlist known automation or namespaces after review.
    • GKE addon reconciliation via system:addon-manager patch is excluded; unexpected create or update from that actor should still be investigated.

    Response and remediation#

    • Remove or change unauthorized NodePort Services, revoke excess RBAC for Services writes, and review firewall exposure for the opened node ports.
  • Kubernetes Exposed Service Created With Type NodePort source medium: This rule detects an attempt to create or modify a service as type NodePort. The NodePort service allows a user to externally expose a set of labeled pods to the internet. This creates an open port on every worker node in the cluster that has a pod for that service. When external traffic is received on that open port, it directs it to the specific pod through the service representing it. A malicious user can configure a service as type Nodeport in order to intercept traffic from other pods or nodes, bypassing firewalls and other network security measures configured for load balancers within a cluster. This creates a direct method of communication between the cluster and the outside world, which could be used for more malicious behavior and certainly widens the attack surface of your cluster.T1133↳ also matches create-services: create services, patch-services: patch services
    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 Exposed Service Created With Type NodePort#

    Kubernetes NodePort services enable external access to cluster pods by opening a port on each worker node. This can be exploited by attackers to bypass network security, intercept traffic, or establish unauthorized communication channels. The detection rule identifies suspicious NodePort service creation or modification by monitoring Kubernetes audit logs for specific actions and authorization decisions, helping to mitigate potential security risks.

    Possible investigation steps#

    • Review the Kubernetes audit logs to identify the specific service that was created or modified with the type NodePort. Focus on entries where kubernetes.audit.objectRef.resource is "services" and kubernetes.audit.verb is "create", "update", or "patch".
    • Check the kubernetes.audit.annotations.authorization_k8s_io/decision field to confirm that the action was allowed, ensuring that the service creation or modification was authorized.
    • Identify the user or service account responsible for the action by examining the relevant fields in the audit logs, such as the user identity or service account name.
    • Investigate the context of the NodePort service by reviewing the associated pods and their labels to understand what applications or services are being exposed externally.
    • Assess the network security implications by determining if the NodePort service could potentially bypass existing firewalls or security controls, and evaluate the risk of unauthorized access or data interception.
    • Verify if the NodePort service is necessary for legitimate business purposes or if it was created without proper justification, indicating potential malicious intent.

    False positive analysis#

    • Routine service updates or deployments may trigger the rule if NodePort services are part of standard operations. To manage this, create exceptions for specific namespaces or service accounts that are known to perform these actions regularly.
    • Development or testing environments often use NodePort services for ease of access. Exclude these environments from the rule by filtering based on labels or annotations that identify non-production clusters.
    • Automated deployment tools or scripts that configure services as NodePort for legitimate reasons can cause false positives. Identify these tools and add their service accounts to an exception list to prevent unnecessary alerts.
    • Internal services that require external access for legitimate business needs might be flagged. Document these services and apply exceptions based on their specific labels or annotations to avoid false alarms.
    • Temporary configurations during incident response or troubleshooting might involve NodePort services. Ensure that these activities are logged and approved, and consider temporary exceptions during the incident resolution period.

    Response and remediation#

    • Immediately isolate the affected NodePort service by removing or disabling it to prevent further unauthorized access or traffic interception.
    • Review and revoke any unauthorized access or permissions granted to users or service accounts that created or modified the NodePort service.
    • Conduct a thorough audit of network traffic logs to identify any suspicious or unauthorized external connections made through the NodePort service.
    • Implement network segmentation and firewall rules to restrict external access to critical services and ensure that only necessary ports are exposed.
    • Escalate the incident to the security operations team for further investigation and to assess potential impacts on the cluster's security posture.
    • Apply security patches and updates to Kubernetes components and worker nodes to mitigate any known vulnerabilities that could be exploited.
    • Enhance monitoring and alerting mechanisms to detect future unauthorized NodePort service creations or modifications promptly.

    Setup#

    The Kubernetes Fleet integration with Audit Logs enabled or similarly structured data is required to be compatible with this rule.

References #

patch services

#
Resource
services

Description

Same NodePort exposure signal as update, via patch, applied to an already-approved Service rather than a new, more visible one.

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/services/dw-harn-services?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": "services",
    "namespace": "dw-harn",
    "name": "dw-harn-services",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "metadata": {
      "labels": {
        "dw-harn-patched": "1"
      }
    }
  },
  "responseObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-services",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1412",
      "creationTimestamp": "2026-07-02T04:47:04Z",
      "labels": {
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "ports": [
        {
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80
        }
      ],
      "selector": {
        "app": "dw-harn"
      },
      "clusterIP": "10.96.31.22",
      "clusterIPs": [
        "10.96.31.22"
      ],
      "type": "ClusterIP",
      "sessionAffinity": "None",
      "ipFamilies": [
        "IPv4"
      ],
      "ipFamilyPolicy": "SingleStack",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "requestReceivedTimestamp": "2026-07-02T04:47:07.529860Z",
  "stageTimestamp": "2026-07-02T04:47:07.535873Z",
  "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 #

  • GKE Exposed Service Created With Type NodePort source medium: Detects creation or modification of a GKE Service with type NodePort. NodePort exposes a static port on every worker node that hosts matching pods, which widens the cluster's external attack surface and can bypass load-balancer and firewall controls. Attackers may create NodePort Services to intercept traffic or establish a direct path into the cluster.T1133↳ also matches create-services: create services, update-services: update services
    Investigation guide

    Triage and analysis#

    Investigating GKE Exposed Service Created With Type NodePort#

    NodePort opens a port on each worker node hosting the service and forwards external traffic to labeled pods. Confirm whether the exposure was approved and which workloads are reachable.

    Possible investigation steps#

    • Review client.user.email, source.ip, and user_agent.original.
    • Inspect gcp.audit.resource_name and gcp.audit.request for the service name, namespace, selector, and port.
    • Identify the backing pods and whether the NodePort is required for a legitimate external entrypoint.
    • Correlate with recent Service or networking changes from the same actor.

    False positive analysis#

    • Approved NodePort Services for lab frontends or custom load balancing may match. Allowlist known automation or namespaces after review.
    • GKE addon reconciliation via system:addon-manager patch is excluded; unexpected create or update from that actor should still be investigated.

    Response and remediation#

    • Remove or change unauthorized NodePort Services, revoke excess RBAC for Services writes, and review firewall exposure for the opened node ports.
  • Kubernetes Exposed Service Created With Type NodePort source medium: This rule detects an attempt to create or modify a service as type NodePort. The NodePort service allows a user to externally expose a set of labeled pods to the internet. This creates an open port on every worker node in the cluster that has a pod for that service. When external traffic is received on that open port, it directs it to the specific pod through the service representing it. A malicious user can configure a service as type Nodeport in order to intercept traffic from other pods or nodes, bypassing firewalls and other network security measures configured for load balancers within a cluster. This creates a direct method of communication between the cluster and the outside world, which could be used for more malicious behavior and certainly widens the attack surface of your cluster.T1133↳ also matches create-services: create services, update-services: update services
    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 Exposed Service Created With Type NodePort#

    Kubernetes NodePort services enable external access to cluster pods by opening a port on each worker node. This can be exploited by attackers to bypass network security, intercept traffic, or establish unauthorized communication channels. The detection rule identifies suspicious NodePort service creation or modification by monitoring Kubernetes audit logs for specific actions and authorization decisions, helping to mitigate potential security risks.

    Possible investigation steps#

    • Review the Kubernetes audit logs to identify the specific service that was created or modified with the type NodePort. Focus on entries where kubernetes.audit.objectRef.resource is "services" and kubernetes.audit.verb is "create", "update", or "patch".
    • Check the kubernetes.audit.annotations.authorization_k8s_io/decision field to confirm that the action was allowed, ensuring that the service creation or modification was authorized.
    • Identify the user or service account responsible for the action by examining the relevant fields in the audit logs, such as the user identity or service account name.
    • Investigate the context of the NodePort service by reviewing the associated pods and their labels to understand what applications or services are being exposed externally.
    • Assess the network security implications by determining if the NodePort service could potentially bypass existing firewalls or security controls, and evaluate the risk of unauthorized access or data interception.
    • Verify if the NodePort service is necessary for legitimate business purposes or if it was created without proper justification, indicating potential malicious intent.

    False positive analysis#

    • Routine service updates or deployments may trigger the rule if NodePort services are part of standard operations. To manage this, create exceptions for specific namespaces or service accounts that are known to perform these actions regularly.
    • Development or testing environments often use NodePort services for ease of access. Exclude these environments from the rule by filtering based on labels or annotations that identify non-production clusters.
    • Automated deployment tools or scripts that configure services as NodePort for legitimate reasons can cause false positives. Identify these tools and add their service accounts to an exception list to prevent unnecessary alerts.
    • Internal services that require external access for legitimate business needs might be flagged. Document these services and apply exceptions based on their specific labels or annotations to avoid false alarms.
    • Temporary configurations during incident response or troubleshooting might involve NodePort services. Ensure that these activities are logged and approved, and consider temporary exceptions during the incident resolution period.

    Response and remediation#

    • Immediately isolate the affected NodePort service by removing or disabling it to prevent further unauthorized access or traffic interception.
    • Review and revoke any unauthorized access or permissions granted to users or service accounts that created or modified the NodePort service.
    • Conduct a thorough audit of network traffic logs to identify any suspicious or unauthorized external connections made through the NodePort service.
    • Implement network segmentation and firewall rules to restrict external access to critical services and ensure that only necessary ports are exposed.
    • Escalate the incident to the security operations team for further investigation and to assess potential impacts on the cluster's security posture.
    • Apply security patches and updates to Kubernetes components and worker nodes to mitigate any known vulnerabilities that could be exploited.
    • Enhance monitoring and alerting mechanisms to detect future unauthorized NodePort service creations or modifications promptly.

    Setup#

    The Kubernetes Fleet integration with Audit Logs enabled or similarly structured data is required to be compatible with this rule.

References #

delete services

#
Resource
services

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/services/dw-harn-services",
  "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": "services",
    "namespace": "dw-harn",
    "name": "dw-harn-services",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "kind": "DeleteOptions",
    "apiVersion": "meta.k8s.io/__internal",
    "propagationPolicy": "Background"
  },
  "responseObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-services",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "1415",
      "creationTimestamp": "2026-07-02T04:47:04Z",
      "labels": {
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "ports": [
        {
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80
        }
      ],
      "selector": {
        "app": "dw-harn"
      },
      "clusterIP": "10.96.31.22",
      "clusterIPs": [
        "10.96.31.22"
      ],
      "type": "ClusterIP",
      "sessionAffinity": "None",
      "ipFamilies": [
        "IPv4"
      ],
      "ipFamilyPolicy": "SingleStack",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "requestReceivedTimestamp": "2026-07-02T04:47:07.600969Z",
  "stageTimestamp": "2026-07-02T04:47:07.609602Z",
  "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 (falco rule field)eqservices1 rulefalco

Detection Rules #

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

Falco #

References #

deletecollection services

#
Resource
services

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/services?labelSelector=dw-harn-patched",
  "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": "services",
    "namespace": "dw-harn",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "responseObject": {
    "kind": "ServiceList",
    "apiVersion": "v1",
    "metadata": {
      "resourceVersion": "629"
    },
    "items": [
      {
        "metadata": {
          "name": "dw-harn-services",
          "namespace": "dw-harn",
          "uid": "00000000-0000-0000-0000-000000000000",
          "resourceVersion": "625",
          "creationTimestamp": "2026-07-02T23:12:28Z",
          "labels": {
            "dw-harn-patched": "1"
          }
        },
        "spec": {
          "ports": [
            {
              "protocol": "TCP",
              "port": 80,
              "targetPort": 80
            }
          ],
          "selector": {
            "app": "dw-harn"
          },
          "clusterIP": "10.96.89.6",
          "clusterIPs": [
            "10.96.89.6"
          ],
          "type": "ClusterIP",
          "sessionAffinity": "None",
          "ipFamilies": [
            "IPv4"
          ],
          "ipFamilyPolicy": "SingleStack",
          "internalTrafficPolicy": "Cluster"
        },
        "status": {
          "loadBalancer": {}
        }
      }
    ]
  },
  "requestReceivedTimestamp": "2026-07-02T23:12:31.886267Z",
  "stageTimestamp": "2026-07-02T23:12:31.897848Z",
  "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 services/proxy

#
Resource
services

create services/proxy

#
Resource
services

update services/proxy

#
Resource
services

patch services/proxy

#
Resource
services

delete services/proxy

#
Resource
services

get services/status

#
Resource
services

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/services/dw-harn-services/status",
  "verb": "get",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=4cf95d11cbd90036bab41cdc6b88cc8f91550e9135ed4bb61495b02f647812ff"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "services",
    "namespace": "dw-harn",
    "name": "dw-harn-services",
    "apiVersion": "v1",
    "subresource": "status"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestReceivedTimestamp": "2026-07-02T21:30:31.191721Z",
  "stageTimestamp": "2026-07-02T21:30:31.193245Z",
  "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 services/status

#
Resource
services

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/services/dw-harn-services/status?fieldManager=kubectl-replace&fieldValidation=Strict",
  "verb": "update",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=4cf95d11cbd90036bab41cdc6b88cc8f91550e9135ed4bb61495b02f647812ff"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "services",
    "namespace": "dw-harn",
    "name": "dw-harn-services",
    "uid": "00000000-0000-0000-0000-000000000000",
    "apiVersion": "v1",
    "resourceVersion": "555",
    "subresource": "status"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-services",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "555",
      "creationTimestamp": "2026-07-02T21:30:27Z",
      "labels": {
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "ports": [
        {
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80
        }
      ],
      "selector": {
        "app": "dw-harn"
      },
      "clusterIP": "10.96.242.55",
      "clusterIPs": [
        "10.96.242.55"
      ],
      "type": "ClusterIP",
      "sessionAffinity": "None",
      "ipFamilies": [
        "IPv4"
      ],
      "ipFamilyPolicy": "SingleStack",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "responseObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-services",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "555",
      "creationTimestamp": "2026-07-02T21:30:27Z",
      "labels": {
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "ports": [
        {
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80
        }
      ],
      "selector": {
        "app": "dw-harn"
      },
      "clusterIP": "10.96.242.55",
      "clusterIPs": [
        "10.96.242.55"
      ],
      "type": "ClusterIP",
      "sessionAffinity": "None",
      "ipFamilies": [
        "IPv4"
      ],
      "ipFamilyPolicy": "SingleStack",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "requestReceivedTimestamp": "2026-07-02T21:30:31.323280Z",
  "stageTimestamp": "2026-07-02T21:30:31.326314Z",
  "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 services/status

#
Resource
services

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/services/dw-harn-services/status?fieldManager=kubectl-patch",
  "verb": "patch",
  "user": {
    "username": "kubernetes-admin",
    "groups": [
      "kubeadm:cluster-admins",
      "system:authenticated"
    ],
    "extra": {
      "authentication.kubernetes.io/credential-id": [
        "X509SHA256=786fc563dbb253683c44d23d0aac3742ea61ade7f27a43f50934a82662e15409"
      ]
    }
  },
  "sourceIPs": [
    "203.0.113.10"
  ],
  "userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
  "objectRef": {
    "resource": "services",
    "namespace": "dw-harn",
    "name": "dw-harn-services",
    "apiVersion": "v1",
    "subresource": "status"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "requestObject": {},
  "responseObject": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "dw-harn-services",
      "namespace": "dw-harn",
      "uid": "00000000-0000-0000-0000-000000000000",
      "resourceVersion": "557",
      "creationTimestamp": "2026-07-02T22:17:08Z",
      "labels": {
        "dw-harn-patched": "1"
      }
    },
    "spec": {
      "ports": [
        {
          "protocol": "TCP",
          "port": 80,
          "targetPort": 80
        }
      ],
      "selector": {
        "app": "dw-harn"
      },
      "clusterIP": "10.96.151.58",
      "clusterIPs": [
        "10.96.151.58"
      ],
      "type": "ClusterIP",
      "sessionAffinity": "None",
      "ipFamilies": [
        "IPv4"
      ],
      "ipFamilyPolicy": "SingleStack",
      "internalTrafficPolicy": "Cluster"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "requestReceivedTimestamp": "2026-07-02T22:17:11.939864Z",
  "stageTimestamp": "2026-07-02T22:17:11.941957Z",
  "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 services (synthetic aggregation)

#
Resource
services

Description

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