eBPF Socket Hooks Let You Control AI Agents Without Touching Their Code
In this article
Platform engineers shipping AI workloads into Kubernetes have a structural ownership problem: AI-generated code lands in production, the developer who prompted it has moved on, and nobody can explain what the process does or where it calls out. Dan Finneran, Principal Community Advocate at Isovalent (now part of Cisco) and a contributor to upstream Kubernetes, presented a concrete mitigation at QCon London built entirely on eBPF socket hooks — no application source changes, no container restarts, no sidecars injected at admission time.
The talk is an explicit proof-of-concept contribution to an active Kubernetes working group standardising AI gateway behaviour for clusters. The architecture is worth examining before the spec hardens.
The Threat Model: Unowned Code Calling Uncontrolled Endpoints
Finneran frames the risk around three compounding failures. First, vibe-coded or AI-generated services enter production with hard-coded model identifiers and no token ceiling. A poisoned prompt against such a service has no spending cap — the provider keeps generating until the request completes, producing a denial-of-service on the backend or a runaway cost event. Second, AI agents granted file-system or infrastructure permissions have, in documented incidents, executed commands like rm -r * or terraform destroy because the LLM response was treated as ground truth. Third, system prompts that constrain LLM output are often absent from vibe-coded clients, leaving the model free to answer any query in any domain — Finneran demonstrated this with a live Chipotle chatbot that began generating Python data-structure implementations when asked through a burrito-ordering UI. He noted Isovalent's own site exhibited the same flaw at the time of the talk.
This connects directly to the broader AI coding agent supply-chain exposure documented in the public Sentry key hijack incident: code that nobody owns and nobody audits is exactly the attack surface that gets exploited.
eBPF Socket Hooks as a Transparent Interception Plane
eBPF has been part of the Linux kernel since around 2014 and requires no kernel module compilation. Any kernel at version 5.12 or later runs it out of the box. The kernel's built-in verifier checks every program before attachment, guaranteeing no infinite loops and no kernel crash path. Programs attach and detach from a running system without rebooting or restarting workloads.
Finneran's gateway attaches eBPF programs to the socket layer rather than the NIC driver or traffic-control subsystem. The tradeoff is explicit:
| Attachment point | Visibility | What you receive | Usability for JSON API manipulation |
|---|---|---|---|
| NIC driver (XDP) | All ingress/egress frames | Raw Ethernet frames, out-of-order | Very low — reassembly required |
| Traffic Control (tc) | All packets post-routing | Raw packets, still inside kernel | Low — no stream reassembly |
| Socket layer | Per-process socket events | Ordered byte streams, kernel-reassembled | High — JSON payloads arrive intact |
When the monitored process calls connect() to reach an LLM endpoint, the socket-attached eBPF program intercepts that system call and silently redirects the connection to a userland proxy running as an ephemeral container inside the same pod. The process receives no error; it believes it connected to the original endpoint. The proxy dials the real LLM endpoint on behalf of the process, giving the gateway full read-write access to the JSON stream in both directions.
The netflush annotation in the demo forces a reconnect on already-open sockets, so the interception captures long-running agents that established connections before the gateway was attached — closing the race condition that would otherwise let persistent connections bypass policy.
Gateway Capabilities Demonstrated Against a Live Cluster
The demo ran against a Kubernetes cluster with Ollama providing local LLM inference. The workload was a pod hard-coded to call a Llama model every few seconds and request Go jokes. Finneran injected the gateway without modifying the pod spec through the normal admission path — instead using an ephemeral container, a Kubernetes API feature that permits adding a container to a running pod post-start, bypassing the restriction that prevents sidecar injection after workload creation.
A Kubernetes watcher process monitored for the annotation AI="true". On detection, it injected the ephemeral proxy container and applied the eBPF socket hook. A ConfigMap drove policy. Demonstrated controls included:
- Model swap: the hard-coded Llama model identifier in the outbound JSON request was rewritten inline to Gemma 2, with the application receiving Gemma 2 responses without any code change.
- Prompt rewrite: the content of the user-role prompt was modified transparently — "jokes about Go" became "facts about Go," then "jokes about horses," purely through ConfigMap updates with no pod restart.
- Response keyword filtering: a policy rule blocked any response containing content about rabbits from reaching the client process; the gateway returned a rejection instead.
- Full payload observability: the proxy logged the raw JSON request and response objects for each LLM call, exposing token counts, model used, and prompt content.
Token-ceiling enforcement and mTLS termination were described architecturally but not exercised in the live demo. On mTLS, Finneran noted that internal cluster traffic to local LLM processes typically runs unencrypted; a proxy pair can terminate and re-establish encrypted sessions transparently to both sides.
Fit Within the Kubernetes AI Gateway Working Group
The architectural primitives — ephemeral containers for zero-restart injection, socket-level eBPF hooks for transparent interception, ConfigMap-driven policy — are all existing stable or beta Kubernetes and Linux kernel features. Nothing in the stack requires a custom kernel build or a new CRD schema.
The risk profile this addresses grows in direct proportion to autonomous agent deployment. As agentic systems acquire more default autonomy, the gap between what an agent is permitted to call and what platform engineers can observe closes only if the interception plane sits below the application — exactly where eBPF operates. Waiting for application developers to instrument their own AI calls, particularly when those developers may no longer be in the organisation, is not a viable control strategy. Kernel-level socket hooks combined with the Kubernetes ephemeral container API represent a deployment path that requires no cooperation from the code being controlled.