8  Containerization

8.1 Overview

Pi does not include a built-in sandbox. This is an intentional design decision: real isolation must come from the operating system or a virtualization/container boundary. This chapter describes three common patterns for running Pi in isolated environments.

8.2 Why Containerize?

When working with untrusted repositories, generated code you do not intend to monitor closely, or unattended automation, you should run Pi inside a contained environment. Containerization provides:

  • Filesystem isolation — limit which host directories the agent can access
  • Credential isolation — pass only the minimum required API keys
  • Network isolation — restrict outbound connections when not needed
  • Process isolation — prevent unwanted side effects on the host system
Warning

If you bind-mount a host workspace read/write, writes from inside the container or VM can still modify host files. Use read-only mounts or copy files into and out of the sandbox when you need stronger protection from unintended writes.

8.3 Three Isolation Patterns

graph TD
    A[Pi Isolation Patterns] --> B[Gondolin]
    A --> C[Plain Docker]
    A --> D[OpenShell]
    B --> B1[Host Pi + Micro-VM Tools]
    C --> C1[Whole Pi in Container]
    D --> D1[Policy-Controlled Sandbox]

Pattern What Is Isolated Best For
Gondolin Built-in tools and ! commands Local micro-VM with host auth
Plain Docker Whole Pi process Simple local isolation
OpenShell Whole Pi process in policy-controlled sandbox Local or remote managed sandbox

8.4 Pattern 1: Gondolin

Gondolin is a micro-VM extension that routes built-in tool execution (read, write, edit, bash) and editor ! commands into an isolated virtual machine. The Pi process itself runs on the host, which means authentication, settings, and sessions remain on the host filesystem.

8.4.1 How It Works

graph LR
    H[Host Pi Process] --> G[Gondolin Extension]
    G --> M[Micro-VM]
    M --> FS[Isolated Filesystem]
    M --> SH[Isolated Shell]
    H --> AUTH[Host Auth & Sessions]

8.4.2 Configuration

Install the Gondolin extension and configure it to route tool calls:

# Install Gondolin
pi install npm:@earendil-works/gondolin

# Or place in ~/.pi/agent/extensions/gondolin.ts

8.4.3 When to Use Gondolin

  • You want host-based authentication and session management
  • You need fine-grained control over which tools run in isolation
  • You want to keep your host credentials and settings intact
  • You need quick startup without full container overhead

8.4.4 Limitations

  • Extension code itself runs on the host
  • Only built-in tool calls are routed to the micro-VM
  • Custom extensions that access the filesystem directly bypass the VM
Note

The Gondolin extension is available in the Pi examples directory. See examples/extensions/gondolin/ for the full implementation.

8.5 Pattern 2: Plain Docker

Run the entire Pi process inside a Docker container. This provides complete isolation of the Pi process, including all extensions, tools, and session data.

8.5.1 Basic Dockerfile

FROM node:22-slim

# Install Pi
RUN npm install -g --ignore-scripts @earendil-works/pi-coding-agent

# Set working directory
WORKDIR /workspace

# Copy project files
COPY . /workspace

# Run Pi
ENTRYPOINT ["pi"]

8.5.2 Running the Container

# Build the image
docker build -t pi-agent .

# Run interactively with mounted workspace
docker run -it --rm \
  -v $(pwd):/workspace \
  -v ~/.pi/agent/auth.json:/root/.pi/agent/auth.json:ro \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  pi-agent

# Run in print mode
docker run --rm \
  -v $(pwd):/workspace \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  pi-agent -p "Summarize this codebase"

8.5.3 Mounting Strategies

# Read-only workspace (agent can read but not modify)
docker run -it --rm \
  -v $(pwd):/workspace:ro \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  pi-agent

# Isolated sessions (do not persist sessions to host)
docker run -it --rm \
  -v $(pwd):/workspace \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  pi-agent --no-session

# Persist sessions to a named volume
docker run -it --rm \
  -v $(pwd):/workspace \
  -v pi-sessions:/root/.pi/agent/sessions \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  pi-agent
Tip

Avoid mounting host ~/.pi/agent unless the container should access host sessions, settings, and credentials. Instead, pass only the specific auth file or environment variables needed.

8.5.4 When to Use Plain Docker

  • You want simple, complete isolation of the Pi process
  • You need reproducible environments across machines
  • You want to run Pi in CI/CD pipelines
  • You need quick disposable environments

8.6 Pattern 3: OpenShell

OpenShell provides a policy-controlled sandbox environment for running Pi. It offers the strongest isolation guarantees and supports both local and remote managed sandboxes.

8.6.1 How It Works

OpenShell wraps the entire Pi process in a sandbox with configurable policies controlling filesystem access, network access, and resource limits.

8.6.2 Configuration

# Install OpenShell CLI
# Follow OpenShell installation instructions

# Run Pi inside OpenShell
openshell run --mount /path/to/workspace \
  --env ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  --network restricted \
  --memory 4g \
  -- pi

8.6.3 Policy Configuration

# openshell-policy.yaml
mounts:
  - source: /path/to/workspace
    target: /workspace
    mode: read-write
  - source: /path/to/reference
    target: /reference
    mode: read-only

network:
  outbound:
    - host: api.anthropic.com
      port: 443
    - host: api.openai.com
      port: 443
  default: deny

resources:
  memory: 4g
  cpu: 2
  disk: 10g

8.6.4 When to Use OpenShell

  • You need policy-controlled isolation beyond what Docker provides
  • You want to run Pi in remote managed sandboxes
  • You need fine-grained network and filesystem access controls
  • You are running untrusted code that requires strong isolation
Warning

No sandbox is perfect. Always review diffs and outputs before copying results back to trusted systems, regardless of which isolation pattern you use.

8.7 Choosing a Pattern

8.7.1 Decision Matrix

Requirement Recommended Pattern
Quick local isolation Plain Docker
Host auth + isolated tools Gondolin
Policy-controlled isolation OpenShell
CI/CD pipeline Plain Docker
Untrusted code execution OpenShell
Minimal overhead Gondolin
Reproducible environments Plain Docker
Remote sandboxes OpenShell
Fine-grained filesystem control OpenShell
Network restrictions needed OpenShell

8.7.2 General Best Practices

  1. Mount only what is needed — do not mount the entire home directory
  2. Use read-only mounts for reference material the agent should not modify
  3. Pass credentials via environment variables rather than mounting auth files
  4. Restrict network access when the task does not require it
  5. Set resource limits to prevent runaway processes
  6. Review outputs before copying results back to trusted systems
  7. Use --no-session for ephemeral tasks that should not persist

8.8 Security Considerations

8.8.1 What Containerization Does Not Solve

  • Prompt injection — malicious content in files can still influence model behavior
  • Side channels — network-accessible resources may still be reachable
  • Shared kernel vulnerabilities — container escape is possible in theory
  • Credential leakage — API keys passed into the container are accessible to the model

8.8.2 Defense in Depth

Combine multiple layers of isolation for sensitive workloads:

  1. Run Pi inside a container (Docker/OpenShell)
  2. Use Gondolin to further isolate tool execution
  3. Apply network restrictions
  4. Use short-lived credentials
  5. Review all outputs before merging to trusted systems
Note

For unattended automation, always use the strongest available isolation and implement monitoring to detect anomalous behavior.