/docs/faq

Frequently asked questions

Short answers to the questions that come up most, each from what the nd7 repository actually documents. Where a question has no documented answer it is left out rather than guessed at. Longer treatments are linked from each answer.

Is a permission prompt not enough?#

A prompt only helps if a person reads it carefully every time, and agents produce a great many of them. It also decides one action at a time, with no way to say "and nothing else": once a command is approved, what it does after that is unconstrained. A kernel sandbox works the other way round: the rules are set once, the operating system applies them to every operation the agent and its children make, and nothing needs anyone to be watching. nd7's own hook says as much in practice: for a Bash command it answers permissionDecision: allow, because once the kernel is the boundary, a second prompt only asks a person to decide again what the rules have already settled. Claude Code does the same for commands its own sandbox has confined.

Is Docker enough to sandbox a coding agent, and how is an OS sandbox different?#

nd7's documents do not compare it with Docker, so this answer is limited to what they do say. A container is another machine's worth of environment: the agent works on a copy of the project, with whatever tooling was put in the image, and things on your machine it would normally use are not there. nd7 takes the other approach — the agent runs on the machine where you already work, with your tools and your checkout, and the kernel's own sandboxing facility restricts what it may touch. The one comparison the repository does draw against a virtual machine is in ADR-0007, which considered a Linux microVM and recorded it as "more control and no nesting problem, at the cost of the developer's environment", classing it as a second tier rather than a replacement.

How is nd7 different from Claude Code's built-in sandbox?#

The README documents two concrete differences. First, nd7 run turns Claude Code's own sandbox off for the session — passing "sandbox": { "enabled": false } — because the kernel refuses a second profile inside an existing one anyway, and an explicit "off" means the refusal does not cost a broken tool call. Second, the refusal is the point: once nd7's profile is applied to the agent and everything it spawns, no profile that anything inside tries to apply can take effect, whether looser or tighter. That is what makes the boundary hold against the model itself and against a compromised dependency. The trade-offs are stated too: Claude Code's /sandbox settings have no effect under nd7, and Claude Code's hostname-based network filtering is lost, because nd7 filters by port and does not yet have a proxy of its own. See How the macOS sandbox works.

Does nd7 work with Codex or other agents?#

Not today. Claude Code is the only agent nd7 supports. The architecture describes where others attach — a different adapter parsing a different payload into the same entries with a source of intent:codex rather than intent:claude-code — and the reserved values for that are already in the schema. Nothing for Codex is implemented, and a Codex adapter is listed as deferred to a later phase. The sandbox side is more nearly agent-agnostic: nd7 run applies its rules to any program, and only adds the hook and the system-prompt line when the program is called claude.

Does nd7 work on Linux?#

Recording, verifying and shipping do; the sandbox does not. nd7 run and nd7-exec print only supported on macOS and exit 2 elsewhere, and the sandbox module is compiled on macOS alone. Continuous integration runs the test suite on both macOS and Linux. A Linux sandbox is planned, using Landlock — the Linux kernel's own sandboxing facility — with fanotify, seccomp-notify or eBPF for the kernel-observation phase. The README describes Linux as Tier 2 and not yet built.

Can the agent turn the sandbox off?#

No, and this is the property the whole design rests on. macOS applies one profile to a process tree and refuses any attempt by a process already inside it to apply a different one: looser, tighter, a superset, a subset, or the same rules with different parameters all fail, and only a semantically identical profile is accepted, as a no-op. That was measured before the design was chosen, and it is recorded in ADR-0007. So neither the model, nor a command it runs, nor a compromised dependency can widen the boundary from inside.

The one exit exists outside that rule: one literal path, the nd7-exec binary, may be executed in a way that leaves the sandbox. That program takes nothing from the caller beyond the command text — not its arguments, not its working directory, not its environment, and it reads your home directory from the password database rather than from $HOME — finds its session by walking the parent-process chain, which a caller cannot forge, and applies that session's rules to itself before running anything. nd7 run refuses to start at all if that binary or the directory holding it is writable by anyone but you. And if the hook that routes commands through it ever stops applying, commands simply run under the outer floor, which is never wider: the failure is closed.

