← Back to Blog
DevSecOps Advanced 19 min

Kubernetes Runtime Threat Defense: Pod Security Standards, Calico Policies & Falco eBPF Detection

Mastering production Kubernetes security: Pod Security Standards (Restricted), Calico zero-trust NetworkPolicies, admission controller enforcement with Kyverno, and Falco eBPF kernel runtime monitoring.

KubernetesContainer SecurityFalcoeBPFCalicoDevSecOpsRBAC
Kubernetes Runtime Threat Defense and Hardening Architecture

Kubernetes simplifies container orchestration at massive scale, but default clusters prioritize developer convenience over security. Permissive Linux capabilities (CAP_SYS_ADMIN), unsegmented pod-to-pod flat networks, writable root filesystems, and unauthenticated kubelet ports expose clusters to catastrophic container escapes and lateral infrastructure compromise.

This guide details how to harden production Kubernetes clusters from the Linux kernel layer up to the API Server.


1. Kubernetes Attack Surface & Defensive Matrix

+-------------------------------------------------------------------------+
|                  KUBERNETES LAYERED DEFENSE IN DEPTH                    |
+-------------------------------------------------------------------------+
|                                                                         |
|  [LAYER 1: API SERVER]   --> Strict RBAC, Disable Anonymous, Audit Log  |
|  [LAYER 2: ADMISSION]    --> Kyverno / OPA Gatekeeper Validating Webhooks|
|  [LAYER 3: POD RUNTIME]  --> Pod Security Standards (Restricted Profile)|
|  [LAYER 4: NETWORK]      --> Calico Default-Deny Ingress/Egress Policies|
|  [LAYER 5: KERNEL/eBPF]  --> Falco Real-Time Syscall Behavioral Alerts  |
|                                                                         |
+-------------------------------------------------------------------------+

2. Pod Security Standards: Enforcing the Restricted Baseline

Pod Security Admission (PSA) enforces built-in security profiles at the namespace level: Privileged, Baseline, and Restricted.

Namespace-Level Enforcement (namespace.yaml):

apiVersion: v1
kind: Namespace
metadata:
  name: production-workloads
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/audit: restricted

Production-Hardened Pod Specification (deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hardened-api-service
  namespace: production-workloads
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-service
  template:
    metadata:
      labels:
        app: api-service
    spec:
      # Isolate Service Account Token
      automountServiceAccountToken: false
      securityContext:
        runAsNonRoot: true
        runAsUser: 10001
        runAsGroup: 10001
        fsGroup: 10001
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: app
          image: ghcr.io/dynamo2k1/api-service:v2.4.0@sha256:7f83b1c9...
          imagePullPolicy: IfNotPresent
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
          resources:
            limits:
              cpu: "500m"
              memory: "512Mi"
            requests:
              cpu: "100m"
              memory: "128Mi"
          volumeMounts:
            - name: tmp-storage
              mountPath: /tmp
      volumes:
        - name: tmp-storage
          emptyDir:
            medium: Memory
            sizeLimit: "64Mi"

3. Calico Zero-Trust NetworkPolicies: Default-Deny Architecture

By default, any pod in a Kubernetes cluster can communicate with any other pod across all namespaces. Implement an explicit Default-Deny All Ingress and Egress policy:

# 1. Global Default-Deny for Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production-workloads
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
# 2. Explicit Ingress/Egress Whitelist for API Service
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-service-traffic
  namespace: production-workloads
spec:
  podSelector:
    matchLabels:
      app: api-service
  policyTypes:
    - Ingress
    - Egress
  ingress:
    # Allow traffic ONLY from Ingress Controller on Port 8080
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
      ports:
        - protocol: TCP
          port: 8080
  egress:
    # Allow DNS queries to CoreDNS
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
    # Allow egress ONLY to Internal PostgreSQL Database
    - to:
        - podSelector:
            matchLabels:
              app: postgres-db
      ports:
        - protocol: TCP
          port: 5432

4. Real-Time Runtime Threat Detection with Falco (eBPF)

Falco taps into Linux kernel system calls via eBPF probes to detect anomalous container activities in real time (e.g. interactive shell spawns, sensitive /etc writes, unexpected outbound network connections).

Custom Falco Threat Detection Rule (falco_rules.local.yaml):

- rule: Terminal Shell Spawned in Production Container
  desc: Detect interactive shell execution inside a live container (Mitre T1059)
  condition: >
    container.id != host and
    spawned_process and
    proc.name in (bash, sh, zsh, ksh, ash) and
    container.image.repository not in (troubleshooting-debug-tools)
  output: >
    ALERT: Shell spawned inside container (user=%user.name user_loginuid=%user.loginuid
    process=%proc.name parent=%proc.pname cmdline=%proc.cmdline
    container_id=%container.id container_name=%container.name image=%container.image.repository)
  priority: CRITICAL
  tags: [container, mitre_execution, pci_dss_10.2]

- rule: Sensitive File Written Inside Container
  desc: Detect tampering with critical system binaries or configs
  condition: >
    open_write and
    container.id != host and
    fd.name startswith /etc/ or fd.name startswith /bin/ or fd.name startswith /usr/bin/
  output: >
    ALERT: Critical path write attempt inside container (file=%fd.name process=%proc.name
    container=%container.name user=%user.name)
  priority: HIGH
  tags: [container, filesystem, defense_evasion]

5. Kubernetes Hardening Verification Checklist

# 1. Audit RBAC Permissions for Privilege Escalation Vectors
kubectl auth can-i create pods --as system:serviceaccount:default:my-sa -n production-workloads

# 2. Run Automated CIS Kubernetes Benchmark
kube-bench run --targets master,node,etcd,policies

# 3. Test Network Policy Isolation (Must Timeout)
kubectl exec -it test-pod -n production-workloads -- nc -zv 10.0.100.50 80

// Discussion

Enjoyed this? Let us work together.

Available for Security Engineering, DevSecOps, and Penetration Testing engagements.