clide

April 23, 2026 · View on GitHub


   ██████ ██      ██ ██████  ███████
  ██      ██      ██ ██   ██ ██
  ██      ██      ██ ██   ██ █████
  ██      ██      ██ ██   ██ ██
   ██████ ███████ ██ ██████  ███████

  sandboxed agentic terminal        v3
  ──────────────────────────────────────

  your project ──bind mount──► /workspace
  .env secrets ──env vars────► container
  browser :7681 ──ttyd───────► web shell

  ┌────────────────────────────────────┐
  │  claude  copilot  codex  gh  bash  │
  │          web (ttyd + tmux)         │
  └──────────────┬─────────────────────┘
          MITM intercept proxy
            firewall.sh
           egress allowlist

        ┌────────┼────────┐
        ▼        ▼        ▼
   intercept  egress   session
    .jsonl    .jsonl    events


     api.anthropic.com    claude
     api.githubcopilot.com copilot
     api.github.com        gh
     api.openai.com        codex
     *everything else      REJECT

  ──────────────────────────────────────
  every request captured. every
  connection logged. nothing leaves
  without a record.

A sandboxed environment for running AI coding agents (Claude Code, GitHub Copilot CLI, Codex CLI, GitHub CLI) that captures structured interaction data from every session. CLIDE is a research instrument: it intercepts API traffic between agents and providers, logs all outbound connections, and records session events — producing machine-readable datasets for studying how AI agents interact with codebases.

Data & Observability

CLIDE captures three streams of structured data from every agent session. This is the core value proposition — not just sandboxing, but complete observability over agent behavior.

intercept.jsonl — API request/response capture

MITM proxy intercepts all traffic between the agent and its provider API. Every prompt, every completion, every tool call — captured with full request and response bodies.

/var/log/clide/intercept.jsonl

Each line is a JSON object:

FieldTypeDescription
timestampISO 8601When the request was made
methodstringHTTP method (POST, GET, etc.)
urlstringFull request URL
request_headersobjectRequest headers (auth tokens redacted)
request_bodyobjectFull request payload — prompts, messages, tool definitions
response_statusintHTTP status code
response_headersobjectResponse headers
response_bodyobjectFull response — completions, tool calls, token counts
duration_msintRound-trip time

egress.jsonl — outbound connection log

Every outbound network connection the agent attempts, whether allowed or blocked by the firewall.

/var/log/clide/egress.jsonl
FieldTypeDescription
timestampISO 8601Connection attempt time
destinationstringHostname or IP
portintDestination port
protocolstringtcp, udp
actionstringALLOW or REJECT
rulestringWhich firewall rule matched

This tells you exactly what the agent tried to reach — and whether it was permitted. Rejected connections are especially interesting: they reveal what the agent wanted to do but couldn't.

Session events — tool use, edits, commands

Agent tool invocations, file edits, and shell commands are captured as structured events:

/var/log/clide/session-events.jsonl
FieldTypeDescription
timestampISO 8601Event time
event_typestringtool_use, file_edit, command, file_read
agentstringWhich CLI produced the event
detailobjectEvent-specific payload (tool name, file path, command, etc.)

Research applications

With these three streams you can reconstruct complete agent sessions:

  • Token economics — measure prompt/completion token counts per task
  • Tool use patterns — which tools agents reach for, in what order, how often
  • Egress behavior — what external resources agents try to access (and what happens when blocked)
  • Latency profiling — provider response times under different prompt sizes
  • Comparative analysis — run the same task across Claude, Copilot, and Codex; diff the data

Egress Firewall (Research Control)

The iptables egress allowlist isn't just security — it's an experimental control. You decide exactly what the agent can reach, creating reproducible conditions for studying agent behavior under different network constraints.

Default allowlist

HostUsed by
api.anthropic.comClaude Code
api.githubcopilot.comGitHub Copilot CLI
api.github.comGitHub Copilot CLI, GitHub CLI
github.comGitHub CLI
registry.npmjs.orgnpm package updates
api.openai.comCodex CLI
auth.openai.comCodex CLI — device code auth

DNS (port 53) and loopback traffic are always allowed.

Modifying the allowlist

Add hosts via CLIDE_ALLOWED_HOSTS in .env:

CLIDE_ALLOWED_HOSTS=pypi.org,files.pythonhosted.org

Disable the firewall entirely with CLIDE_FIREWALL=0 (unrestricted egress — no rejected connections logged).

The firewall uses iptables and requires the NET_ADMIN capability (already set in docker-compose.yml). If unavailable, it degrades gracefully with a warning.

Architecture

Trust boundary: the host trusts the container with a read-write mount of your project directory and your API credentials via .env. The container cannot reach the internet beyond the allowlisted endpoints (when NET_ADMIN is available). See SECURITY.md for the full threat model.

Quick Start

  1. Clone and configure credentials:

    git clone https://github.com/itscooleric/clide
    cd clide
    cp .env.example .env   # then edit with your tokens
    
  2. Add your tokens to .env:

    GH_TOKEN=your_github_pat_here
    
    # Claude auth — pick one:
    CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-xxxxx   # subscription (recommended)
    # ANTHROPIC_API_KEY=sk-ant-xxxxx              # API credits
    
  3. Build and run:

    docker compose build
    ./clide web       # web terminal at http://localhost:7681
    ./clide claude    # Claude Code CLI
    ./clide shell     # interactive shell with all CLIs
    