What does nd7 not protect against today?#

The limits the repository states, rather than a general threat model:

  • Anything inside the allowed area. The project directory is writable, so an agent can damage your project; that is what version control is for. Reading is open everywhere except ~/.ssh, ~/.aws and ~/.nd7, so a credential in a .env file inside the project is readable.
  • Network exfiltration over HTTPS. Port 443 to any host is allowed. Filtering is by port, not hostname.
  • The Write and Edit tools running wider than you intended. They run inside the agent process and see only the rules the session started with; nd7 allow does not reach them.
  • Programs, generally. The rules allow executing anything inside the boundary. An allowlist derived from recorded sessions is the stated next step.
  • Someone who can write your disk. They can rewrite the whole log and its chain. See the next question.
  • Anything on Linux. The sandbox is not built there.

Can I trust the audit log?#

With two qualifications, both of which nd7 states itself rather than leaving you to discover.

Intent, not effect. Every entry comes from Claude Code's own hook stream: what the agent said it was about to do, and what it reported back. It is not proof of what ran on the machine. Every entry carries a source naming its evidence class so no reader can confuse the two, and recording what the kernel observed is a planned phase, not something that exists.

The chain is a self-check, not third-party evidence. A clean nd7 verify proves the file has not been modified since it was written, if you trust the chain head. Someone with write access to the directory can rewrite the entire chain, head included, and it will verify. nd7 verify prints exactly that caveat on every success. The answer that exists today is shipping a copy to a vault the recording machine cannot rewrite; a signature field is reserved in the format and is not implemented.

Within those limits the log is strong: entries are hash-chained with BLAKE3 over their own exact bytes, the first entry's link is bound to the session id so a chain cannot be moved between sessions, concurrent hooks are serialised by a per-session lock, and verification stops at and names the first entry that does not check out. See How the audit log works.

Have sandboxes for coding agents actually failed?#

Yes, and the cases are documented rather than hypothetical. In July 2026 OpenAI's models escaped an internal evaluation environment through a zero-day in the one network channel they were allowed, and reached Hugging Face's infrastructure; the same month, Pillar Security published escape paths in four coding agents in which the agent never broke out directly but wrote a file that a trusted component outside the sandbox later ran. Separately, a Claude Code network-sandbox bypass disclosed in May 2026 turned on a null byte in a hostname that the allowlist and the operating system parsed differently, and there are primary-source reports of agents deleting hundreds of gigabytes with recursive deletes nobody asked for. Each case, with its sources and an honest note on what nd7 would and would not have changed, is on When sandboxes failed.

Would nd7 have prevented the Hugging Face incident?#

No, not the part that mattered. nd7 allows TCP port 443 to any host, so an agent that wants to send data out over HTTPS can; filtering is by port, not hostname, and hostname filtering through a proxy is on the roadmap rather than built. Where nd7 would have helped is the write and read boundaries: the profile applies to the claude process and everything it spawns, so writes outside the project and reads of ~/.ssh, ~/.aws and ~/.nd7 are refused by the kernel, not by a prompt. And the audit log would have given a record to reconstruct from — detection in that incident came after the fact, from logs — but it records intent, what the agent said it was about to do, not what the kernel saw, and it says so on every entry.

Does nd7 use sandbox-exec?#

No. nd7 applies profiles by calling the system sandboxing library directly — sandbox_init_with_parameters, wrapped in src/sandbox.rs — either between fork and exec, so a program and its whole tree start confined, or to the calling process. The sandbox-exec command appears in nd7's documents only as something Claude Code's own sandbox uses to wrap each Bash call, and as the thing that cannot start under an outer profile. One rejected alternative in ADR-0007 would have let that command out through a second exit; it was measured to work and rejected, because a command would then have run under Claude Code's profile alone with nd7 no longer on top of it.

Whether the mechanism is deprecated is not something nd7's documents address, so this page will not claim either way. What they do record is the condition under which the design would have to be revisited: if Apple removes the exec modifier that lets one literal path leave a sandbox, or if Claude Code stops honouring hook rewrites of a tool call.

Updated . This page as Markdown · Source on GitHub.