Best AI Agent Tools for DevOps on Linux

Necco Ceresani
Necco Ceresani··20 min read

Fifteen years building engineering platforms, currently focused on advanced AI infrastructure at yeet. I love turning the deeply complex topics into something everyone can understand. I relate deeply with the core yeet philosophy that you can just build things.

Last updated: September 2026

Quick answer. The tools in this category split cleanly into two groups that get discussed as one, and picking across the split is where teams waste time. Confinement decides what an agent can reach before it acts: Landlock, bubblewrap, Anthropic's sandbox-runtime, gVisor, containers and agent-lock. Recording tells you what it did: auditd, claudefeed, exectop and the yeet system graph. Neither substitutes for the other, most teams need one from each column, and every tool below is quoted from its own documentation rather than characterized from memory, including ours.

I build kernel-side tooling for Linux, which means I have a commercial interest in you reaching for the last two entries and a working knowledge of why the first six exist. I have not run all of these in production, and where I have not, the entry says what the vendor's own docs say and nothing more. What I do see repeatedly is a team that has picked a strong tool from one column, believes the job is done, and cannot answer the question the other column exists for.

What should an AI agent tool for DevOps enforce, and what should it record?

Pick one of two jobs and be honest about which, because a tool that does one well is usually silent about the other. Confinement is a decision made before an action completes: the kernel, or a userspace kernel, or a proxy refuses something. Recording is a fact established after: a process did this, at this time, in this tree.

The distinction matters because the failure modes are opposite. A confinement tool scoped too broadly permits the thing you cared about and reports nothing, so you learn nothing from it. A recording tool catches an action nobody anticipated and only after it completed, so you learn everything and prevented nothing. That is not a reason to prefer one; it is the reason the two get paired.

Three questions sort the field faster than any feature list. Does it need root or a privileged install. Does it enforce on a path, an inode, a syscall, or a domain name. And when it refuses something, can you see the refusal, because a denial you cannot observe is a policy you cannot debug. That third question is the one most comparison posts skip, and it decides whether adopting the tool is a day of work or a month: a jail that silently blocks the thing your agent needed presents as the agent being broken, and you will spend that month bisecting a policy you cannot read.

Which AI agent confinement tools run without root: Landlock or bubblewrap?

Landlock and bubblewrap, and that is most of why they are the default answer for a developer box. Both were built for a process to restrict itself rather than for an administrator to restrict a fleet.

Landlock

Landlock is in mainline Linux and its own description is precise about the goal: "to enable restricting ambient rights (e.g. global filesystem access) for a set of processes." The project says it lets "any process, including unprivileged ones, to securely restrict themselves," and it works as "a stackable LSM" that adds a layer rather than replacing the system's existing access controls.

What it does better: no install, no daemon, no privilege, and it enforces on the inode rather than the path, which closes the hardlink gap that path-based checks carry. What it costs you: filesystem is the primary surface, network restriction is not what the project leads with, and it confines without reporting, so a refusal is invisible unless you pair it with something that watches. Who it fits: an agent on a machine where you cannot load BPF and do not need a record.

bubblewrap

bubblewrap is the primitive underneath a lot of this category, described as a "Low-level unprivileged sandboxing tool used by Flatpak and similar projects." It builds the sandbox from unprivileged user namespaces, and the project is explicit that the setuid mode it once had "has been removed."

The sentence worth reading twice before adopting it is the project's own scoping:

"bubblewrap is a tool for constructing sandbox environments. bubblewrap is not a complete, ready-made sandbox with a specific security policy."

And immediately after: "the level of protection between the sandboxed processes and the host system is entirely determined by the arguments passed to bubblewrap." That is an unusually honest statement and it tells you exactly what you are buying: a mechanism, with the policy as your problem. The docs also name specific escapes to handle, including D-Bus sockets as a privilege-escalation path and TIOCSTI needing a seccomp filter to prevent out-of-sandbox command execution. Who it fits: teams building their own per-command sandbox, and the thing you reach for when you want to compose the policy yourself.

Is Anthropic's sandbox-runtime the right tool for a Claude Code setup?

It is the shortest path if you are already running Claude Code, because it is the same mechanism the product uses, packaged for arbitrary processes. Anthropic's sandbox-runtime describes itself as "a lightweight sandboxing tool for enforcing filesystem and network restrictions on arbitrary processes at the OS level, without requiring a container."

The design is two layers with opposite defaults, which is the detail that makes it fit agent work: reads are allowed by default with denial exceptions, writes are denied by default and need explicit allowance, and all network access is denied by default, permitted per-domain through HTTP/HTTPS and SOCKS5 proxies. On Linux it is built on bubblewrap, so the entry above is its foundation.