Your project is mounted at /workspace inside the container. Data logs appear in /var/log/clide/.

Included CLIs

CLICommandAuth env var
Claude CodeclaudeCLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY
GitHub Copilot CLIcopilotGH_TOKEN
GitHub CLIghGH_TOKEN
Codex CLI (OpenAI)codexOPENAI_API_KEY
GitLab CLIglabGITLAB_TOKEN + GITLAB_HOST

Claude Code auth

OAuth token (recommended): Uses your Claude Pro/Max subscription — no API credits consumed. Generate with claude setup-token on any machine with a browser, valid for 1 year.

API key: Pay-per-use. Create at https://console.anthropic.com/settings/keys.

Set one (not both) in .env. If both are present, OAuth takes priority.

Codex CLI auth

Set OPENAI_API_KEY in .env, or use device code flow inside the container:

codex auth login --auth device

Usage

Wrapper script

./clide web       # start web terminal at http://localhost:7681
./clide shell     # interactive shell with all CLIs
./clide claude    # run Claude Code CLI
./clide copilot   # run GitHub Copilot CLI
./clide codex     # run Codex CLI
./clide gh repo view  # run GitHub CLI with args
./clide help      # show all commands

Make targets

make web          # start web terminal
make shell        # interactive shell
make claude       # Claude Code CLI
make codex        # Codex CLI
make help         # show all targets

Docker Compose directly

docker compose run --rm shell
docker compose up -d web
PROJECT_DIR=/path/to/repo docker compose run --rm shell

VS Code tasks

Ctrl+Shift+P > Run Task > choose from web terminal, copilot, or shell targets.

tmux — Multi-Agent Workflows

tmux is installed and enabled by default in the web terminal. Run multiple agents side-by-side: Claude in one pane, Copilot in another, monitoring data logs in a third.

Every browser tab attaches to the same named session (main), so refreshing re-attaches rather than spawning a new shell.

For make shell / ./clide shell, tmux is opt-in:

CLIDE_TMUX=1
KeyAction
Ctrl-b |Split pane horizontally
Ctrl-b -Split pane vertically
Ctrl-b <arrow>Move between panes
Ctrl-b dDetach (session stays alive)
MouseClick to focus, scroll, drag to resize

Python Dev Tooling

The container includes a Python 3 virtualenv at /opt/pyenv with pytest and ruff pre-installed. The venv is clide-owned — pip install works without sudo.

Note: pip install requires outbound PyPI access. Add pypi.org,files.pythonhosted.org to CLIDE_ALLOWED_HOSTS if the firewall is enabled.

Git Workspace

safe.directory = * is pre-configured so volume-mounted repos work without ownership errors. Appropriate for a single-user sandbox — see SECURITY.md for caveats.

Additional Docs

DocContents
SECURITY.mdThreat model, trust boundaries, attack surface, hardening
RUNBOOK.mdHealth checks, logs, rebuilds, credential rotation, troubleshooting
DEPLOY.mdProduction deployment with Caddy reverse proxy

Compatibility

Host OS

OSStatusNotes
LinuxSupportedNative Docker — full functionality including egress firewall
macOS (Apple Silicon)SupportedDocker Desktop required; arm64 builds natively
macOS (Intel)SupportedDocker Desktop required
Windows (WSL2)SupportedDocker Desktop with WSL2 backend required
Windows (no WSL2)PartialEgress firewall requires NET_ADMIN; availability varies

Requirements

ComponentMinimum
Docker Engine20.10+
Docker Composev2.0+ (docker compose, not docker-compose)
CPUamd64 or arm64
Browser (web terminal)Chrome, Firefox, Safari, Edge
Environment Variable Reference

CLIDE_* variables

VariableWhere setDefaultDescription
CLIDE_UIDBuild arg1000UID for clide user. Set to $(id -u) to match host.
CLIDE_GIDBuild arg1000GID for clide group. Set to $(id -g) to match host.
CLIDE_FIREWALLRuntime .env1Set to 0 to disable egress allowlist.
CLIDE_ALLOWED_HOSTSRuntime .env(empty)Additional hostnames for egress allowlist.
CLIDE_TMUXRuntime .env(off)Set to 1 to enable tmux in shell mode.

Auth variables

VariableDescription
GH_TOKENGitHub PAT with Copilot Requests permission
CLAUDE_CODE_OAUTH_TOKENClaude OAuth token (subscription)
ANTHROPIC_API_KEYAnthropic API key (pay-per-use)
OPENAI_API_KEYOpenAI API key for Codex CLI
GITLAB_TOKENGitLab PAT
GITLAB_HOSTGitLab instance URL
GIT_AUTHOR_NAME / GIT_COMMITTER_NAMEGit authorship inside container
GIT_AUTHOR_EMAIL / GIT_COMMITTER_EMAILGit email inside container
TTYD_USER / TTYD_PASSWeb terminal authentication

Build args are baked in at docker compose build. Runtime vars take effect on container start — no rebuild needed.

Notes

  • Tokens don't expire unless you set an expiry. OAuth tokens from claude setup-token are valid for 1 year.
  • .env is gitignored. Don't commit it.
  • Rebuild with latest CLI versions: docker compose build --no-cache
  • Data logs persist across container restarts when /var/log/clide/ is volume-mounted.