A Rust-based jail wrapper for sandboxing AI agents using podman. Provides isolation, resource limits, and workspace management for secure AI agent execution.
- 🤖 AI Agent Integration: Pre-configured support for Claude Code, GitHub Copilot CLI, Cursor Agent, Gemini CLI, Codex CLI, and Jules CLI
- 🏗️ Layered Container System: Smart image building with automatic project type detection (Rust, Go, Node.js, Python, Java, PHP, C/C++, C#, Terraform, Kubernetes)
- ⚡ Performance Optimizations: LRU cache, batch operations, parallel builds, and background pre-fetching for faster execution
- 📦 Nix Flakes Support: Automatic detection and loading of Nix development environments
- 🔄 Workspace Auto-mounting: Current directory automatically mounted to
/workspacein the jail - 🔒 Minimal Auth by Default: Claude auto-mounts only API credentials; other agents require explicit flags
- 🌍 Environment Inheritance: Automatically inherits
TERM, timezone, and SSH agent socket - 🔐 Opt-in Git/GPG: Enable git configuration and GPG signing with
--git-gpgflag - 🛡️ Resource Limits: Memory and CPU quota restrictions
- 🌐 Network Isolation: Configurable network access (disabled, private, or shared)
- 🔥 eBPF-based Host Blocking: Optional eBPF program to block container access to host IPs
- 📁 Bind Mounts: Support for read-only and read-write mounts
git clone https://github.com/cyrinux/jail-ai.git
cd jail-ai
cargo build --release
sudo cp target/release/jail-ai /usr/local/bin/For advanced network isolation using eBPF:
git clone https://github.com/cyrinux/jail-ai.git
cd jail-ai
# Build eBPF programs (requires Docker/Podman)
./build-ebpf.sh
# Build and install main binary and eBPF loader
make build-all
make install-loader
# Grant capabilities to the eBPF loader helper binary
sudo setcap cap_bpf,cap_net_admin+ep $(which jail-ai-ebpf-loader)
# Verify capabilities
getcap $(which jail-ai-ebpf-loader)eBPF Host Blocking Benefits:
- Prevents containers from accessing host network interfaces
- Uses unprivileged eBPF programs loaded by a small (~400 LOC) helper binary
- Main jail-ai binary remains unprivileged
- Requires
CAP_BPFandCAP_NET_ADMINcapabilities on the loader only
cargo install jail-aiNote: The Crates.io installation only includes the main binary. For eBPF host blocking support, install from source.
- podman - Container runtime
- Rust toolchain (for building from source)
For building with eBPF host blocking support:
- Docker or Podman - For building eBPF programs in a container
- Rust nightly - With
rust-srccomponent (installed automatically by build-ebpf.sh) - bpf-linker - eBPF linker (installed automatically by build-ebpf.sh)
# Create a jail with auto-mounted workspace (auto-builds image if needed)
jail-ai create my-agent
# Execute a command in the jail
jail-ai exec my-agent -- ls -la /workspace
# Start an interactive shell
jail-ai exec my-agent --interactive -- bash
# Claude Code with minimal auth (auto-mounts credentials only)
jail-ai claude -- chat "help me debug this code"
# GitHub Copilot with full config
jail-ai copilot --copilot-dir -- suggest "write tests"
# Cursor Agent with full config
jail-ai cursor --cursor-dir -- analyze
# Gemini CLI with full config
jail-ai gemini --gemini-dir -- --model gemini-pro "explain this"
# Codex CLI - Open interactive shell for OAuth authentication
jail-ai codex --codex-dir --auth
# Codex CLI - Run agent after authentication is complete
jail-ai codex --codex-dir -- generate "create a REST API"
# Jules CLI - Google's AI coding assistant
jail-ai jules --jules-dir -- chat "help me refactor this code"
# Start interactive shell in Claude jail (without running Claude)
jail-ai claude --shell
# Use eBPF host blocking (requires jail-ai-ebpf-loader installed)
jail-ai create my-agent --block-host
jail-ai claude --block-host -- chat "help me debug"jail-ai includes several performance optimizations for faster execution:
- LRU Cache: Caches
podman image existschecks (~85% faster for repeated checks) - Hash Memoization: Caches project hash calculations (~95% faster for repeated calls)
- Batch Operations: Groups multiple
podman inspectcalls (~75% faster)
Enable parallel building for multi-language projects:
export JAIL_AI_PARALLEL_BUILD=1
jail-ai claude # Up to 3× faster for Rust + Node.js + Python projectsEnable background pre-fetching of layers:
export JAIL_AI_PREFETCH=1
jail-ai claude # Layers build in background while you workCombine both for maximum performance:
export JAIL_AI_PARALLEL_BUILD=1
export JAIL_AI_PREFETCH=1
jail-ai claudePerformance Gains:
- Single-language projects: ~1.2× faster
- Multi-language projects: ~2.8× faster with parallel build
- Repeated operations: ~6× faster with caching
- Pre-fetching: Zero perceived latency for commonly used layers
For detailed information, see Performance Optimizations Documentation.
jail-ai uses a smart layered image system that automatically detects your project type and builds appropriate container images:
-
Base Layer (
localhost/jail-ai-base:latest)- Shell: zsh with Powerlevel10k theme, bash
- Shell enhancements: fzf, ripgrep, fd-find
- Utilities: git, vim, nano, helix, jq, tree, tmux, htop, gh CLI
-
Language Layers (built on demand)
- 🦀 Rust: cargo, clippy, rustfmt
- 🐹 Go: go toolchain
- 🟢 Node.js: npm, yarn, pnpm
- 🐍 Python: pip, black, pylint, mypy, pytest
- ☕ Java: OpenJDK, Maven, Gradle
- ❄️ Nix: Nix package manager with flakes
- 🐘 PHP: PHP 8.2, Composer, PHPUnit, PHPStan
- 🔧 C/C++: GCC, Clang, CMake, vcpkg, GDB, Valgrind
- 🎯 C#: .NET SDK 8.0, dotnet-format, EF Core tools
- 🏗️ Terraform: Terraform CLI, tflint
- ☸️ Kubernetes: kubectl, helm, k9s
-
Agent Layers (optional)
- 🤖 Claude Code:
claudeCLI - 🦾 GitHub Copilot:
copilotCLI - ➡️ Cursor:
cursor-agentCLI - 🔮 Gemini:
geminiCLI - 💻 Codex:
codexCLI - 🤖 Jules:
julesCLI (Google's AI coding assistant)
- 🤖 Claude Code:
Shared Mode (Default): Layer-based tags for efficient storage
# Base only
localhost/jail-ai-base:latest
# Base + Rust
localhost/jail-ai-agent-claude:base-rust
# Base + Rust + Node.js + Claude
localhost/jail-ai-agent-claude:base-rust-nodejsIsolated Mode: Workspace-specific images
jail-ai claude --isolated # Uses: localhost/jail-ai-agent-claude:abc12345Default Behavior (Minimal Auth):
jail-ai claude→ Auto-mounts~/.claude/.credentials.json(API keys only)jail-ai copilot→ No auth mounted (use--copilot-dir)jail-ai cursor→ No auth mounted (use--cursor-dir)jail-ai gemini→ No auth mounted (use--gemini-dir)jail-ai codex→ No auth mounted (use--codex-dir)jail-ai jules→ No auth mounted (use--jules-dir)
Opt-in Mounting:
--claude-dir: Mount entire~/.claudedirectory (settings, history)--copilot-dir: Mount~/.config/.copilotdirectory--cursor-dir: Mount~/.cursorand~/.config/cursordirectories--gemini-dir: Mount~/.geminidirectory--codex-dir: Mount~/.codexdirectory- First Run: When
--codex-dir(or--agent-configs) is specified and credentials are missing, automatically enters auth mode - Manual Auth: Use
--authto re-authenticate or update credentials (joins running container or starts stopped one)
- First Run: When
--jules-dir: Mount~/.config/julesdirectory- First Run: When
--jules-dir(or--agent-configs) is specified and credentials are missing, automatically enters auth mode - Manual Auth: Use
--authto re-authenticate or update credentials
- First Run: When
--agent-configs: Mount all of the above
Use --git-gpg flag to enable:
Git Configuration:
- Mounts local
.git/configor creates.gitconfigfrom your git settings - Includes:
user.name,user.email,user.signingkey - Enables GPG signing:
commit.gpgsign,tag.gpgsign
GPG Configuration:
- Mounts
~/.gnupgdirectory - Auto-mounts all GPG agent sockets:
S.gpg-agent- Main GPG agent socketS.gpg-agent.ssh- SSH authentication socketS.gpg-agent.extra- Extra GPG agent socketS.gpg-agent.browser- Browser GPG agent socket
- Supports SSH-based GPG signing (
gpg.format=ssh)
# Claude with full config + git/GPG
jail-ai claude --claude-dir --git-gpg -- chat "make a commit"jail-ai includes optional eBPF-based network filtering to prevent containers from accessing host network interfaces.
- Uses eBPF programs attached to the container's network namespace
- Blocks all traffic to host IP addresses (both IPv4 and IPv6)
- Loaded by a small privileged helper binary (
jail-ai-ebpf-loader) - Main
jail-aibinary remains unprivileged
See the From Source (With eBPF Host Blocking) installation section.
Required Capabilities:
The eBPF loader helper requires these capabilities:
sudo setcap cap_bpf,cap_net_admin+ep $(which jail-ai-ebpf-loader)CAP_BPF: Load eBPF programsCAP_NET_ADMIN: Attach eBPF programs to network interfaces
Use the --block-host flag when creating a jail:
# Create jail with host blocking
jail-ai create my-agent --block-host
# Use with AI agents
jail-ai claude --block-host -- chat "help me debug"
jail-ai copilot --copilot-dir --block-host -- suggest "write tests"- Helper Binary: Small (~400 LOC), easy to audit, runs with elevated capabilities
- Main Binary: Unprivileged, handles all user interaction and container management
- eBPF Programs: Verified by kernel, cannot crash or compromise system
- Automatic Cleanup: eBPF programs are automatically detached when container stops
# Debug build (default workspace members only, excludes eBPF)
cargo build
make build
# Release build
cargo build --release
# Build with eBPF support
./build-ebpf.sh # Build eBPF programs in container
make build-loader # Build eBPF loader helper
make install-loader # Install and set capabilities
# Build everything (main binary, eBPF programs, and loader)
make build-all
# Run
cargo run -- <args>
make run ARGS="<args>"# Run all tests
cargo test
make test
# Run specific test
cargo test <test_name>
# Lint
cargo clippy -- -D warnings
make clippy
# Format
cargo fmt
make fmt# Build custom AI agent image
make build-image
# Test image
make test-image
# Clean image
make clean
# Custom image name/tag
make build-image IMAGE_NAME=custom-name IMAGE_TAG=version- CLAUDE.md - Claude Code guidelines for this project
- docs/specs/ - Technical specifications and implementation details
- IMAGE_TAGGING_STRATEGY.md - Image naming and tagging strategy
- LAYERED_IMAGES_SUMMARY.md - Layered image system overview
- NIX_FLAKES_SUPPORT.md - Nix flakes integration
- GIT_CONFIG_VERIFICATION_REPORT.md - Git config mapping details
- IMPLEMENTATION_SUMMARY.md - Implementation details
- docs/ - Man pages and additional documentation
The container uses zsh as the default shell with:
- Powerlevel10k (p10k) - Fast, minimal theme with git integration
- fzf integration:
Ctrl+R- Search command historyCtrl+T- Search files in current directoryAlt+C- Change to subdirectory
- Smart history - 10000 entries with deduplication
- Useful aliases -
llfor detailed listing, colored ripgrep
Contributions are welcome! Please follow these guidelines:
- Use conventional commits with emoji to distinguish commit types
- Run
cargo clippyandcargo fmtbefore committing - Add tests for new features
- Update documentation as needed
- Build before committing
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
- Built with Rust 🦀
- Powered by podman containers
- Inspired by the need for secure AI agent sandboxing
- Repository: https://github.com/cyrinux/jail-ai
- Author: Cyril Levis [email protected]
- Author: Max Baz [email protected]
Made with ❤️ and Rust