What it costs you is stated in the repo rather than discovered later. The network filtering "does not otherwise inspect the traffic passing through the proxy," domain fronting is a named bypass, and the Linux implementation carries a weaker mode for Docker compatibility that the docs say "considerably weakens security." It is also labelled a research preview in beta, with APIs and configuration formats that "may evolve." Who it fits: a team standardizing on Claude Code that wants the same boundary around other processes, and is comfortable with a beta contract.

When are gVisor or containers the right tools for an AI agent?

When the agent is running code you did not write, which is a different threat model from the agent itself misbehaving. Both of these isolate a workload rather than scoping a trusted process.

gVisor

gVisor "provides a strong layer of isolation between running applications and the host operating system. It is an application kernel that implements a Linux-like interface." It "intercepts application system calls and acts as the guest kernel, without the need for translation through virtualized hardware."

That is the strongest isolation in this post, and the docs price it honestly in the next sentence: "This comes at the price of reduced application compatibility and higher per-system call overhead." They also note gVisor "does not presently implement every system call, /proc file, or /sys file so some incompatibilities may occur," which matters more than it sounds for agent work, because an agent's whole job is reaching for tools you did not anticipate. Who it fits: running untrusted generated code, where a kernel exploit is in your threat model.

Containers

A container is the tool most teams already have, and it is the one most often mistaken for access control. It bounds the filesystem and it does nothing about credentials you mounted, a network route you left open, or a socket you bind-mounted so the agent could reach what it needed.

The specific trap for agent work is that the useful configuration defeats the isolation. An agent in a container cannot see host processes, which is usually the point, so --pid=host gets added, then CAP_SYS_PTRACE so it can read them. At that point it is a packaging choice rather than a boundary. Who it fits: reproducible environments and untrusted tooling, not host inspection.

Which tools record what an AI agent did rather than blocking it?

auditd, exectop and the yeet system graph, and a team with none of these cannot answer the only question that matters after something goes wrong.

auditd

auditd ships with the distribution, survives reboots, and your compliance team probably already reads its output, which together beat any technical argument. A watch is one line:

auditctl -w /etc/nginx/ -p wa -k agent-config

-p wa catches writes and attribute changes, -k tags records so ausearch -k agent-config finds them later. What it costs you: it is noisy at agent volumes, it has no per-agent scoping, and correlating a burst of records back to one agent session is work you do yourself. Who it fits: anywhere the record has to be durable and auditable rather than immediate.

claudefeed

claudefeed is the entry built for this exact job: an agent audit feed that streams every command, file open and TCP connection a coding-agent session makes, scoped to that session's process subtree. It finds the live claude processes itself, seeds its tracked set and starts streaming, so there is no pid to supply.

What it does better than the alternatives is the scoping, and its README is precise about why that matters. strace -f needs a pid named up front and a session is a moving tree, because the agent spawns a shell, the shell spawns git, and git spawns ssh. auditd catches the tree and hands you a system-wide log to filter afterwards. claudefeed filters in the kernel and scopes to the subtree.

Its limits are unusually well documented, and four matter for a DevOps decision. It records that a file was opened and never the bytes, by design. It hooks openat only, so open(2), openat2, mmap and a descriptor passed across a socket do not appear. exec fires at syscall entry, so a command that failed to launch still produces a line. And it is TCP-only at connect initiation, so UDP and raw sockets are unhooked and DNS over UDP is invisible.

The framing note is the same as its siblings: "claudefeed observes. It tells you what a session did; it does not stop, hold, or modify anything." Who it fits: the default record for a coding-agent session on one box, when you want exec, file and network in one feed.

exectop

exectop answers a narrower question more legibly. It attaches three sched tracepoints, follows a process tree through fork, and folds repetition into one row per kind of command, so a build firing thousands of execs reads as a handful of rows with the unusual ones ranked on top.

Pick it over claudefeed when the question is about volume rather than variety: a slow build, a dependency install, anything where the interesting fact is that one command ran nine hundred times. Its own limits are that anything which does not exec is invisible, so work done inside Node or Python without launching a program leaves no row and fetch() looks like nothing where curl is a row, and delivery is bound by bytes rather than events, so a fork storm beyond roughly 2,700 execs a second outruns the ring buffer. Like claudefeed, it "does not stop, delay, or modify anything."

The yeet system graph

