AI News HubLIVE
In-site rewrite5 min read

code-on-incus: Give each AI agent its own isolated machine with root

code-on-incus (COI) is an open-source tool that leverages Incus system containers to provide AI coding agents with isolated machine environments featuring full root access, systemd, Docker, and package management. It defaults to protecting host credentials, employs kernel-level nftables monitoring for real-time threat detection and automated response, and supports popular AI coding assistants like Claude Code and opencode.

SourceHacker News AIAuthor: Tomte

Notifications You must be signed in to change notification settings

Fork 45

Star 578

BranchesTags

Open more actions menu

Folders and files

NameName

Last commit message

Last commit date

Latest commit

History

975 Commits

975 Commits

.github/workflows

.github/workflows

cmd/coi

cmd/coi

docs

docs

internal

internal

misc

misc

profiles/default

profiles/default

schema

schema

scripts

scripts

testdata/dummy

testdata/dummy

tests

tests

.gitignore

.gitignore

.golangci.yml

.golangci.yml

.pre-commit-config.yaml

.pre-commit-config.yaml

CHANGELOG.md

CHANGELOG.md

LICENSE

LICENSE

Makefile

Makefile

README.md

README.md

go.mod

go.mod

go.sum

go.sum

install.sh

install.sh

pyproject.toml

pyproject.toml

renovate.json

renovate.json

ruff.toml

ruff.toml

Repository files navigation

Isolated machines for AI coding agents - with active defense.

COI gives each AI agent its own machine - a full system container with root access, systemd, Docker, and the ability to install anything. Agents work like they would on a real server: run services, manage packages, use cron - without touching your actual system. Files stay correctly owned, no permission hacks needed.

Your credentials stay on the host. SSH keys, environment variables, and Git tokens are never exposed to AI tools unless you explicitly mount them. If something goes wrong, COI catches it - reverse shells, credential scanning, data exfiltration - and pauses or kills the container automatically. No manual intervention needed.

Built by developers, for developers who run AI agents and want to know what those agents are doing. Not a product, not a startup - a tool that does the job.

Who this is for

You run AI coding agents and want them to have full machine access - root, Docker, package managers, services - without risking your host

You want to know when an agent does something suspicious, not find out after the fact

You run multiple agents in parallel and need them isolated from each other

You want persistent dev environments that survive restarts and reboots, not throwaway containers that lose your setup every time

You care about your credentials not ending up inside an agent-controlled environment

Watch the BetterStack video about Code on Incus

Table of Contents

Who this is for

Supported AI Coding Tools

Supported Tools (detailed)

Features

Quick Start

Why Incus Instead of Docker or Docker Sandboxes?

Installation

macOS Support

Usage

Run Scripts and Commands in the Sandbox

Session Resume

Persistent Mode

Configuration

Profiles

Resource and Time Limits

Container Lifecycle & Session Persistence

Network Isolation

Security Monitoring

Security Best Practices

Snapshot Management

System Health Check

Troubleshooting

FAQ

Supported AI Coding Tools

Currently supported:

Claude Code (default) - Anthropic's official CLI tool

