Build an AI Runtime Anomaly Detector for Kubernetes with Claude API and eBPF
eBPF gives you a live syscall-level view of what's happening inside every container. Build a tool that feeds that stream through Claude API to catch anomalous process behavior — crypto miners, reverse shells, unexpected file access — that signature-based tools miss.
Signature-based runtime security tools (rule "if process X spawns process Y, alert") catch known attack patterns and miss everything novel. eBPF gives you the raw syscall stream — process execs, network connections, file access — for every container in real time. This tool feeds behavioral summaries of that stream through Claude to catch what a signature can't: genuinely novel or subtly disguised anomalous behavior.
Architecture
Container syscalls → eBPF probe (Tetragon/Falco) → structured events
↓
Behavioral summarizer (batches events per pod)
↓
Claude reasons over the behavior pattern
↓
"normal" / "suspicious" / "malicious" + evidence
eBPF Event Collection (via Tetragon)
# TracingPolicy — capture process execs and network connections per pod
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: runtime-behavior-monitor
spec:
kprobes:
- call: "sys_execve"
syscall: true
args:
- index: 0
type: "string"
- call: "tcp_connect"
syscall: false
args:
- index: 0
type: "sock"import json
import subprocess
from collections import defaultdict
def stream_tetragon_events():
"""Consume the Tetragon gRPC/JSON event stream."""
proc = subprocess.Popen(
["tetra", "getevents", "-o", "json"],
stdout=subprocess.PIPE, text=True
)
for line in proc.stdout:
yield json.loads(line)Behavioral Summarization — Don't Send Raw Events to Claude
Raw syscall streams are enormous and mostly noise — the summarization step is what makes this tractable and cheap.
def summarize_pod_behavior(pod_name: str, events: list[dict], window_seconds: int = 60) -> dict:
"""Turn a raw event stream into a compact behavioral summary."""
process_execs = [e for e in events if e.get("process_exec")]
network_connects = [e for e in events if e.get("process_connect")]
return {
"pod": pod_name,
"window_seconds": window_seconds,
"unique_processes_spawned": list(set(e["process_exec"]["binary"] for e in process_execs)),
"network_destinations": list(set(e["process_connect"]["destination"] for e in network_connects)),
"unusual_exec_count": len(process_execs),
"sample_exec_chain": [e["process_exec"]["binary"] for e in process_execs[:20]],
}Claude Behavioral Analysis
import anthropic
client = anthropic.Anthropic()
ANALYZE_PROMPT = """Analyze this container's runtime behavior for anomalies.
Pod: {pod}
Time window: {window_seconds}s
Processes spawned: {processes}
Network destinations contacted: {destinations}
Process exec chain sample: {exec_chain}
Baseline expected behavior for this pod (from its normal operating pattern
over the last 7 days): {baseline}
Flag as suspicious or malicious if you see patterns like:
- Process spawning a shell (sh, bash) when the app normally never does
- Network connections to destinations outside the known service mesh/allowlist
- Binaries in /tmp or unusual paths being executed
- Cryptomining indicators (sustained high CPU exec chains to mining-pool-like destinations)
- Reconnaissance patterns (whoami, id, cat /etc/passwd, uname -a in sequence)
Respond with ONLY valid JSON:
{{"verdict": "normal"|"suspicious"|"malicious", "confidence": "high"|"medium"|"low",
"evidence": "specific reasoning", "recommended_action": "..."}}"""
def analyze_behavior(summary: dict, baseline: dict) -> dict:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=500,
messages=[{
"role": "user",
"content": ANALYZE_PROMPT.format(
pod=summary["pod"], window_seconds=summary["window_seconds"],
processes=summary["unique_processes_spawned"],
destinations=summary["network_destinations"],
exec_chain=summary["sample_exec_chain"],
baseline=baseline,
)
}]
)
text = response.content[0].text.strip()
if text.startswith("```"):
text = text.split("```")[1].replace("json", "", 1).strip()
import json
return json.loads(text)Response Loop
def monitor_and_respond():
events_by_pod = defaultdict(list)
for event in stream_tetragon_events():
pod = event.get("pod_name", "unknown")
events_by_pod[pod].append(event)
if len(events_by_pod[pod]) >= 50: # Batch, don't analyze every single event
summary = summarize_pod_behavior(pod, events_by_pod[pod])
baseline = get_pod_baseline(pod)
verdict = analyze_behavior(summary, baseline)
if verdict["verdict"] == "malicious" and verdict["confidence"] == "high":
isolate_pod(pod) # NetworkPolicy that blocks all egress
page_security_oncall(pod, verdict["evidence"])
elif verdict["verdict"] in ("suspicious", "malicious"):
notify_security_channel(pod, verdict)
events_by_pod[pod] = [] # Reset windowWhy Behavioral Baselines Matter More Than Generic Rules
A payments service that never spawns a shell process in its normal operation, suddenly spawning sh -c after a request, is a strong signal regardless of what that shell does next. A generic rule-based tool without per-pod baselines either misses this (too permissive) or false-positives constantly on services that legitimately shell out (too strict). Building and maintaining per-pod behavioral baselines — what's normal for this specific workload — is the actual hard engineering problem here; the Claude analysis step is only as good as the baseline it's comparing against.
def build_baseline(pod_label: str, days: int = 7) -> dict:
"""Run this on a schedule against historical event data to keep
baselines current as legitimate app behavior evolves."""
historical_events = query_historical_events(pod_label, days=days)
return {
"normal_processes": extract_common_processes(historical_events),
"normal_destinations": extract_common_destinations(historical_events),
}More AI security tooling? Read our Falco vs Tetragon runtime security comparison and Autonomous security patch triage agent.
Today I Fixed
Short real fixes from production — posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
AI Agents for Zero-Trust Policy Generation: Where This Is Heading in 2026
Writing least-privilege IAM policies and NetworkPolicies by hand means either over-permissioning out of laziness or spending hours tracing what a service actually calls. AI agents that observe real traffic and generate tight zero-trust policies from it are becoming a practical alternative in 2026.
Build an AI Kubernetes Deployment Readiness Checker with Claude API
Build a Python CLI tool using Claude API that analyzes Kubernetes YAML manifests before deployment — catches missing resource limits, root containers, and security issues with a go/no-go score.
Build an AI Kubernetes Admission Controller with Claude API and OPA
Combine OPA Gatekeeper's policy enforcement with Claude API's reasoning to catch risky Kubernetes manifests that static rules miss — and explain the violation in plain English instead of a cryptic denial message.