DEV Community

Malik Taimoor Awan
Malik Taimoor Awan

Posted on

Why You Shouldn't Let AI Agents Run Naked Bash: Building an Unprivileged Sandbox in Rust

What If Your AI Coding Agent Deletes Your Project? Building a Zero-Trust Sandbox with Rust

AI coding agents are becoming an important part of modern software development.

Tools like Claude Code, OpenAI Codex, Aider, OpenHands, Cursor, and other autonomous coding agents can execute terminal commands, modify source files, install dependencies, and run scripts.

But there is one important question:

What happens when an AI agent executes a dangerous command on your actual development machine?

Imagine an agent accidentally:

  • Deletes important project files.
  • Overwrites your .env configuration.
  • Reads SSH keys or cloud credentials.
  • Modifies Git history.
  • Executes an untrusted installation script.
  • Makes unexpected outbound network connections.

A simple confirmation prompt isn't always enough.

I started building ShadowCLI to explore a different approach: putting a zero-trust security boundary between AI coding agents and the developer's machine.

Introducing ShadowCLI

GitHub: https://github.com/6t9xstar/shadowcli

ShadowCLI is an open-source, Rust-based execution sandbox for AI coding agents.

Instead of allowing commands to modify your actual project immediately, ShadowCLI executes them inside an isolated Linux environment.

Changes are captured in a temporary copy-on-write layer. Developers can inspect the resulting differences, review modifications, approve changes, or discard the session.

The goal is simple:

Let AI agents work, but keep developers in control of what reaches their actual projects.

How Does It Work?

ShadowCLI uses multiple Linux security mechanisms to isolate command execution.

Its architecture combines:

  1. Linux User Namespaces – Isolate user and group identities.
  2. Mount Namespaces – Provide a private filesystem view.
  3. PID Namespaces – Isolate processes.
  4. Network Namespaces – Restrict outbound network access by default.
  5. Landlock LSM – Enforce filesystem access restrictions.
  6. Seccomp BPF – Block selected high-risk system calls.
  7. OverlayFS / CopyFS – Capture filesystem modifications without directly changing the host project during execution.

These layers work together to create a defense-in-depth execution environment.

Getting Started

ShadowCLI is designed for Linux systems with the required kernel and sandbox capabilities.

1. Clone the repository

git clone https://github.com/6t9xstar/shadowcli.git

cd shadowcli
Enter fullscreen mode Exit fullscreen mode

2. Build the project

You need Rust 1.80 or later.

cargo build --release
Enter fullscreen mode Exit fullscreen mode

3. Install the binary

sudo cp target/release/shadow /usr/local/bin/
Enter fullscreen mode Exit fullscreen mode

4. Check system compatibility

shadow doctor
Enter fullscreen mode Exit fullscreen mode

This checks important system capabilities, including kernel compatibility, user namespaces, Landlock, Seccomp, and filesystem support.

5. Run a command inside the sandbox

shadow run -- npm test
Enter fullscreen mode Exit fullscreen mode

By default, outbound network access is blocked.

If a task requires network access, you can explicitly allow it:

shadow run --allow-network -- cargo build
Enter fullscreen mode Exit fullscreen mode

You can also configure execution timeouts:

shadow run --timeout 30 -- ./agent-script.sh
Enter fullscreen mode Exit fullscreen mode

Inspect Changes Before Applying Them

One of the most important parts of ShadowCLI is its review workflow.

After an agent executes commands, inspect the captured changes:

shadow diff
Enter fullscreen mode Exit fullscreen mode

View a summary:

shadow diff --stat
Enter fullscreen mode Exit fullscreen mode

Review modifications interactively:

shadow review
Enter fullscreen mode Exit fullscreen mode

Apply approved changes:

shadow apply --all --yes
Enter fullscreen mode Exit fullscreen mode

If you need to undo the most recent apply operation:

shadow apply --rollback
Enter fullscreen mode Exit fullscreen mode

Or discard unapplied sandbox changes:

shadow discard
Enter fullscreen mode Exit fullscreen mode

This creates a workflow where executing commands and accepting their modifications are separate decisions.

Who Can Use ShadowCLI?

ShadowCLI is designed as a general execution boundary for tools that execute terminal commands.

Potential integration targets include:

  • Claude Code
  • OpenAI Codex
  • Aider
  • OpenHands
  • Gemini CLI
  • OpenCode
  • Cline
  • Roo Code
  • Custom AI coding agents

For example, you can wrap a terminal-based agent command:

shadow run -- aider
Enter fullscreen mode Exit fullscreen mode

You can also integrate sandboxed command execution into your own Python-based agent:

import subprocess

result = subprocess.run(
    [
        "shadow",
        "run",
        "--project",
        ".",
        "--allow-network",
        "--",
        "npm",
        "test"
    ],
    capture_output=True,
    text=True
)

print(result.stdout)
print(result.stderr)
Enter fullscreen mode Exit fullscreen mode

Actual compatibility depends on how an agent interacts with the filesystem and launches subprocesses.