opencode - Open-source AI coding agent (https://opencode.ai)

pi - AI coding assistant (https://pi.dev)

Coming soon:

Aider - AI pair programming in your terminal

Cursor - AI-first code editor

And more...

Tool selection is config/profile-driven:

~/.coi/config.toml or ./.coi/config.toml

[tool] name = "opencode" # or "claude" (default), "pi"

coi shell # Uses the configured tool (Claude Code by default) coi shell --profile opencode # Or switch via a profile with [tool] name = "opencode"

Permission mode - Control whether AI tools run autonomously or ask before each action:

~/.coi/config.toml or .coi/config.toml

[tool] name = "claude" # Default AI tool permission_mode = "bypass" # "bypass" (default) or "interactive"

See the Supported Tools wiki page for detailed configuration, API key setup, and adding new tools.

Features

Core Capabilities

Multi-slot support - Run parallel AI coding sessions for the same workspace with full isolation

Session resume - Resume conversations with full history and credentials restored (workspace-scoped)

Persistent containers - Keep containers alive between sessions (installed tools preserved)

Workspace isolation - Each session mounts your project directory

Slot isolation - Each parallel slot has its own home directory (files don't leak between slots)

Workspace files persist even in ephemeral mode - Only the container is deleted, your work is always saved

Container snapshots - Create checkpoints, rollback changes, and branch experiments with full state preservation

Host Integration

SSH agent forwarding - Use git-over-SSH inside containers without copying private keys ([ssh] forward_agent = true)

Host socket forwarding - Forward arbitrary host Unix sockets into the container ([[sockets]]) so the host endpoint never enters the container — the building block for credential brokers (mint short-lived tokens on the host, fetch them on demand inside). Untrusted project-config sockets are gated behind coi trust

Environment variable forwarding - Selectively forward host env vars by name (forward_env in config)

Command-sourced env vars - Mint a fresh secret per session by running a host command at start and injecting its output as an env var ([defaults.env_commands]) — for short-lived API keys/tokens. Trusted-scope config only

Host timezone inheritance - Containers automatically inherit the host's timezone (configurable via [timezone] config)

Sandbox context file - Auto-injected ~/SANDBOX_CONTEXT.md tells AI tools about their environment (network mode, workspace path, persistence, etc.). Automatically loaded into each tool's native context system: Claude Code via ~/.claude/CLAUDE.md, OpenCode via the instructions field in opencode.json, pi via ~/.pi/agent/APPEND_SYSTEM.md symlink (opt out with auto_context = false)

Security & Isolation

Credential protection - SSH keys, .env files, Git credentials, and environment variables are never exposed unless explicitly mounted

Privileged container guard - Refuses to start when security.privileged=true is detected, which defeats all container isolation

Security posture verification - coi health checks seccomp, AppArmor, and privilege settings to confirm full isolation

Kernel version enforcement - Warns on host kernels below 5.15 that may lack security features for safe isolation

Real-time threat detection - Kernel-level nftables monitoring detects reverse shells, C2 connections, data exfiltration, DNS tunneling, and credential scanning

Automated response - Auto-pause on HIGH threats, auto-kill on CRITICAL — no manual intervention needed

Network isolation - nftables-based restricted/allowlist/open modes block private network access and prevent exfiltration

Protected paths - .git/hooks, .git/config, .husky, .vscode mounted read-only to prevent supply-chain attacks

Host-side immutable protection - Protected paths are locked with chattr +i during sessions, preventing unshare -m + umount bypass of read-only mounts (opt out: [security] host_immutable = false)

Git identity guard - Containers enforce user.useConfigOnly=true, preventing AI tools from committing as the default "code" user

Guest API disabled - Incus guest API (/dev/incus) disabled by default, preventing host path and topology leaks

System containers - Full OS isolation with unprivileged containers, better than Docker privileged mode

Automatic UID mapping - No permission hell, files owned correctly

Audit logging - All security events logged to JSONL for forensics and compliance

Safe Dangerous Operations

AI coding tools often need broad filesystem access or bypass permission checks

These operations are safe inside containers because the "root" is the container root, not your host system

Containers are ephemeral - any changes are contained and don't affect your host

This gives AI tools full capabilities while keeping your system protected

Quick Start

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

Or use opencode instead (config-driven: [tool] name = "opencode",

or a profile: coi shell --profile opencode)

That's it! Your AI coding assistant is now running in an isolated container with:

- Your project mounted at /workspace

- Correct file permissions (no more chown!)

- Full Docker access inside the container

- GitHub CLI available for PR/issue management

- All workspace changes persisted automatically

- No access to your host SSH keys, env vars, or credentials

Why Incus Instead of Docker or Docker Sandboxes?

Incus is a modern Linux container and virtual machine manager, forked from LXD. Unlike Docker (which uses application containers), Incus provides system containers that behave like lightweight VMs with full init systems.

Security Comparison

Capability code-on-incus Docker Sandbox Bare Metal

Credential isolation Default (never exposed) Partial None

Real-time threat detection Kernel-level (nftables) No No

Reverse shell detection Auto-kill No No

Data exfiltration alerts Auto-pause No No

Network isolation nftables (3 modes) Basic No

Protected paths Read-only mounts No No

Auto response (pause/kill) Yes No No

Audit logging JSONL forensics No No

Supply-chain attack prevention Git hooks/IDE configs protected No No

Why Incus Instead of Docker Sandboxes?

Linux-first, not Linux-last. Docker Sandboxes' microVM isolation is only available on macOS and Windows. Linux gets a legacy container-based fallback. COI is built for Linux from the ground up because Incus is Linux-native.

No Docker Desktop required. Docker Sandboxes is a Docker Desktop feature. Docker Desktop is not open source and has commercial licensing requirements for larger organizations. COI depends only on Incus - fully open source, no vendor lock-in, no additional runtime.

System containers, not containers-in-VMs. Incus system containers run a full OS with systemd and native Docker support inside - one clean isolation layer. Docker Sandboxes nests application containers inside microVMs, adding architectural complexity.

No permission hell. Incus automatic UID/GID shifting means files created by agents have correct ownership on the host. No mapping hacks needed. (Note: files created via sudo in the workspace will be root-owned — the sandbox context file instructs AI tools to fix ownership after sudo operations.)

Credential isolation by default. Host environment variables, SSH keys, and Git credentials are never exposed to AI tools unless explicitly mounted.

Simple and transparent. No separate daemon, no opaque VM nesting. COI talks directly to Incus - easy to inspect, debug, and extend.

Installation

Automated Installation (Recommended)

One-shot install

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

This will:

- Download and install coi to /usr/local/bin

- Check for Incus installation

- Verify you're in incus-admin group

- Show next steps

Manual installation: Download the binary from GitHub Releases, make it executable, and move to /usr/local/bin/. Requires Linux with Incus installed and user in the incus-admin group. You must log out and back in (or run newgrp incus-admin) after adding your user to the group — COI runs incus directly and requires the group to be active in your session. See the Incus installation guide for setting up Incus.

Build Images

Build the default coi-default image (5-10 minutes)

coi build

Build without compression (faster iteration):

set [container.build] compression = "none" in config or the profile

coi build

Build a custom image via a profile

coi profile create my-image

Edit .coi/profiles/my-image/config.toml: set [container] image and a [container.build] section

coi build --profile my-image

Build images for all profiles that ha

[truncated for AI cost control]