Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 131 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,109 @@
# egg

Sandboxed LLM code execution environment with infrastructure-level security controls.
A hardened sandbox for autonomous LLM code agents with infrastructure-enforced security controls.

**The core principle:** Security through infrastructure, not instructions. An LLM cannot bypass controls that don't exist in its environment.
> *Inspired by Andy Weir's short story "The Egg" - a contained environment where development happens before emerging into the world. The AI agent works inside the egg; when ready, it "hatches" via human review and merge.*

## The Core Principle

**Security through infrastructure, not instructions.**

Behavioral controls (telling an LLM "don't do X") can be bypassed through prompt injection, jailbreaks, or model drift. egg enforces security at the infrastructure level - the agent physically cannot perform unauthorized actions because the capabilities don't exist in its environment.

## What Makes egg Robust

| Threat | How egg Prevents It |
|--------|---------------------|
| Agent steals credentials | Credentials never enter the sandbox - gateway injects them at request time |
| Agent pushes to main | Gateway enforces branch policies; agent can only push to `egg/*` branches |
| Agent merges its own PR | Gateway has no merge endpoint - humans must merge via GitHub UI |
| Agent exfiltrates code | Private mode restricts network to Anthropic API + private GitHub repos only |
| Agent accesses other workspaces | Each agent gets isolated git worktree; `.git/` is shadowed |
| Agent bypasses controls via git config | Sandbox has no git metadata - all git ops go through gateway |

## Architecture

```
┌─────────────────────────────────────────────────────────────────────────────┐
│ egg │
│ │
│ ┌───────────────────────────┐ ┌───────────────────────────────┐ │
│ │ Gateway Sidecar │ │ Sandbox Container │ │
│ │ (Trusted) │ │ (Untrusted) │ │
│ │ │ │ │ │
│ │ ┌─────────────────────┐ │ HTTP │ ┌─────────────────────────┐ │ │
│ │ │ Git/GH Policy │◄─┼──────────┼──│ git/gh wrappers │ │ │
│ │ │ Engine │ │ API │ │ (intercept all ops) │ │ │
│ │ └─────────────────────┘ │ │ └─────────────────────────┘ │ │
│ │ │ │ │ │
│ │ ┌─────────────────────┐ │ API │ ┌─────────────────────────┐ │ │
│ │ │ Anthropic Proxy │◄─┼──────────┼──│ Claude Code │ │ │
│ │ │ (credential inject) │ │ Proxy │ │ (ANTHROPIC_BASE_URL) │ │ │
│ │ └─────────────────────┘ │ │ └─────────────────────────┘ │ │
│ │ │ │ │ │
│ │ ┌─────────────────────┐ │ HTTPS │ ┌─────────────────────────┐ │ │
│ │ │ HTTP Proxy (Squid) │◄─┼──────────┼──│ All outbound traffic │ │ │
│ │ │ (domain allowlist) │ │ Proxy │ │ (private mode) │ │ │
│ │ └─────────────────────┘ │ │ └─────────────────────────┘ │ │
│ │ │ │ │ │
│ │ HAS: │ │ HAS: │ │
│ │ - GitHub tokens │ │ - Workspace files only │ │
│ │ - Anthropic API keys │ │ - Isolated git worktree │ │
│ │ - Full network access │ │ │ │
│ │ │ │ NO: │ │
│ │ │ │ - Credentials (any kind) │ │
│ │ │ │ - Git metadata (.git/) │ │
│ │ │ │ - Direct network (private) │ │
│ └───────────────────────────┘ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```

## Key Features

### Zero Credential Exposure

The sandbox container **never** has access to credentials:
- **Anthropic API**: Requests route through gateway via `ANTHROPIC_BASE_URL`; gateway injects API key
- **GitHub**: All git/gh commands intercepted by wrappers that call gateway API; gateway injects tokens
- **No environment leakage**: Container environment is sanitized of credential variables

### Git Isolation via Gateway-Managed Worktrees

Each agent session gets a fully isolated workspace:
- **Isolated worktree**: Own branch, own staging area, no visibility into other agents' work
- **Shadowed `.git/`**: Container sees empty `.git/` directory (tmpfs mount) - cannot access git metadata
- **Gateway controls all git state**: Branch creation, commits, pushes all validated by gateway

### Granular Access Control

The gateway enforces fine-grained policies on every operation:
- **Branch ownership**: Agents can only push to branches with configured prefix (default: `egg/`)
- **Protected branches**: Direct pushes to main/master blocked; must go through PR
- **No merge capability**: Gateway has no merge endpoint - humans must review and merge
- **Blocked operations**: Force push, `git config --global`, remote manipulation all blocked

### Public and Private Network Modes

| Mode | Network Access | Use Case |
|------|----------------|----------|
| **Public** | Full internet + credential-injected API calls | Open source work, package installation |
| **Private** | Anthropic API + private GitHub repos only | Confidential code, sensitive data |

