code-on-incus (coi)

repository·master·Indexed 20 days ago

https://github.com/mensfeld/code-on-incus

code-on-incus (coi) provides isolated, secure system containers using Incus for AI coding agents. It allows agents full system access (root, Docker, package managers) while protecting the host machine from accidental damage, credential theft, or malicious activity. Key features include real-time threat detection, workspace persistence, SSH agent forwarding, and support for AI tools like Claude Code, opencode, and pi.

Tokens
23.3K
Snippets
95
Records
126
Agent score
69%

What's inside code-on-incus

  1. Overview of code-on-incus (coi) features

    master

    code-on-incus (coi) provides isolated system containers (using Incus) for AI coding agents.

    Key Capabilities

    • Isolation: Each agent gets a full system container with root access, systemd, and Docker, preventing them from touching your host system.
    • Security: Protects host credentials (SSH keys, env vars, Git tokens) by default. Includes real-time threat detection (reverse shells, data exfiltration) that can auto-pause or kill containers.
    • Persistence: Workspace files persist even in ephemeral mode. Containers can be kept alive between sessions to preserve installed tools.
    • Host Integration:
      • SSH Agent Forwarding: Use [ssh] forward_agent = true to use git-over-SSH without copying keys.
      • Port Publishing: Map container TCP ports to localhost using [ports] pool or [[ports.map]].
      • Socket Forwarding: Forward host Unix sockets using [[sockets]].
      • Credential Catalog: Inject specific credentials via [[credentials]] entries.
      • Environment Variables: Forward specific host variables via forward_env or inject secrets via [defaults.env_commands].
    • Context Injection: Automatically injects ~/SANDBOX_CONTEXT.md into the agent's environment to inform them of their network mode, workspace path, and persistence status.
  2. Provide credentials to containerized tools

    master

    You can grant credentials to tools running inside the container using four primary methods:

    1. [[sockets]]: Forwards host Unix sockets into the container via an Incus proxy device. Ideal for credential brokers.
    2. [defaults.env_commands]: Runs a host command at session start and injects its trimmed stdout as an environment variable. Best for plain tokens (e.g., AWS Bedrock).
    3. [ports]: Publishes container TCP ports on the host. Use pool = 3 for identity-mapped ports or [[ports.map]] for fixed ports (e.g., name = "web", container = 3000).
    4. [[credentials]]: Copies static files from host to container. Use bundle = "<name>" to reference the COI built-in catalog (e.g., ollama) or set host/container for ad-hoc files.

    Security Note: Sockets, [ports], and ad-hoc [[credentials]] are gated behind coi trust if they originate from an untrusted project .coi/config.toml. Catalog-referenced credentials are never gated.

  3. Configure Network Isolation and Allowlist mode

    master

    COI provides three network modes via [network] mode:

    1. Restricted (default): Blocks private networks, allows internet.
    2. Allowlist: Only specific domains/IPs allowed. In this mode, DNS egress is blocked, and COI writes allowed addresses directly into the container's /etc/hosts.
    3. Open: No restrictions (trusted projects only).

    Allowlist Configuration: When using mode = "allowlist", you must list exact hostnames or CIDR ranges. Wildcards (e.g., *.example.com) are not supported because addresses are resolved at setup time and written to /etc/hosts.

    [network]
    mode = "allowlist"
    allowed_domains = [
        "api.anthropic.com",
        "registry.npmjs.org",
        "10.0.0.0/8",
        "8.8.8.8",
    ]
  4. Configure code-on-incus via config.toml

    master

    Configuration is managed via TOML files. The configuration follows a hierarchy where the last applied setting wins:

    1. Built-in defaults
    2. User config (~/.coi/config.toml or $COI_CONFIG)
    3. Project config (./.coi/config.toml)
    4. Profile (--profile <name>)

    Note: Config-shaped settings (like [container] or [tool]) do not have CLI flags or environment variable overrides; they are the single source of truth. CLI flags like --workspace, --slot, --resume, and --profile are for per-invocation choices only.

    [container]
    image = "coi-default"
    persistent = true
    
    [tool]
    name = "claude"
    permission_mode = "bypass"
  5. Resume a previous AI coding session

    master

    You can resume a previous session to restore full conversation history, tool credentials, user settings, and project context.

    Resume Commands

    • coi shell --resume: Automatically detects and resumes the latest session for the current workspace.
    • coi shell --resume=<session-id>: Resumes a specific session by its ID.
    • coi list --all: Use this to find available session IDs.

    Note: Sessions are workspace-scoped. The profile used during the original session is automatically restored unless you explicitly override it with --profile.

    coi shell --resume
  6. Install code-on-incus (coi)

    master

    You can install coi using an automated script or manually.

    Run the following command to download and install coi to /usr/local/bin, check for Incus, and verify your incus-admin group membership:

    curl -fsSL https://raw.githubusercontent.com/mensfeld/code-on-incus/master/install.sh | bash

    Manual Installation

    1. Download the binary from GitHub Releases.
    2. Make the binary executable.
    3. Move it to /usr/local/bin/.

    Requirements:

    • Linux with Incus installed.
    • Your user must be in the incus-admin group.
    • Important: You must log out and back in (or run newgrp incus-admin) after adding your user to the group for the changes to take effect.
    curl -fsSL https://raw.githubusercontent.com/mensfeld/code-on-incus/master/install.sh | bash
  7. Enable and Monitor Security

    master

    COI includes built-in security monitoring to detect reverse shells, data exfiltration, environment scanning, and network threats.

    To enable monitoring, add this to your config.toml:

    [monitoring]
    enabled = true

    Response Levels:

    • INFO/WARNING: Logged to audit logs.
    • HIGH: Container is paused (requires coi unfreeze to continue).
    • CRITICAL: Container is killed immediately.

    Audit Logs: Logs are stored at ~/.coi/audit/<container-name>.jsonl. Use coi audit to stream these logs to stdout:

    coi audit --follow
  8. Use the hardened profile for untrusted code

    master

    For inspecting untrusted code, use the built-in hardened profile. It provides maximum security by enforcing:

    • network.mode = "restricted" (no exfiltration path)
    • Workspace secret masking (e.g., .env, *.pem)
    • Host immutability
    • Ephemeral container (no persistence)
    • No SSH-agent forwarding
    • Real-time threat monitoring with auto-pause/kill
    coi shell --profile hardened        # restricted net + secret masking + ephemeral + monitoring
    coi profile info hardened           # see exactly what it locks down
  9. Quick Start with code-on-incus

    master

    To get started with an isolated AI coding environment, follow these steps:

    1. Install the CLI.
    2. Build the image (required for the first time, takes ~5-10 minutes):
      coi build
    3. Start a session in your project directory:
      cd your-project
      coi shell

    By default, coi shell uses Claude Code. Your project will be mounted at /workspace inside the container with correct file permissions, and all workspace changes are persisted automatically.

    # Install
    curl -fsSL https://raw.githubusercontent.com/mensfeld/code-on-incus/master/install.sh | bash
    
    # Build image (first time only, ~5-10 minutes)
    coi build
    
    # Start coding with your preferred AI tool (defaults to Claude Code)
    cd your-project
    coi shell
  10. Build coi images

    master

    Use the coi build command to create container images. You can build the default image, custom images via profiles, or rebuild everything.

    Build Commands

    • Default image: coi build (builds coi-default, takes ~5-10 minutes).
    • Custom profile: coi build --profile <name> (requires a profile created via coi profile create <name>).
    • All profiles: coi build --all (builds all profiles containing a [container.build] section).
    • Force rebuild: coi build --all --force (rebuilds all profile images from scratch).

    Customizing Builds

    To build without compression for faster iteration, set [container.build] compression = "none" in your config or profile.

    The coi-default image includes:

    • Ubuntu 24.04 with Docker support.
    • mise (polyglot runtime manager) with Python 3, pnpm, TypeScript, and tsx pre-installed.
    • Node.js 22 LTS, Claude Code CLI, and GitHub CLI (gh).
    • Common tools: tmux, git, curl, build-essential, fd-find, bat, tree, strace, lsof, sqlite3, postgresql-client, redis-tools, and imagemagick.
    coi build
  11. Set Resource and Time Limits

    master

    You can control container resource consumption in your config.toml using the [limits] section. Supported limits include:

    • CPU: count (cores) or usage percentage.
    • Memory: limit (e.g., 2GiB) and swap.
    • Runtime: max_duration (e.g., 2h) to trigger auto-stop.
    • Other: Disk I/O rates and process counts.
    [limits.cpu]
    count = "2"
    
    [limits.memory]
    limit = "2GiB"
    
    [limits.runtime]
    max_duration = "2h"
  12. How profile discovery works for `coi build --all`

    master

    When using the --all flag, coi discovers and builds images for all profiles visible from your current working directory:

    1. Global Profiles: Located in ~/.coi/profiles/.
    2. Project-local Profiles: Located in .coi/profiles/ within your current directory.

    Build Order: The default profile is always built first. All other profiles are then processed in alphabetical order. Profiles that do not have a [container.build] section are silently skipped (unless they are the coi-default alias).