Where exectop answers what was launched, the graph answers what the host looks like, and it is the entry that changes an access decision rather than a monitoring one. Install yeet and the daemon exposes the machine as a typed GraphQL graph:

yeet graph dump                                  # the schema, as SDL
yeet graph query '{ procs { pid comm cpu_time } }'

dump prints the schema so an agent can discover the surface, and query returns JSON on stdout. The graph covers processes with command lines, CPU time, memory, disk I/O and scheduler run delay, plus per-core CPU, memory, network interfaces, containers, load average and kernel stats.

The property that matters here is structural rather than configured. The schema is built as Schema<Query, EmptyMutation, Subscription>: there is no mutation type, so no query string changes anything on the host. That makes it the one entry in this post where read-only is the absence of a code path rather than a policy you could misconfigure. What it costs you: it answers what the schema covers, so a novel question needs a probe written for it, and the daemon is a privileged install.

agent-lock

agent-lock is the one tool here that does both jobs from the same hook. A BPF LSM program on lsm/file_open returns -EPERM for a path outside the directory you name, and the same hook streams every refusal to a dashboard, so enforcement and observation are the same kernel code rather than two systems you correlate later.

Its stated limits, from its own README:

"agent-lock enforces on file opens only. It does not govern sockets, so it neither sees nor stops network activity, and it reads paths and verdicts rather than file contents."

Three consequences. It gates on the path rather than read-versus-write, so "may read this config but not write it" is not expressible. A hardlink inside the jail pointing outside resolves to an in-bounds path, which is the documented limit of path-based enforcement and why Landlock's inode checks do not carry it. And it is one host, one process tree, no history. Who it fits: bounding an agent's writes to one tree while watching what it reached for, on a kernel with CONFIG_BPF_LSM=y.

Which AI agent tool should I pick for my DevOps setup?

ToolEnforces or recordsNeeds rootEnforces onDoes not cover
agent-lock on yeetBothYes, BPF LSMFile opens, by pathSockets; read vs write; hardlinks
yeet graphRecords, read-only by typeYes, daemonNothing, it is a query surfaceQuestions outside the schema
claudefeedRecordsYes, daemonNothing, it is a feedPayloads; openat only; UDP
exectopRecordsYes, daemonNothing, tracepoints onlyNon-exec work; >2,700 execs/sec
LandlockEnforcesNoInodeReporting; network
bubblewrapEnforcesNoWhatever you configurePolicy is yours; D-Bus; TIOCSTI
sandbox-runtimeEnforcesNoPaths and domainsTraffic content; domain fronting
gVisorEnforcesYesSyscallsCompatibility; per-syscall cost
auditdRecordsYesNothing, it is a logPer-agent scoping; noise

Read the second column first. Everything above the line in your head should be one tool from each of the two jobs, and the rest of the table is about which constraint you can actually satisfy: root or not, kernel version or not, and whether you need to see the refusals.

The bottom line: pick one from each column, then check the constraint

Decide which job you are buying before you compare tools, because the two columns do not substitute for each other and most of the disagreement in this category is people arguing across the split. For confinement without root on a developer box, Landlock is in mainline and enforces on the inode, and bubblewrap is the primitive to reach for when you want to compose the policy yourself, remembering it "is not a complete, ready-made sandbox with a specific security policy." If you already run Claude Code, sandbox-runtime gives you the same boundary around other processes at the cost of a beta contract. For untrusted generated code where a kernel exploit is in scope, gVisor is the strongest isolation here and prices it in compatibility. For the record, auditd when it must survive a reboot and exectop when you want one agent's process tree now, knowing it "does not stop, delay, or modify anything." And when you want an agent to ask questions about a host rather than hold a shell on it, yeet's graph has no mutation type at all.

The mistake worth avoiding is treating a strong pick in one column as coverage of both. A team with gVisor and no record cannot say what the agent did inside it; a team with auditd and no confinement has a very good account of an incident it did not prevent.

Frequently asked questions

What are the best AI agent sandboxing tools for Linux?

Landlock and bubblewrap for unprivileged confinement, Anthropic's sandbox-runtime if you are standardizing on Claude Code, gVisor when the agent runs untrusted code, and agent-lock when you want the kernel to refuse opens outside a directory and to show you every refusal. Which is best depends on whether you can load BPF and whether you need to see denials.

Do I need root to sandbox an AI agent on Linux?

No. Landlock is explicitly designed so that any process, including an unprivileged one, can restrict itself, and bubblewrap builds its sandbox from unprivileged user namespaces after removing its old setuid mode. BPF LSM enforcement and the yeet daemon do need a privileged install, which is a fleet decision rather than a laptop one.

