Lesson 5 of 5 · 25 min read

Kubernetes Audit Logs — verb, resource, user, sourceIPs

Kubernetes audit logs are the control-plane telemetry for container orchestration — they record every API call to the kube-apiserver. In a Kubernetes environment, the API server is the single chokepoint for all cluster operations, making it the highest-value telemetry source.


Kubernetes Audit Log Structure

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "3da92f8d-8f31-4497-b6c2-54ff16948f7a",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/production/pods/webapi-7d9b8c-xk2np/exec",
  "verb": "create",
  "user": {
    "username": "attacker@victim.com",
    "uid": "12345678-abcd-...",
    "groups": ["system:authenticated"],
    "extra": {}
  },
  "impersonatedUser": null,
  "sourceIPs": ["203.0.113.55"],
  "userAgent": "kubectl/v1.28.0 (linux/amd64) kubernetes/abc123",
  "objectRef": {
    "resource": "pods",
    "namespace": "production",
    "name": "webapi-7d9b8c-xk2np",
    "apiVersion": "v1",
    "subresource": "exec"
  },
  "responseStatus": {
    "code": 101
  },
  "requestObject": {
    "stdin": true,
    "stdout": true,
    "tty": true,
    "container": "webapi",
    "command": ["/bin/bash"]
  },
  "timestamp": "2024-03-15T09:23:14.882Z"
}

Key fields for detection

FieldDetection use
verbWhat type of operation — exec, create, delete
user.usernameWho made the request
user.groupsGroup membership (system:masters = cluster-admin)
sourceIPsWhere the request came from
objectRef.resourceWhat type of resource (pods, secrets, configmaps)
objectRef.namespaceWhich namespace
objectRef.nameWhich specific resource
objectRef.subresourceexec, log, portforward — high-interest operations
responseStatus.code200/201=success, 401=unauth, 403=denied, 404=not found
requestObjectWhat was requested (command in exec, spec in create)

High-Priority Detection Patterns

1. Interactive Shell Execution (exec)

{
  "verb": "create",
  "objectRef": {"resource": "pods", "subresource": "exec"},
  "requestObject": {"command": ["/bin/bash"], "tty": true}
}

kubectl exec -it <pod> -- /bin/bash generates this. In production, there is almost no legitimate reason to exec an interactive shell into a running pod — operations should be automated, not interactive. This is a critical alert.

2. Secret Access

{
  "verb": "get",
  "objectRef": {"resource": "secrets", "namespace": "production", "name": "aws-credentials"},
  "user": {"username": "system:serviceaccount:default:compromised-sa"}
}

A service account in the default namespace reading a secret named aws-credentials in the production namespace — cross-namespace secret access is unusual and warrants investigation.

3. ClusterRoleBinding Creation (Privilege Escalation)

{
  "verb": "create",
  "objectRef": {"resource": "clusterrolebindings"},
  "requestObject": {
    "metadata": {"name": "backdoor-admin"},
    "roleRef": {"name": "cluster-admin"},
    "subjects": [{"kind": "User", "name": "attacker@victim.com"}]
  }
}

Creating a ClusterRoleBinding that grants cluster-admin to an external user is the Kubernetes equivalent of adding someone to the Domain Admins group. Immediate alert.


Configuring an Audit Policy

Without a policy, Kubernetes logs nothing. A production-grade minimal policy:

# /etc/kubernetes/audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # Don't log reads to health endpoints
  - level: None
    nonResourceURLs: ["/healthz", "/readyz", "/livez"]
  
  # Don't log kube-system service account activity (too noisy)
  - level: None
    userGroups: ["system:nodes"]
    verbs: ["get", "list", "watch"]
  
  # Log ALL exec and portforward at full detail
  - level: RequestResponse
    resources:
      - group: ""
        resources: ["pods/exec", "pods/portforward", "pods/log"]
  
  # Log secret access metadata (not content)
  - level: Metadata
    resources:
      - group: ""
        resources: ["secrets", "configmaps"]
  
  # Log all other writes
  - level: Metadata
    verbs: ["create", "update", "patch", "delete"]
  
  # Don't log read-only operations on non-sensitive resources
  - level: None
    verbs: ["get", "list", "watch"]
Kubernetes Auditing— Kubernetes Docs Falco Default Rules— CNCF Falco