Secure, isolated, and rootless environments for running autonomous AI CLI agents (Hermes, Aider, Claude Code) without exposing your host system.
Modern AI coding agents are incredibly powerful, but they require execution capabilities in your terminal. If an agent is targeted by an Indirect Prompt Injection (e.g., by reading a malicious file in a public repository or a website), it could be instructed to:
- π Exfiltrate private SSH keys (
~/.ssh) or credentials. - π₯ Run destructive commands (
rm -rf /) due to a hallucination or malicious input. - π Access sensitive host processes.
A simple .gitignore style file only helps with token clutterβit is not a security boundary.
ai-agent-sandbox locks your AI agents into a hardened rootless container jail using Podman with multi-layered security verification.
- π Complete Isolation: The agent only sees the specific project folder you grant it access to. It cannot see your home directory or unapproved processes.
- π Network Lock (Optional/Default): Prevents data exfiltration by disabling network access unless explicitly enabled via
--online. - π‘οΈ Phase 1 Pre-Flight Validation: The launcher automatically checks host dependencies, validates input paths, and intercepts potentially dangerous commands before execution.
- π§Ή Clean Workspace Policy: Tool-specific data, chat histories, and configurations are mapped to a centralized host directory, keeping your project folders completely clutter-free.
- π Cloud-First Deployment: Images are automatically built via CI/CD and published to the GitHub Container Registry (GHCR). The launcher fetches them seamlessly on demand.
The host system provides a centralized configuration directory that maps dynamically to the native standard directories expected by each tool inside the container:
Host System Container (Guest)
βββ ~/.config/ai-agent-sandbox/
βββ hermes/ βββββββββββββββββββββββΊ /root/.hermes/ (shared global store: skills, config, SOUL, state.db, auth)
β βββ projects/
β βββ <sha256-of-abs-path[:12]>/
β βββ memories/ ββββββββββββββββββββΊ /root/.hermes/memories/ (project-isolated: RAG/Memory, no cross-repo bleed)
β βββ USER.md (bind-mounted :ro from global) (persona, single source of truth)
βββ aider/ βββββββββββββββββββββββΊ /root/.aider/
β βββ projects/
β βββ <sha256-of-abs-path[:12]>/ (project-isolated history/cache)
βββ claude-code/ βββββββββββββββββββββββΊ /root/.claude-code/
The launcher scopes agent memory per project directory, not per tool. A short, collision-free project key (sha256 of the project's absolute host path, truncated to 12 chars) isolates each repo's memories/ store:
- Shared global store β skills, config, persona source and tool state are mounted once for all projects (
/root/.hermesinside the container). - Project-isolated memory β only
~/.hermes/memoriesis mounted fromprojects/<key>/memories, shadowing the global folder via Podman sub-mount. Project-specific knowledge (RAG/Memory) therefore never leaks between repositories. - Persona bind-mount β the global
USER.mdis bind-mounted read-only (USER.md:Z,ro) into each project'smemories/. This is a single source of truth: editing the global persona takes effect in every project immediately, with zero drift, and projects cannot overwrite it. MEMORY.mdis deliberately NOT shared β it holds per-project knowledge and stays isolated in each project store.
Migration note: Legacy installs stored the entire
.hermestree per project under~/.config/ai-agent-sandbox/hermes/<dirname>/. On first launch with the new layout, the launcher promotes the first such legacy store once to the shared global root (skills/config/persona preserved); itsMEMORY.mdis shadowed and does not bleed into the container.
.
βββ run.sh # Universal secure launcher (with GHCR integration & Phase 1 validation)
βββ flavors/
βββ base/ # Common core layer (Ubuntu 24.04 + core utilities)
βββ hermes/ # Hermes Agent flavor layer
βββ aider/ # Aider flavor layer
βββ claude-code/ # Claude Code flavor layer
| Flavor | Target AI Agent | Default Container Command | Network Requirement |
|---|---|---|---|
hermes |
Open-source multi-agent router | hermes chat --tui |
Offline capable |
aider |
CLI Pair-Programmer | aider |
Offline capable (with local LLMs) |
claude-code |
Anthropic's official CLI Agent | claude |
Requires --online |
base |
Sandbox core environment | bash |
Offline capable |
To use this sandbox, you need Podman installed on your host system. Podman is required because it runs rootless by default, providing superior security over standard Docker setups.
sudo apt update && sudo apt install -y podmanbrew install podman
podman machine init
podman machine start- Clone the repository and run the global installer:
git clone [https://github.com/MiGoller/ai-agent-sandbox.git](https://github.com/MiGoller/ai-agent-sandbox.git) cd ai-agent-sandbox ./setup.sh - Launch any agent instantly from ANY directory on your host:
hermes aider claude
The launcher script (run.sh) connects directly to the GitHub Container Registry. You do not need to build images locally!
When executing an agent, the sandbox automatically handles the lifecycle:
- First Launch: If the image isn't available on your host, it will be pulled from GHCR automatically.
- Auto-Updates: On subsequent launches, the script performs a quick, low-overhead check against GHCR to ensure you are always running the latest, most secure image version.
If your repository or packages are set to private, ensure your local Podman client is authenticated:
echo "YOUR_GITHUB_TOKEN" | podman login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdinThe universal launcher script (run.sh) acts as a secure wrapper for your container execution.
./run.shβ Launches the default flavor (hermes) in Strict Isolation Mode (No network) using the production GHCR image../run.sh --onlineβ Enables host network mode (required for external API calls or local LLM proxies like LiteLLM)../run.sh --buildβ Enforces local compilation. It bypasses the GHCR registry and builds the container layers locally from yourflavors/directories (ideal for tweaking or development)../run.sh --localβ Switches agent memory from the global fallback (~/.config/ai-agent-sandbox) to a project-specific hidden folder (.ai_agent_sandbox_data) in your current directory.
To inspect the exact podman run command (all volume mounts, env pass-through, network mode) without starting a container, generate a sed-modified copy of the launcher and run it:
# Preview the resolved podman command (no container is started)
sed 's/^podman run /echo podman run /' run.sh > run-dry.sh && chmod +x run-dry.sh
./run-dry.sh hermes --onlineUse this to verify the per-project memory mounts (projects/<key>/memories) and the read-only persona bind-mount (USER.md:Z,ro) before launching for real. run-dry.sh is git-ignored.
To bypass the default startup command or drop into an interactive debug shell, simply append your command to the end of the script:
# Get a standard interactive bash shell inside the Aider sandbox
./run.sh aider bash
# Execute a one-off command and immediately exit
./run.sh --online hermes profile listThis project is licensed under the MIT License.