nono sandboxes any local coding agent using OS kernel primitives (Landlock on Linux, Seatbelt on macOS) with zero setup and zero runtime overhead after initialization, and no container, daemon, or VM required. Restrictions are kernel-enforced allow-lists that child processes inherit and no API can escape; on Linux, filesystem confinement needs kernel 5.13+ and network confinement needs 6.7+. Secrets are injected at the boundary through a credential proxy so the agent never sees raw tokens, and per-tool JSON profiles give each agent its own filesystem, network, and credential policy. Reach for a full microVM like Firecracker only when you need hardware-level isolation for genuinely untrusted code.
A coding agent running on your laptop inherits your permissions. Every file your user account can read, it can read: your SSH keys, your ~/.aws/credentials, your browser cookies, the private repos sitting in every sibling directory. That is the uncomfortable default, and it is exactly why teams are looking for a way to sandbox coding agents locally without the weight of a virtual machine. nono, an open-source (Apache-2.0) sandbox from the nolabs-ai project, is the tool that has made that practical: it isolates any agent using operating-system kernel primitives with, in its own words, zero setup and zero latency.
nono is a local, OS-level sandbox that confines an agent to a kernel-enforced allow-list of files, network destinations, and credentials. It launched in May 2026 (Luke Hinds published the launch write-up on HuggingFace) and, according to its GitHub repository, sits at around 2,800 stars as of mid-July 2026. On Linux it uses Landlock and on macOS it uses Seatbelt to apply restrictions the agent cannot escape, with no daemon, no container, no VM, and no disk usage. The codebase is 95.2% Rust with foreign-function bindings for Rust, Python, TypeScript, and Go.
This post covers the threat model a local agent creates, how the two kernel sandboxes underneath nono actually work, what nono layers on top (per-tool profiles, secret brokering, an audit trail), how to wire it around Claude Code and your own harnesses, and where it stops being enough and you genuinely need a VM boundary. The through-line: kernel sandboxing buys you most of the isolation of a microVM at close to none of the overhead, and for local coding agents that is usually the right trade.
01 · The threat model: why a local coding agent can touch every file and secret
A local coding agent runs as your user, so by default it can read, write, and delete anything your account can, including SSH keys, cloud credentials, and every repository on the machine. That is the entire problem nono exists to solve.
Think about what actually happens when you launch an agent in a terminal. It spawns as a child of your shell, inheriting your user id, your environment variables, and your filesystem permissions. Nothing about "this is an AI process" changes what the kernel will let it do. If the agent decides, or is steered by a prompt injection buried in a dependency's README, an issue comment, or a web page it fetched, to run cat ~/.aws/credentials or curl your environment file to an attacker's host, the operating system has no reason to stop it. The model is a probabilistic process holding your full authority.
This is a different risk shape from the classic web-app threat model, and it is why we treat local agents as their own category in the AI security reviews we run at Particula Tech. The attack does not need a remote code execution bug. The agent already has execution; the only question is what it is allowed to reach. Prompt injection turns "read this file" into an instruction the agent may faithfully carry out, which is why containing the blast radius matters more than trying to make the model refuse. We go deeper on the exfiltration side of this in our guide to preventing data leakage in AI applications, and on the broader posture in securing AI systems that touch sensitive data.
The naive fixes are all bad. Running the agent as a second user account is clumsy and leaks through shared group permissions. Running it in a container works but drags in Docker, image builds, and volume-mount gymnastics that most developers will not tolerate on every invocation. Running it in a VM is the strongest boundary and the heaviest. What people actually want is least privilege at the process level: this agent, right now, can see this project directory and reach these two hosts, and nothing else. That is precisely what kernel sandboxes provide.
02 · How Landlock (Linux) and Seatbelt (macOS) sandbox AI agents at the kernel
Both are OS-native sandbox mechanisms that let an unprivileged process drop itself into an allow-list it cannot climb back out of: Landlock on Linux, Seatbelt on macOS. nono is a friendly front end over both.
Landlock is a Linux Security Module (LSM) that lets an unprivileged process voluntarily restrict its own access to the filesystem and network, with no root and no config files. The process describes the paths and operations it should still be allowed, applies the ruleset, and from that point the kernel denies everything else for that process and its descendants. According to the Linux kernel Landlock documentation (kernel.org, 2026), Landlock was first introduced in Linux 5.13, filesystem restriction is available from that version, and network restrictions (controlling TCP bind and connect) require Landlock ABI v4, which shipped in Linux 6.7. nono targets ABI v5 and degrades gracefully to the highest ABI the running kernel supports, so on an older kernel you still get filesystem confinement even where network rules are not yet enforceable.
Seatbelt is Apple's built-in sandbox framework, available since OS X 10.5, that confines a process to a declarative policy describing which files, network operations, and system services it may use. It is the same class of mechanism macOS uses under the hood for App Store apps. nono compiles your intent into a Seatbelt profile on macOS the same way it emits a Landlock ruleset on Linux, so the policy you write is portable across the two platforms.
The property that makes this a real security boundary and not a polite suggestion is irrevocability. According to Luke Hinds' launch write-up (HuggingFace, 2026), once nono applies its restrictions there is no API to escape them. The allow-list is enforced by the kernel, so a compromised or injected agent cannot ask the kernel nicely to lift them. And crucially, the restrictions are inherited by child processes, so an agent that shells out to npm, python, or a build script cannot launder its way around the sandbox by spawning a helper.
Two honest limits. First, these are the two confirmed platforms as of this writing. Windows support runs through WSL2 and is best treated as partial and experimental (it needs a real Linux kernel, and the launch write-up listed Windows as not yet supported). If your team is on native Windows, plan for WSL2 or a VM. Second, a kernel sandbox shares the host kernel, so a kernel-level exploit is out of scope for Landlock or Seatbelt to contain. That is the exact line where microVMs earn their keep, covered further down.
| Capability | Requirement |
|---|---|
| Filesystem restriction (Linux) | Landlock, kernel 5.13+ |
| Network restriction (Linux) | Landlock ABI v4, kernel 6.7+ |
| macOS sandbox | Seatbelt, OS X 10.5+ |
| Windows | WSL2 (partial/experimental, needs a Linux kernel) |
03 · What nono adds: per-tool profiles, secret brokering, and an audit trail
Raw Landlock and Seatbelt give you one filesystem and network boundary; nono adds five composable defense layers, a credential proxy so the agent never touches raw secrets, per-tool isolation, and cryptographic session logging, all driven by JSON profiles.
Landlock and Seatbelt are powerful but low-level. Wiring them by hand for each tool an agent might invoke is exactly the kind of work no one does, which is how "we will sandbox it later" becomes "it is running unsandboxed in prod." nono's contribution is the ergonomics and the layers on top. According to nono's project site (nono.sh, 2026), the sandbox carries zero runtime overhead after initialization because enforcement lives in the kernel rather than a monitoring process, and it needs no daemon, no container, no VM, no disk usage, and no root privileges.
nono organizes its protection into five layers, and it is worth knowing which are reversible:
The secret-brokering layer is the one most teams underestimate. A credential proxy is a broker that holds your secrets and injects them into outbound requests at the boundary, so the agent itself never receives the raw value. In nono's model the agent may call gh, but gh only receives a GitHub token through nono's credential proxy (L7 filtering, with keyring:// references and env or header injection). By default, sensitive paths like SSH keys, AWS credentials, and shell configs are blocked outright, and a why command explains why any given path was denied. That last detail matters more than it sounds: the single biggest reason developers disable a sandbox is not knowing why something broke.
For the audit layer, nono.sh lists cryptographic session logging, and the repository lists audit among its capabilities, so you get a durable record of what the agent did. If you are hardening the tool surface an agent can reach, this pairs naturally with the discipline in our MCP server security hardening checklist, which covers the credential-scoping and least-privilege patterns on the server side of the same problem.
| Layer | What it does | Reversible? |
|---|---|---|
| Command blocklist | Blocks named dangerous commands | Yes (overridable) |
| Kernel delete/truncate blocks | Prevents destructive file ops in the kernel | No (irreversible) |
| Filesystem sandbox | Landlock/Seatbelt path allow-list | No |
| Network sandbox | Restricts outbound destinations | No |
| Process inheritance | Child processes inherit all restrictions | No |
04 · How to sandbox coding agents locally: wiring nono around Claude Code and custom harnesses
For supported agents you point nono at a prebuilt profile and launch normally; nono ships profiles for seven agents including Claude Code, and for custom harnesses you write a small JSON profile describing allowed paths, hosts, and credentials.
The fastest path is the prebuilt profile. nono ships ready-made profiles for Claude Code, Codex, Pi, CoPilot, Hermes, OpenCode, and OpenClaw. The claude-code.json profile predefines security groups such as node_runtime, python_runtime, and rust_runtime, so the common toolchains an agent shells out to are already accounted for. In practice, sandboxing Claude Code locally looks like running it under nono with that profile rather than launching the bare binary:
# Run Claude Code confined to the nono claude-code profile nono run --profile claude-code -- claude
For a custom harness, or your own GPT or Claude wrapper, you describe the boundary in a JSON profile. The composable policy system lets each profile declare its own filesystem, network, and credential rules, and compose from a base via an extends mechanism so you are not repeating yourself across tools. A profile looks, roughly, like this:
{
"extends": "base",
"filesystem": {
"read": ["./", "~/.cache/agent"],
"write": ["./", "/tmp/agent-scratch"]
},
"network": { "allow": ["api.anthropic.com", "github.com"] },
"credentials": { "GITHUB_TOKEN": "keyring://github/token" }
}The shape above is illustrative rather than a schema reference (check the repo for exact keys), but the model is the point: the agent's working directory and a scratch space are writable, its home directory and credential files are not, outbound traffic is pinned to the two hosts it legitimately needs, and the GitHub token is a keyring reference the proxy resolves, never a literal in the agent's environment. Start from that posture for any local agent and you have capped what a prompt injection can reach before you write a single custom rule.
05 · Least-privilege profiles per agent and per tool
Give each agent and each delegated tool its own isolated sandbox with the narrowest filesystem, network, and credential policy that still lets it work, and compose those policies with extends instead of hand-maintaining one giant allow-list.
Least privilege is the principle that a process should hold only the permissions it needs for its task and no more. nono operationalizes it at two granularities. Per agent, Claude Code gets a different profile than a data-scraping agent, because their legitimate reach differs. Per tool, nono places delegated tools in isolated child sandboxes with separate filesystem, network, and credential policies, so a tool that only needs to read the repo cannot also open a socket, and a tool that talks to one API cannot reach another.
The practical way to design these is to start closed and open the minimum. Deny all filesystem access, then add the project directory and a scratch path. Deny all network, then add the specific API hosts the agent calls. Deny all credentials, then broker in the one token a given tool needs. Because policies compose through extends, you keep a hardened base profile and layer small per-tool deltas on top, which is far more maintainable than a per-agent monolith. Across the local agent setups we harden at Particula Tech, the profiles that survive contact with real work are the ones scoped per tool, not per agent: a single agent-wide allow-list always drifts toward "allow everything," because one tool needed one extra path and nobody narrowed it back down.
A word on what to skip: do not lean on the command blocklist as your primary control. It is the one reversible, overridable layer, and blocklists are a losing game against a model that can spell a command a dozen ways. Treat the filesystem and network allow-lists as the real boundary and the blocklist as a convenience tripwire, not a wall.
06 · nono vs Firecracker microVMs: overhead vs isolation
nono gives you near-zero overhead by sharing the host kernel, while a microVM like Firecracker gives you a separate guest kernel and hardware isolation at the cost of a roughly 125 ms boot and a few MiB per instance. Pick based on how much you trust the code.
A microVM is a lightweight virtual machine that boots a minimal guest kernel in milliseconds, giving you a hardware-enforced boundary far stronger than a shared-kernel sandbox. According to the Firecracker specification (2026), a microVM boots to guest init in 125 milliseconds or less, adds under 5 MiB of VMM memory overhead per microVM, and supports a steady mutation rate of 5 microVMs per host core per second. Those numbers are excellent for a VM. They are still much more than nono's zero-after-init overhead, and they come with root and KVM requirements plus a guest image to manage.
The real difference is the boundary, not the benchmark:
We compared the microVM options in depth in smolVM vs Firecracker for sandboxing AI-generated code, and the managed-cloud equivalents in Modal vs E2B vs Daytona vs Vercel Sandbox. The short version: those are the right tools when you are executing genuinely untrusted code, running many tenants, or need the ability to contain a kernel-level compromise. nono is the right tool when the code is your own agent doing your own work on your own machine, and you want to cap what a prompt injection can reach without paying VM tax on every keystroke.
| Dimension | nono (kernel sandbox) | Firecracker microVM |
|---|---|---|
| Isolation boundary | Shared host kernel (Landlock/Seatbelt) | Separate guest kernel + hardware virtualization |
| Startup | Zero setup, applied in-process | ~125 ms boot to guest init |
| Steady-state overhead | Zero after init | Under 5 MiB VMM memory per microVM |
| Root required | No | Yes (KVM access) |
| Disk footprint | None | Guest rootfs image |
| Contains a kernel exploit? | No | Yes |
| Best for | Local coding agents you mostly trust | Untrusted or multi-tenant code |
07 · The bottom line: when nono is enough and when you still need a VM
Use nono for any local coding agent on macOS or Linux; reach for a Firecracker-class microVM or a managed cloud sandbox only when you are running untrusted, multi-tenant, or kernel-exploit-relevant code. For the common case of confining Claude Code or your own harness on a dev machine, nono is the right default.
Concretely, here is the decision we give teams:
What to use as of July 2026: install the current nono release (the 0.67.x line was the latest in early July 2026), start from the prebuilt claude-code profile, and tighten the filesystem and network allow-lists to your actual project and API hosts. Keep the destructive-operation and credential-proxy layers on, and do not rely on the command blocklist as a real control. If you are on native Windows, treat WSL2 support as experimental and budget for a VM instead.
If you are rolling agents out across a team and want the profiles and boundary designed against your real threat model rather than the defaults, that is precisely the work of Particula Tech's AI security reviews, and the AI security pillar guide maps where local sandboxing sits alongside the rest of the stack. Start closed, open the minimum, and let the kernel do the enforcing.
08 · FAQ
Quick answers to the questions this post tends to raise.