Is Landlock or bubblewrap better for an AI agent?

They solve different halves. Landlock is a kernel LSM that a process uses to restrict itself and enforces on the inode; bubblewrap is a userspace tool that constructs a sandbox from namespaces and leaves the policy to whoever writes the arguments. Landlock is simpler to reason about; bubblewrap composes more.

Does a container sandbox an AI agent?

It bounds the filesystem and nothing you deliberately passed in. For agent work the useful configuration usually undoes the isolation, because seeing host processes needs --pid=host and reading them needs added capabilities. A container with both is a packaging choice rather than a security boundary.

What is the difference between agent confinement and agent monitoring?

Confinement decides what the agent can reach before an action completes; monitoring establishes what it did afterwards. They fail in opposite directions, which is why most setups need one of each rather than the strongest single tool.

What is the difference between claudefeed and exectop?

claudefeed streams exec, file-open and TCP-connect events for one agent session and finds the session itself, so it suits the general question of what an agent did. exectop folds repeated commands into one row per kind, so it suits the narrower question of what ran and how often. Both observe rather than enforce.

Can auditd track what an AI agent did?

Yes, and it is the right choice when the record must survive a reboot or be read by people who already read auditd output. A watch such as auditctl -w /etc/nginx/ -p wa -k agent-config tags records for later retrieval. It is noisy at agent volumes and has no per-agent scoping, so correlation is work you do yourself.

Does eBPF help with AI agent security on Linux?

For two specific jobs. A BPF LSM program can refuse a file open outside a named directory and stream the refusals, and tracepoint-based tools can record every process an agent's tree launched. Neither judges whether an action was correct, and neither sees work an agent does inside a process without launching anything.

What can no AI agent tool do?

Tell a good change from a bad one, because the system calls are identical and the difference is intent. None of these tools constrains a cloud API call either, since that never reaches your kernel, and none stops an agent acting inside a process it already controls.

Is gVisor too slow for AI agent workloads?

Its own documentation prices the tradeoff as "reduced application compatibility and higher per-system call overhead," and notes it does not implement every system call, /proc file or /sys file. Whether that is too slow depends on the workload, and the compatibility half is often the bigger problem for agents, which reach for tools nobody anticipated.

Can an AI agent query a Linux host without a shell?

Yes. The yeet daemon exposes the host as a typed GraphQL graph, so yeet graph query returns JSON for processes, CPU, memory, network, containers and kernel stats. Its schema is built with no mutation type, so there is no query that changes the machine, which is a stronger guarantee than a permission rule over shell command text.

Sources

  • Landlock. The project's own description of its goal, "restricting ambient rights (e.g. global filesystem access) for a set of processes", its statement that any process including unprivileged ones can securely restrict themselves, and its position as a stackable LSM layered on existing controls.
  • bubblewrap on GitHub. Source for the self-description, the removal of setuid mode in favour of unprivileged user namespaces, the scoping statement that it "is not a complete, ready-made sandbox with a specific security policy", and the named escapes including D-Bus and TIOCSTI.
  • anthropic-experimental/sandbox-runtime. Source for the two-layer default model, the per-domain proxy filtering, the statement that filtering "does not otherwise inspect the traffic", the domain-fronting bypass, the Docker-compatibility mode that "considerably weakens security", and the research-preview status.
  • gVisor documentation. Source for the application-kernel description, the syscall-interception mechanism, and the stated cost in compatibility and per-syscall overhead, including the unimplemented syscalls and /proc and /sys files.
  • auditd(8) manual page. The daemon behind the durable-record option, and the reference for the watch syntax used above.
  • claudefeed. Source for the exec, file-open and TCP-connect feed scoped to an agent's process subtree, the self-discovery of live sessions, and its documented gaps: paths rather than payloads, openat only, exec at syscall entry, and TCP connect initiation with UDP and raw sockets unhooked.
  • exectop. Source for the three sched tracepoints, the fold-by-kind behaviour, and its own limits section: observability rather than enforcement, blindness to non-exec work, and the throughput ceiling around 2,700 execs a second.
  • agent-lock. Source for the lsm/file_open hook returning -EPERM, enforcement and observation sharing one kernel program, and the stated limits on sockets, read-versus-write, hardlinks and history.
  • yeet documentation. The runtime behind the system graph and the two scripts above. The read-only property quoted here was verified against the schema construction at master rather than taken from documentation.

Related resources

Built with yeet, a JS runtime for writing eBPF programs on Linux machines. Join us on discord.