Skip to content

feat: Container-based isolation for safe autonomous execution #332

@acreeger

Description

@acreeger

Overview

Add optional container-based isolation for looms, enabling safer bypassPermissions usage and allowing users to define complex multi-service environments (Redis, databases, multiple servers) without iloom needing to understand each service.

Value Proposition

Today With Container Isolation
bypassPermissions executes on host Execution sandboxed to container
iloom needs service-specific code Users define their own environments
Risk scales with autonomy Damage contained, nuke container if needed
Single port calculation (web) User-defined ports for any service

Core Concept

iloom provides:

  • Worktree isolation (existing)
  • Port offset calculation for user-defined services
  • Container lifecycle management
  • Environment variable injection

User provides:

  • devcontainer.json / docker-compose.yml defining their services
  • Uses ILOOM_PORT_<NAME> convention for port variables

Port Discovery & Configuration

Convention

Users use ILOOM_PORT_<NAME> prefix in their compose files:

services:
  web:
    ports:
      - "${ILOOM_PORT_WEB}:3000"
  api:
    ports:
      - "${ILOOM_PORT_API}:4000"
  redis:
    ports:
      - "${ILOOM_PORT_REDIS}:6379"

During il init

iloom parses compose file, finds ILOOM_PORT_* vars, prompts for base ports:

Detected container configuration...
Found port variables: ILOOM_PORT_WEB, ILOOM_PORT_API, ILOOM_PORT_REDIS

What's the base port for WEB? › 3000
What's the base port for API? › 4000  
What's the base port for REDIS? › 6379

Settings

{
  "container": {
    "enabled": true,
    "ports": {
      "WEB": 3000,
      "API": 4000,
      "REDIS": 6379
    }
  }
}

At il start 123

iloom calculates offsets and writes to .env:

ILOOM_PORT_WEB=3123
ILOOM_PORT_API=4123
ILOOM_PORT_REDIS=6502

Proposed Flow

il start 123
  → Create worktree (existing)
  → Calculate port offsets, write to .env
  → Launch devcontainer with worktree mounted
  → Claude Code runs INSIDE container
  → bypassPermissions is now sandboxed

il finish 123
  → Generate summary (existing)
  → Stop/remove container
  → Merge worktree (existing)

Configuration

{
  "container": {
    "enabled": true,
    "configPath": ".devcontainer/devcontainer.json",
    "ports": {
      "WEB": 3000,
      "API": 4000
    },
    "keepAlive": false  // Stop container on finish vs keep running
  },
  "workflows": {
    "issue": {
      "permissionMode": "bypassPermissions"  // Now safe!
    }
  }
}

Open Questions

Claude Code Execution

  • How does Claude Code CLI run inside the container?
  • Option A: Install Claude CLI inside container, run natively
  • Option B: Run Claude on host, exec commands into container
  • Option C: Use devcontainer's remote execution capabilities
  • Needs research: How does devcontainer exec interact with Claude's terminal sessions?

IDE Integration

  • How does --ide cursor work with devcontainers?
  • VS Code has "Reopen in Container" - should iloom trigger this?
  • Or does iloom open the worktree and let user reopen in container manually?
  • Different IDEs handle devcontainers differently (WebStorm, etc.)

Container Lifecycle

  • Start on il start, stop on il finish?
  • What if user runs il spin multiple times - reuse running container?
  • What about il cleanup - force remove container?
  • Resume after machine restart?

Parsing Strategy

  • Parse devcontainer.json or docker-compose.yml or both?
  • What if both exist with different port definitions?
  • What if neither exists but container.enabled: true?

Database Integration

  • How does this interact with Neon branching?
  • If user runs containerized Postgres, do they still want Neon?
  • Support both? (containerized services + Neon for prod-like data)

Secrets & Environment

  • How do API keys (Linear, etc.) get into the container?
  • Mount .env.local? Copy? Inject via env?
  • Security implications of mounting secrets into container

Filesystem Mounting

  • Mount worktree as volume
  • What about node_modules - mount or install inside?
  • .git directory handling
  • Volume mounts for data persistence across container restarts

Network Isolation

  • Should containers from different looms be network-isolated?
  • What if issue Locking down Broker mode #123's container needs to call issue #456's API?
  • Default to isolated networks?

Risks

  1. Complexity - Significant feature touching many parts of iloom (init, start, finish, spin, cleanup, open, dev-server)

  2. Docker dependency - Not all users have/want Docker. Must remain optional with graceful degradation.

  3. Performance overhead - Container startup adds latency to il start. Image pull on first run. Need to quantify.

  4. Platform inconsistencies - Docker behavior differs across macOS/Linux/Windows. Docker Desktop licensing considerations.

  5. Resource usage - Multiple running containers (one per loom) could exhaust memory/CPU. May need guidance on limits.

  6. Debugging difficulty - Container issues are harder to diagnose than host issues. Need good error messages.

  7. devcontainer CLI dependency - Requires @devcontainers/cli installed. Add to iloom dependencies or require user install?

  8. Breaking existing workflows - Users with existing devcontainer setups may have conflicts. Migration path needed.

Non-Goals (V1)

  • Remote container execution (Docker on remote host)
  • Kubernetes/orchestration support
  • Multi-container networking between looms
  • Container image building/publishing

Implementation Approach

Suggest implementing in waves:

Wave 1: Foundation

  • Port parsing during il init
  • Port calculation and .env injection at il start
  • Basic devcontainer launch/stop

Wave 2: Integration

  • IDE integration (open in container)
  • il spin inside container
  • il open / il dev-server with containers

Wave 3: Polish

  • il cleanup container handling
  • Error handling and recovery
  • Documentation

Acceptance Criteria

  • Users can define multi-service environments via devcontainer
  • il init detects and configures port mappings
  • il start launches container with correct ports
  • Claude Code can execute inside container
  • bypassPermissions is sandboxed to container
  • il finish cleans up container
  • Graceful fallback when Docker unavailable
  • Works with existing Neon integration (or clearly documented alternative)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions