Agent safety at the syscall boundary

Agent safety, enforced below the agent.

Prompts and training shape what an agent tries. Mriga decides what it can do. Each agent gets its own KVM virtual machine, every syscall passes a policy decision, and credentials never enter the guest.

3,000
KVM guests on one host
1.14 s
to boot all 3,000
2.9 MB
per idle VM
25 ms
restore to serving HTTP

Live runs, one AWS c6i.metal.

The problem

The hazard is what an agent does with access it legitimately holds.

Agents hold real grants: repos, connectors, keys, the open web. An injected prompt, a confused tool call or a malicious tool acts through them at machine speed. Model-side controls are probabilistic. Runtime controls are deterministic.

Today you trade safety for cost. Containers share the host kernel; seccomp is the last line. MicroVMs boot a guest kernel and need a tap device each, which runs out before memory. Mriga keeps the hardware boundary and shares the overhead.

Safety properties

Hazard, control, mechanism

None depends on the model or the agent's intent.

HazardControlMechanism
Escape to the hostHardware boundary per agentKVM VM, no guest kernel to pivot from.
Routing around enforcementNo unmediated syscallsSyscalls rewritten to traps at load; JIT-emitted ones on first execution.
Unapproved actionAllowlist policy per jailJSON policy on syscalls, files, destinations at dispatch. Seccomp backstop. Hot reload.
Credential exfiltrationKeys never enter the guestTLS terminates in the host daemon, which injects the key.
Cross-tenant blast radiusOne jail, one policy per tenantIsolation cheap enough for a VM per run.
Unseen behaviorEvery event attributedLive syscall trace and denials, per agent.

The trade: the host daemon reads request plaintext. That seam enables policy, audit and key custody.

Mechanism

How enforcement works, in four steps

  1. 1 / 4

    Rewrite the binary

    Every path to the kernel is one two-byte instruction. Each syscall becomes a trap at load; JIT-emitted ones on first execution.

    Post 1 →
  2. 2 / 4

    Drop the guest kernel

    A 36 KB no_std shim answers the ~30 syscalls an agent makes. No guest OS, no guest TCP stack, no tap per VM.

    Post 2 →
  3. 3 / 4

    Snapshot it while serving

    Boot once, snapshot while answering, fan out. Pages share copy-on-write; writable data hardlinks from one template. 1,500 instances, ~101 MB of disk.

    Post 3 →
  4. 4 / 4

    Own the network path

    The pool daemon sits between agents and upstreams, holding the DNS cache, warm TLS sessions and credentials. Handshakes are already paid.

    Post 4 →
Request path on one hostAn agent binary's syscalls trap into a 36 KB shim inside a KVM jail. Network traffic leaves through the host pool daemon, which holds policy and audit, TLS sessions, DNS cache and the snapshot store, before reaching model APIs and tools.KVM JAIL×1,500Agent binaryrewritten ELF · unchanged source36 KB shim~30 syscalls · no guest kerneltrapPOOL DAEMON · HOSTio_uringPolicy + auditper jail · hot reloadseccomp backstopTLS + keys338 warm sessionskeys never in guestDNS cachefleet-wideone query per TTLSnapshot storeone imageshared CoWpackets · denialsUPSTREAMModel APIsTools · connectorsThe open webkey injectedEvery syscall traps into the shim. Every packet leaves through the daemon. The guest can see neither.
Fig. 1 · The request path on one host.
Measured

What safety on every run costs

A control too expensive for every run doesn't get applied. One c6i.metal, n = 1,500, live LLM load.

PropertyValueMeasured
Fleet warm-up0.42 s1,500 VMs restored from one 99 MB snapshot
Running density10.8 / GBAgents per GB, 139 GB physical
Dispatch to first syscall44 msp50 · 86 ms p95 · 105 ms p99
TLS handshake per call0 ms338 upstream sessions shared by the fleet
DNS cache hit rate100 %260.7 K hits, one upstream query per name per TTL
Restore to serving25 msn8n, past startup and answering HTTP

Same app, same machine, three runtimes

1,500 copies of n8n on one box. Docker and Firecracker hit per-instance overhead, not memory.

Fig. 2 · Target 1,500 (dashed). Docker: writable layer per container. Firecracker: bridge limit. Mriga: all serving in ~32 s, 113 GB RAM, ~101 MB disk. Memory per instance is a wash (~98 / ~103 / ~75–95 MiB). Both walls are tunable defaults.
Where it fits

What runs today, and what doesn't yet

Model-generated code
Shipping
Code interpreters, tool sandboxes, coding agents. A VM per run.
Multi-tenant agent platforms
Shipping
A jail and policy per tenant. Your provider keys stay host-side.
An instance per customer
Shipping
A real app per account, proven with n8n at 1,500 per box. Idle costs a shared image.
Bursty fleets that mostly wait
Shipping
Runs, evals and rollouts waiting on a model. A 25 ms restore replaces the warm pool.
Ray, GPU residency, Kubernetes
Roadmap
Not yet proven. No numbers until they are.
First questions

What engineers ask first

Why enforce safety in the runtime instead of the model?
Model-side controls change the odds of a bad action. Runtime controls remove it. Only the second holds when the model is wrong, jailbroken or replaced.
Does it stop prompt injection?
No. Nothing below the model can tell a malicious instruction from a legitimate one. Mriga bounds what an injected agent can do and traces every attempt.
Is this a guardrail layer around the model?
No. Mriga never touches the model, prompt or harness. It sits at the syscall and the socket. Mriga is the box the agent runs in.
How is it different from Firecracker or a seccomp-hardened container?
Containers share a kernel behind seccomp. Firecracker boots a guest kernel with a tap per VM, which stopped it at 1,023. Mriga keeps KVM, swaps the kernel for a 36 KB shim, and moves networking to one host daemon.
Do we rebuild our images or binaries?
No. Syscalls are rewritten at load. Name your runtimes (Chromium, Node, Python, JVM) and we'll benchmark them.
What can the host daemon see?
Request plaintext. It terminates TLS to inject keys and apply policy, so the daemon is trusted with plaintext.
What does evaluation take from our team?
Tell us what you run and how many at once. We benchmark density, cold start and restore against your current runtime.
Which numbers are measured?
All of them, from live runs on one c6i.metal; method in the posts below. Roadmap items carry none.
Blog
Early access

Run your agents under Mriga

Onboarding a few teams running agents or untrusted code in production.

info@mriga.dev
Send us

Image, runtime, what it calls.

And

How many at once, peak and average.

You get

Trace, policy, and cost on your workload.