Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pi-sandbox

A secured agent workspace: herdr (terminal multiplexer) + pi (coding agent) + Kaimon (Julia MCP server), all running inside a bubblewrap sandbox with deny-by-default filesystem, runtime, and environment policies — plus enforced secure defaults for package installs and per-project containment for agents.

        ┌─────────────────────────────────────────────────┐
        │  HOST                                            │
        │  ./sandbox.sh ──► bubblewrap (deny-by-default)   │
        │   ┌───────────────────────────────────────────┐  │
        │   │  SANDBOX                                  │  │
        │   │  herdr (PID 1)  ── TUI, panes, workspaces │  │
        │   │   ├─ pane: pi agent                       │  │
        │   │   │    └─ (optional) pi-bwrap: NESTED     │  │
        │   │   │       bwrap scoped to one project     │  │
        │   │   ├─ pane: kaimon MCP server (Julia,      │  │
        │   │   │    localhost:2828) ◄─ MCP ── pi        │  │
        │   │   └─ panes: shells (fish, own history)    │  │
        │   └───────────────────────────────────────────┘  │
        └─────────────────────────────────────────────────┘

What's in the repo

File Contents
sandbox.sh the bubblewrap policy: mounts, env allowlist, hardened defaults, --check probe
sandbox-project.sh optional wrapper: scope the whole sandbox to one project
README.md this overview
HERDR.md herdr session layout + the kaimon auto-start hook
SANDBOX.md the sandbox policy, deep dive: mounts, env, hardening, troubleshooting
PI.md pi installation, MCP setup (Kaimon), plugins, extensions, skills

How it's secured

Three independent layers — a leak on any one of them defeats the other two, so all three matter:

  1. Containment (SANDBOX.md). Deny-by-default on every axis: no read-only bind of / (the root filesystem is enumerated, only allowlisted paths are visible); $HOME is masked with a private tmpfs and rebound one path at a time; /run is masked (no session bus, keyring, gpg, or docker sockets); --clearenv keeps every credential out of the environment. No tokens, no SSH keys, no token stores ever enter the sandbox.
  2. Supply-chain defaults (SANDBOX.md). npm runs with an enforced read-only ~/.npmrc (ignore-scripts=true, min-release-age=7) and uv with a forced UV_EXCLUDE_NEWER=7 days — a poisoned registry package can't run install scripts and fresh typosquats are gated out. The host's npm/uv config is never even visible inside.
  3. Per-project agent containment (pi-bwrap, SANDBOX.md). herdr sees all of ~/Git, but an agent launched with pi-bwrap gets a nested bwrap that hides ~/Git except the project it was launched in — a rogue agent can only read/poison the one project it's working on, and never even sees sibling repos.

Quickstart

./sandbox.sh                # attach to the sandboxed herdr session
./sandbox.sh --check        # policy probe — run after every sandbox.sh edit
./sandbox-project.sh [dir]  # optional: sandbox scoped to one project
cd ~/Git/my-project && pi-bwrap   # agent scoped to that one project

HERDR.md explains the two workspaces (pi-sandbox for agents, kaimon for the MCP server TUI) and why kaimon auto-starts.


Security posture in one paragraph: the sandbox contains secrets, not code — code execution inside is routine and expected (agents, Julia builds, pip installs), so containment is about making exfiltration worthless (nothing credentialed is reachable) and blast radius small (one project per agent). The remaining trust-based boundaries are documented honestly in SANDBOX.md: the ssh-agent forwarding (a live signing oracle, deliberate for git push) and the fact that a rogue agent could still modify the one project the host IDE has open.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages