Tvijo wiki
Catalog

Topics

Letting an agent run shell commands: use a sandbox or refuse

A shell tool is the most powerful thing you can hand to an agent. Wrap every command in an operating-system sandbox, and if no sandbox is available, refuse to run instead of running unprotected. Make the unsafe switch explicit, loud and off by default.

🎯 For A developer who gives an agent a shell or code execution tool

πŸ“š You will learn
  • What a minimal sandbox for agent commands isolates
  • Why the default must be refusal when no sandbox exists
  • How to keep an escape hatch from becoming the normal path

🐚 Why the shell is different

Most tools do one thing. A shell tool does anything the account can do: read keys, delete a directory, open a network connection, start a background process. An agent that can run commands is only as safe as the box around those commands, because its instructions come from text that may include text it should not trust.

🧱 What our sandbox does

Our agent shell tool never runs a command directly. It wraps it with an isolation program, bwrap first and firejail as the alternative. With bwrap the wrapper does the following.

  • It starts with an empty root file system in memory, then adds only what the command needs, mounted read-only: the system programs and libraries.
  • It makes only the allowed work folders writable, and creates the working directory inside them.
  • It isolates the process list, inter-process communication and host name from the rest of the machine.
  • It cuts the network unless the call explicitly allows it.
  • It dies with its parent, so a stuck command does not outlive the agent.

The list of allowed work folders is configured, and a path outside it is refused before the wrapper starts.

🚫 The important part: no sandbox, no run

If neither isolation program is installed, the tool does not fall back to running the command bare. It returns an error named no_sandbox_available and does nothing. This is the decision recorded in our design note of 23 May 2026: a safe default that fails closed.

An escape hatch exists, because a developer laptop may have no isolation program: an environment variable that allows commands without isolation. Using it writes a warning on each run, and every call, allowed or refused, is written to an audit record with the isolator used. Keep the switch out of service definitions. The point is the shape: the dangerous mode needs a deliberate, visible act, and the safe mode needs none.

πŸ› οΈ Practice: wrap your own shell tool

  1. Decide which folders a command may write to, and write them down in one setting.
  2. Install an isolation program on every host that runs agents. Check with a script that prints which one it found.
  3. Write the wrapper so that the command list goes into the isolation program as arguments, never as a string for a second shell.
  4. Cut the network by default. Add a per-call flag for the few commands that need it, and log each use.
  5. Make the tool return a clear error when no isolation program is found. Do not add a silent fallback.
  6. Add one environment switch for unsafe mode. Make it print a warning every time and keep it out of production units.
  7. Write tests: a write outside the allowed folders fails, a network call fails, a missing isolation program refuses.

βœ… Check yourself

  • Run a command that writes to your home directory. It fails.
  • Run a command that opens a network connection. It fails unless the call allowed the network.
  • Remove the isolation program on a test host. The tool refuses with a named error.
  • Search your service definitions for the unsafe switch. It is not there.

🚧 When this does NOT work

  • Escapes through allowed folders. Whatever you make writable, the agent can change. Do not put the repository root, your home directory or a folder with keys in the list.
  • Network on. If a command needs the network, it can send out anything it can read. Allow it for named commands only.
  • Kernel-level bugs. A sandbox reduces risk and is not a guarantee. Keep the host patched and do not run it as the most privileged account.
  • Slow commands. Isolation adds start-up time. Do not skip it to save milliseconds.
  • Containers hiding the problem. If the agent already runs in a throw-away container, a second layer may add little. Decide that explicitly and write it down.

πŸ“Š Evidence

On 3 November 2026, 21:53 UTC the shell tool listed two isolation programs in its code. On the host that produced this page, bwrap was installed and firejail was not installed. The shell sandbox test file held 14 tests and the general tools test file 11.

What we measured Isolation options in the tool code, their presence on this host, and test counts
When 3 November 2026, 21:53 UTC
Artifact The shell tool module, its sandbox test file and the design note of 23 May 2026 in our private repository
Limit Counts show that the behaviour is tested, not that no escape exists

➑️ Next

Read what an agent may touch in Permissions and data flow, and the decisions in Agent shell access: decision forks.

Sources

πŸ”— Article connections

Open the full knowledge graph β†—

Published article links. Select a node to open its article at the heading.

100%
β†’ Linked articles← Linked fromβ‹― Same topic
Article links Β· keyboard / text view

πŸ’¬ Comments

Comments are public and moderated. Do not post personal data.
  • No comments yet. Be the first!

Next steps