Security Is More Than a Confirmation Prompt

I believe AI-assisted development needs more than a simple permission dialog.

A secure execution workflow should consider:

  • Filesystem isolation.
  • Credential protection.
  • Network restrictions.
  • Process isolation.
  • System call restrictions.
  • Change inspection.
  • Explicit approval.
  • Recovery and rollback.

ShadowCLI brings these ideas together using native Linux security technologies and Rust.

It is not a replacement for security auditing, backups, or a hardened virtual machine. Its protection also depends on the host kernel, filesystem, configuration, and the correctness of its isolation mechanisms.

Open Source and Contributions

ShadowCLI is released under the Apache-2.0 license.

I'm continuing development and would appreciate feedback from developers working with:

  • Rust and Linux systems programming.
  • AI coding agents.
  • Linux kernel security.
  • Sandboxing and container isolation.
  • DevSecOps and application security.

If you're interested in this area, explore the repository, review the implementation, report issues, or contribute improvements.

GitHub Repository: https://github.com/6t9xstar/shadowcli

I'd particularly like to hear your thoughts:

Would you trust an AI coding agent with unrestricted access to your development machine, or would you prefer every modification to go through an isolated execution and review process?

Let's discuss.

Top comments (6)

Collapse
 
florian131313 profile image
G •

Clone and cargo build are not enough on Debian or Ubuntu. Unprivileged user namespaces stay off by default there, a sysctl on Debian and an AppArmor switch on Ubuntu 24.04, so the namespace stack in the post never starts. shadow doctor is the check that shows it.

Collapse
 
6t9 profile image
Malik Taimoor Awan •

Thanks everyone — these are exactly the kinds of real-world edge cases I want ShadowCLI to be tested against.

The namespace setup requirements need clearer distro-specific documentation; shadow doctor is the starting point, but the install guidance should do more to explain host prerequisites.

The current staging/review model covers filesystem changes made by commands routed through ShadowCLI. It does not capture or roll back external side effects from desktop-control tools, logged-in browsers, or other MCP servers. Those need separate account isolation and action-approval controls.

And the package-cache, OverlayFS, and Git-index points are excellent performance and compatibility items. I’m adding them to the investigation list rather than assuming the current behavior is optimal.

Appreciate the thoughtful feedback — this is how the project gets more robust.

Collapse
 
autenai profile image
Auten •

Does the staging layer also cover tools that never touch the shell, like an MCP server that clicks around a desktop or a logged-in browser? A sent email or a submitted form can't be diffed and rolled back like a file.

For screen-control agents (Auten team here, that's what we build) the closest thing we've found is a separate desktop user holding only the accounts the task needs, plus keeping the client's approval prompt on for send, buy and delete.

Collapse
 
6t9 profile image
Malik Taimoor Awan •

Thanks everyone — these are exactly the kinds of real-world edge cases I want ShadowCLI to be tested against.

The namespace setup requirements need clearer distro-specific documentation; shadow doctor is the starting point, but the install guidance should do more to explain host prerequisites.

The current staging/review model covers filesystem changes made by commands routed through ShadowCLI. It does not capture or roll back external side effects from desktop-control tools, logged-in browsers, or other MCP servers. Those need separate account isolation and action-approval controls.

And the package-cache, OverlayFS, and Git-index points are excellent performance and compatibility items. I’m adding them to the investigation list rather than assuming the current behavior is optimal.

Appreciate the thoughtful feedback — this is how the project gets more robust.

Collapse
 
reidmarlow profile image
Reid Marlow •

Beyond the unprivileged namespace sysctl, the piece that usually catches people with OverlayFS and coding agents is package caching.

If the agent runs cargo build or npm install inside the scratch layer, the upper directory ends up capturing hundreds of megabytes of downloaded crates and node_modules alongside the actual code diff. Unless you explicitly bind-mount the host global cache read-only into ~/.cargo and ~/.cache, the sandbox re-downloads the world on every attempt, and walking thousands of tiny files across the overlay copy-on-write layer kills disk latency.

The other quirk to watch is git index writes. Some tools rely on hardlinks or atomic renames within the working tree, which can trigger cross-device link errors across overlayfs layers unless the mount specifically enables index and metacopy options.

Collapse
 
6t9 profile image
Malik Taimoor Awan •

Thanks everyone — these are exactly the kinds of real-world edge cases I want ShadowCLI to be tested against.

The namespace setup requirements need clearer distro-specific documentation; shadow doctor is the starting point, but the install guidance should do more to explain host prerequisites.

The current staging/review model covers filesystem changes made by commands routed through ShadowCLI. It does not capture or roll back external side effects from desktop-control tools, logged-in browsers, or other MCP servers. Those need separate account isolation and action-approval controls.

And the package-cache, OverlayFS, and Git-index points are excellent performance and compatibility items. I’m adding them to the investigation list rather than assuming the current behavior is optimal.

Appreciate the thoughtful feedback — this is how the project gets more robust.