In private mode:
- All traffic routes through Squid proxy with strict domain allowlist
- Only private GitHub repositories are accessible (public repos blocked)
- WebSearch, WebFetch tools are blocked
- No package manager access (dependencies pre-installed in image)
- Data exfiltration to arbitrary endpoints is impossible

### Comprehensive Audit Trail

Every operation through the gateway is logged:
- Git operations (status, diff, commit, push)
- GitHub CLI operations (PR create, comment)
- Policy violations (attempted, blocked)
- Session lifecycle

## Quick Start

Expand All @@ -12,53 +113,18 @@ git clone https://github.com/jwbron/egg.git
cd egg
./dev setup

# Start the sandbox
egg start --config egg.yaml
```
# Configure credentials
cp secrets.yaml.example ~/.config/egg/secrets.yaml
# Edit with your GitHub App / PAT and Anthropic credentials

## Architecture
# Start the sandbox (public mode)
egg start --config egg.yaml

```
┌─────────────────────────────────────────────────┐
│ egg │
│ │
┌──────────────────────┼───────────────────┐ ┌───────────────────────┤
│ Gateway Container │ │ │ Sandbox Container │
│ │ │ │ │
│ ┌─────────────┐ │ │ │ ┌─────────────┐ │
│ │ REST API │◄────┼───────────────────┼────┼──│ git wrapper │ │
│ │ Server │ │ │ │ └─────────────┘ │
│ └─────────────┘ │ │ │ │
│ │ │ │ ┌─────────────┐ │
│ ┌─────────────┐ │ │ │ │ gh wrapper │ │
│ │ Policy │ │ │ │ └─────────────┘ │
│ │ Engine │ │ │ │ │
│ └─────────────┘ │ │ │ ┌─────────────┐ │
│ │ │ │ │ LLM CLI │ │
│ ┌─────────────┐ │ │ │ │ (Claude) │ │
│ │ HTTP Proxy │◄────┼───────────────────┼────┼──│ │ │
│ │ (Squid) │ │ │ │ └─────────────┘ │
│ └─────────────┘ │ │ │ │
│ │ │ │ NO: GitHub tokens │
└──────────────────────┼───────────────────┘ │ NO: SSH keys │
│ │ NO: Direct network │
│ │ YES: Workspace files │
│ │ YES: LLM API (proxy) │
│ └───────────────────────┤
│ │
└─────────────────────────────────────────────────┘
# Start with network lockdown (private mode)
egg start --config egg.yaml --private
```

## Features

- **Gateway Sidecar**: All git/gh operations routed through a policy-enforcing gateway
- **Network Isolation**: Configurable domain allowlists for both public and private modes
- **Session-based Access**: Per-container session tokens for multi-container environments
- **Audit Logging**: Structured logs for all operations with correlation IDs
- **Worktree Isolation**: Per-container git worktrees preventing cross-contamination
- **Credential Isolation**: Sandbox container never has direct credential access

## CLI Commands
## CLI Reference

| Command | Description |
|---------|-------------|
Expand All @@ -69,40 +135,38 @@ egg start --config egg.yaml
| `egg status` | Show running containers and health status |
| `egg config validate` | Validate configuration files |

### CLI Flags for `egg start`
### Flags for `egg start`

| Flag | Description |
|------|-------------|
| `--config <path>` | Path to egg.yaml config file (default: `./egg.yaml`) |
| `--private` | Enable private network mode (blocks all external network except Claude API) |
| `--headless` | Run in non-interactive/headless mode (for automation, CI, scripted workflows) |
| `--private` | Enable private mode (Anthropic API + private GitHub repos only) |
| `--headless` | Run in non-interactive mode (for automation, CI) |

## Documentation

- [Architecture](docs/architecture.md)
- [Configuration](docs/configuration.md)
- [Security Model](docs/security.md)
- [API Reference](docs/api.md)
- [Setup Guide](docs/setup.md)
- [Testing Guide](docs/testing.md)
- [Troubleshooting](docs/troubleshooting.md)

## Development
- [Architecture](docs/architecture.md) - System design and component overview
- [Security Model](docs/security.md) - Threat model and security guarantees
- [Configuration](docs/configuration.md) - Configuration file reference
- [Setup Guide](docs/setup.md) - First-time setup walkthrough
- [API Reference](docs/api.md) - Gateway REST API documentation
- [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions

```bash
# Set up development environment
./dev setup
### Architecture Decision Records

# Run linters (same as CI)
./dev lint
- [Git Isolation Architecture](docs/adr/git-isolation-architecture.md) - Worktree isolation design
- [Credential Injection](docs/adr/credential-injection.md) - Zero-credential sandbox design
- [Network Isolation](docs/adr/network-isolation.md) - Public/private mode implementation

# Run tests (same as CI)
./dev test
## Development

# Run full CI pipeline locally
./dev ci
```bash
./dev setup # Set up development environment
./dev lint # Run linters
./dev test # Run tests
./dev ci # Run full CI pipeline locally

# Fast mode (native, no Docker overhead)
# Fast mode (native Python, no Docker)
./dev native lint
./dev native test
```
Expand Down
Loading
Loading