{"id":50581845,"url":"https://github.com/siinghd/isobox","last_synced_at":"2026-06-05T03:04:36.037Z","repository":{"id":362582136,"uuid":"1259765841","full_name":"siinghd/isobox","owner":"siinghd","description":"Open-source, self-hostable sandbox for running untrusted / AI-generated code, isolated by gVisor. Stateful sessions, persistent memory, live kernels — no KVM required.","archived":false,"fork":false,"pushed_at":"2026-06-04T23:37:02.000Z","size":340,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T00:13:24.658Z","etag":null,"topics":["ai-agents","code-execution","code-interpreter","golang","gvisor","sandbox","security","self-hosted"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/siinghd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY_AUDIT.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-04T20:50:04.000Z","updated_at":"2026-06-04T23:37:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/siinghd/isobox","commit_stats":null,"previous_names":["siinghd/isobox"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/siinghd/isobox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siinghd%2Fisobox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siinghd%2Fisobox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siinghd%2Fisobox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siinghd%2Fisobox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/siinghd","download_url":"https://codeload.github.com/siinghd/isobox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siinghd%2Fisobox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33927315,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","code-execution","code-interpreter","golang","gvisor","sandbox","security","self-hosted"],"created_at":"2026-06-05T03:04:33.447Z","updated_at":"2026-06-05T03:04:36.031Z","avatar_url":"https://github.com/siinghd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# isobox\n\n**Run untrusted code safely, on your own box — no KVM required.**\n\nOpen-source, self-hostable sandbox for executing untrusted / AI-generated code in isolated, resource-capped, ephemeral environments. Isolated by [gVisor](https://gvisor.dev). Security-first: every default is the safe one.\n\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)\n\u0026nbsp;·\u0026nbsp; [Live demo](https://isobox.hsingh.app) \u0026nbsp;·\u0026nbsp; [Architecture](docs/ARCHITECTURE.md) \u0026nbsp;·\u0026nbsp; [Threat model](docs/THREAT_MODEL.md)\n\n\u003c/div\u003e\n\n---\n\n## Why\n\nAI agents generate code that has to run *somewhere*. Running it on the host is reckless; spinning up a full VM per call is slow and needs hardware virtualization you may not have. **isobox** is the middle path: a userspace kernel (gVisor) gives you a real syscall boundary without `/dev/kvm`, wrapped in a hardened, horizontally-scalable HTTP service you can self-host.\n\nWhat makes it different from Piston / Judge0 / E2B:\n\n- **Built for AI agents.** Real work needs to fetch, scrape, and crunch data — so isobox ships a batteries-included Python (requests/httpx, BeautifulSoup/lxml, pandas/numpy…) and an **opt-in, firewalled network egress**: code can reach the public internet but **cannot** touch cloud metadata, private/VPN ranges, the host, or send mail. Verified, not asserted.\n- **Hardened by default.** Network off, read-only rootfs, non-root, all caps dropped, swap off, pids/memory/cpu/wall-time capped, output truncated, digest-pinned images — *together*, verified on a real shared box. (The Judge0 escape CVEs came straight from unsafe defaults.)\n- **No KVM needed.** Runs on plain cloud VMs via gVisor's `systrap` platform, where Firecracker-based tools (E2B) physically cannot.\n- **Blast-radius ceiling.** The entire sandbox subsystem runs under one hard-capped cgroup slice, so a runaway can never OOM its neighbours.\n- **Honest about the boundary.** On no-KVM hosts the trust boundary is gVisor's software Sentry (excellent defense-in-depth, *not* a hardware VM). For fully-hostile multi-tenant on KVM hardware, flip to the Firecracker backend. We document the line instead of hiding it.\n- **One static binary.** API + playground UI embedded. `scp` it and run.\n\n## Quickstart\n\n```bash\n# Prereqs: Docker + gVisor (runsc). One-time host setup:\nsudo bash deploy/setup.sh          # installs runsc, the runsc-untrusted runtime, and isobox.slice\n\n# Build \u0026 run\ngo build -o bin/isoboxd ./cmd/isoboxd\nISOBOX_REGISTRY=internal/registry/registry.yaml ./bin/isoboxd\n# -\u003e playground on http://127.0.0.1:8090\n```\n\nRun some code:\n\n```bash\ncurl -s localhost:8090/execute -H 'content-type: application/json' -d '{\n  \"language\": \"python\",\n  \"code\": \"print(sum(range(100)))\"\n}'\n# {\"language\":\"python\",\"version\":\"3.14.5\",\"backend\":\"gvisor\",\n#  \"run\":{\"stdout\":\"4950\\n\",\"stderr\":\"\",\"exitCode\":0,\"timedOut\":false,\"oomKilled\":false,\"truncated\":false,\"durationMs\":214}}\n```\n\nStream output live (Server-Sent Events):\n\n```bash\ncurl -N localhost:8090/execute -H 'accept: text/event-stream' -H 'content-type: application/json' \\\n  -d '{\"language\":\"python\",\"code\":\"import time\\nfor i in range(3):\\n  print(i,flush=True); time.sleep(0.5)\"}'\n```\n\nLet an agent fetch + scrape + analyze (opt-in `network: true`, firewalled to the public internet):\n\n```bash\ncurl -s localhost:8090/execute -H 'content-type: application/json' -d '{\n  \"language\": \"python\",\n  \"network\": true,\n  \"code\": \"import requests, pandas as pd, io\\n csv = requests.get(\\\"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv\\\").text\\n df = pd.read_csv(io.StringIO(csv))\\n print(df.groupby(\\\"species\\\")[\\\"sepal_length\\\"].mean())\"\n}'\n```\n\n## API\n\n📖 Full reference: [`docs/API.md`](docs/API.md) · machine-readable [`/openapi.yaml`](https://isobox.hsingh.app/openapi.yaml) (OpenAPI 3.1) · agent-readable [`/llms.txt`](https://isobox.hsingh.app/llms.txt).\n\n| Method | Path | Purpose |\n|---|---|---|\n| `POST` | `/execute` | Run code, return stdout/stderr/exit. Send `Accept: text/event-stream` for live SSE. |\n| `GET` | `/runtimes` | List available languages + versions. |\n| `GET` | `/healthz` | Liveness. |\n| `GET` | `/readyz` | Readiness — **503 unless the protective slice is actually capped**. |\n| `GET` | `/` | Embedded playground UI. |\n\n**Request:**\n\n```jsonc\n{\n  \"language\": \"python\",          // name or alias (py, py3, …)\n  \"version\": \"3.14.5\",           // optional, pins a version\n  \"code\": \"print(1)\",            // single-file convenience…\n  \"files\": [{\"name\":\"main.py\",\"content\":\"…\"}],  // …or multi-file\n  \"stdin\": \"\",\n  \"args\": [],\n  \"limits\": {                    // all optional, clamped to hard ceilings\n    \"memoryBytes\": 268435456,    // ≤ 512 MiB\n    \"cpus\": 1.0,                 // ≤ 2.0\n    \"pids\": 128,                 // ≤ 256\n    \"outputBytes\": 65536,        // ≤ 256 KiB\n    \"wallTimeMs\": 10000          // ≤ 20 000\n  },\n  \"network\": false               // default false\n}\n```\n\n**Result signals** are authoritative and disambiguate the otherwise-ambiguous exit 137:\n`exitCode`, `timedOut`, `oomKilled`, `truncated`, `durationMs`.\n\n## Languages\n\nLive today: **Python, JavaScript, TypeScript, Ruby, Go, Rust** — all start fast: Python/JS/TS/Ruby ≈0.6–1.1s, Rust ≈1.4s, Go ≈2s (a pre-warmed stdlib cache cuts Go from ~14s). The default **Python is batteries-included** for agent work; `python-slim` is the minimal zero-build fallback. Languages are declared in [`internal/registry/registry.yaml`](internal/registry/registry.yaml) — adding one is a config entry (digest-pinned image, run command, default limits), no code change, hot-reloadable with `SIGHUP`.\n\n## Clients\n\nDependency-free clients in [`clients/`](clients): [`python/isobox.py`](clients/python/isobox.py) and [`js/isobox.mjs`](clients/js/isobox.mjs) — both support `execute()`, live `stream()` (SSE), and `runtimes()`.\n\n```python\nfrom isobox import Isobox\nbox = Isobox(\"https://isobox.hsingh.app\")\nprint(box.execute(\"python\", code=\"print(40+2)\")[\"run\"][\"stdout\"])  # 42\n```\n\n## Configuration\n\n| Env | Default | Meaning |\n|---|---|---|\n| `ISOBOX_ADDR` | `127.0.0.1:8090` | Listen address |\n| `ISOBOX_REGISTRY` | `internal/registry/registry.yaml` | Language catalogue path |\n| `ISOBOX_CONCURRENCY` | `4` | Global max concurrent sandboxes |\n| `ISOBOX_API_KEY` | *(empty)* | If set, required via `X-API-Key` / `Bearer` |\n| `ISOBOX_RATE_PER_MIN` | `30` | Per-IP rate limit |\n| `ISOBOX_RATE_BURST` | `10` | Per-IP burst |\n| `ISOBOX_ALLOW_NETWORK` | `1` | Allow opt-in `network:true` (filtered egress). `0` disables it host-wide |\n| `ISOBOX_EGRESS_NETWORK` | `isobox-egress` | Docker network carrying the egress firewall |\n\n## Security\n\nRead the [**threat model**](docs/THREAT_MODEL.md) and the [**adversarial audit**](docs/SECURITY_AUDIT.md) (live red-team; verdict *pass with fixes* — isolation held, found-and-fixed defects documented). Short version: defense-in-depth — gVisor syscall boundary, `--network=none`, read-only rootfs, `--user=nobody`, `--cap-drop=ALL`, `no-new-privileges`, swap-off memory cap, pids cap, cpu cap, worker-enforced wall-time kill, output truncation, ephemeral per-run filesystem, scrubbed env, digest-pinned images, and a hard-capped parent cgroup slice. **Residual risk:** on no-KVM hosts the boundary is software (gVisor Sentry), strictly weaker than a microVM — use the Firecracker backend for hostile multi-tenant on KVM hardware.\n\n## Self-hosting \u0026 scaling\n\nSingle binary, stateless gateway. Single node uses an in-process semaphore-gated queue (no external dependencies). For multi-node, the same `Queue` interface targets Valkey/Redis Streams (at-least-once; executions are idempotent because the network is off). See [ARCHITECTURE.md](docs/ARCHITECTURE.md) and [DEPLOY.md](docs/DEPLOY.md).\n\n## Roadmap\n\n- [x] gVisor backend, sync + SSE, hardened-by-default, hard-capped slice\n- [x] Languages: Python, JavaScript, TypeScript, Ruby, Go, Rust\n- [x] **Firewalled network egress** for agents (public-only; metadata/private/host/SMTP blocked)\n- [x] **Batteries-included Python** + pre-warmed Go; dependency-free Python + JS clients\n- [x] **Stateful sessions** — persistent `/workspace`, file upload/download, multi-step exec (`/v1/sessions`)\n- [x] **Live-kernel sessions** — variables persist across steps, Code-Interpreter style (`type: kernel`)\n- [x] **Persistent memory** — multi-tenant KV (`/v1/memory`) + re-attachable volumes (`/v1/volumes`, `/memory`)\n- [x] **Scale primitives** — warm pool, Prometheus `/metrics`, Valkey-Streams queue (default-off)\n- [x] `llms.txt` + OpenAPI 3.1 served live\n- [ ] Harden warm pool (per-request limits) + Valkey driver before enabling in prod\n- [ ] More languages (C/C++, Bash, Java) + Piston-compatible `/api/v2/execute` shim\n- [ ] Firecracker and hardened-runc backends\n- [ ] Cloudflare Turnstile + Authenticated Origin Pull for the public demo\n\n## License\n\n[Apache-2.0](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiinghd%2Fisobox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsiinghd%2Fisobox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiinghd%2Fisobox/lists"}