iweb · open-source personal application node
A personal application node. Operated by your AI agent.
You don't need to learn containers, databases, or network operations. Hand your MCP endpoint and one owner key to an AI coding agent (Codex, Claude Code, …) — it deploys and operates applications on your own node. You manage everything from a browser console with a single key.
$docker compose up -d --build
iweb-kernel listening :8080 — the only published port
health: curl -H "Host: $IWEB_BASE_HOST" http://127.0.0.1:9010/_iweb/health
console: https://admin.<base>/ — log in with an owner key
What’s inside
Ingress · 01
Single-port Rust kernel
kernel-rs is a ~4MB static Rust binary and the node's only published port. It owns host routing, the recovery authority, owner-key auth, and a per-app proxy with WebSocket upgrade tunnels. Everything else — RustFS, the control API, every celld listener — stays on container-internal loopback.
Operations · 02
MCP is the operator
mcp.<base>/mcp is a protected system application: every JSON-RPC request — including initialize and tools/list — must carry an owner key as a Bearer token. Tools cover workspace read/write/delete and domain listing/registration. The worker forwards the credential per request and never stores it.
Trust · 03
Two-tier runtime trust
celld v0.3 (Cloudflare Workers API) is the trusted tier: image-seeded fleet apps, one process per app, watchdog soft limits. iweb-wasmd is the untrusted tier and the only runtime admission path: arbitrary or AI-generated packages execute as wasi:http 0.2 components under Wasmtime — engine-enforced isolation, host services, no socket capability.
Storage · 04
Built-in RustFS
S3-compatible object storage (MinIO lineage), single-node friendly with a low memory envelope, loopback-only with no console. Buckets: iweb-workspace, iweb-cells-<app>, iweb-apps, iweb-system.
Identity · 05
Revocable owner keys
One identity, many revocable tokens (the GitHub PAT model). Issue delegated keys (iwb_<id>_<secret>) with absolute expiry, copy a ready-to-paste deployment prompt for an AI agent, ban a key instantly, and read an append-only, per-key-attributed audit trail of every control-plane operation. The bootstrap IWEB_API_TOKEN cannot be banned — it is the credential face of the recovery law.
Console · 06
Static console, tight envelope
A SvelteKit + shadcn-svelte static app served as celld native assets — replaceable like any app, never a secret configuration screen. The whole node idles within ≤ 240 MB RssAnon (spec: openspec/specs/node-boundary/).
Ingress
One published port routes the whole node
iweb-kernel :8080 is the only published port (a single Rust binary). Everything except the Kernel ingress — RustFS, the control API, every celld listener — stays on container-internal loopback and is never published. One installation is one owner's personal node.
| Route | Serves |
|---|---|
api.<base> | Kernel control API (same router/auth as loopback) |
admin.<base> | per-app celld :8787 (Admin console) |
mcp.<base>/mcp | per-app celld :8797 (MCP endpoint) |
<app>.<base> | per-app celld (IWEB_CELLD_PORTS) |
<base>/<app>/app | path alias for the same application |
Behind the proxy: RustFS (S3-compatible, loopback-only, no console) backing the
iweb-workspace / iweb-cells-<app> / iweb-apps / iweb-system buckets.
Demo apps
Three reference applications ship in the image
They exercise the runtime end-to-end. Open collab on both of its domains in two browser windows — a message sent on one side jumps live on the other: the Durable Object cross-instance consistency demo.
| App | Host | Demonstrates |
|---|---|---|
hello | hello.<base> | Pure static site via celld's wrangler assets interface — no worker code. |
search | search.<base> | D1 (SQLite) database search with parameterized SQL. |
collab | collab.<base>, collab-b.<base> | Frontend/backend split; two celld instances share one Durable Object for cross-instance realtime collaboration over WebSocket. |
Quick start
One compose command, one health check
IWEB_BASE_HOST is a hostname suffix only (no scheme/port/path). The container publishes one port (8080 — map it however you like); TLS is terminated in front of the node (1Panel, Caddy, nginx, …) and the kernel routes by HTTP Host header only.
cp .env.example .env
# Set a unique CELLD_NODE, IWEB_BASE_HOST, a long random IWEB_API_TOKEN,
# and the MinIO-compatible root + celld S3 secrets.
docker compose up -d --build
curl -H "Host: $IWEB_BASE_HOST" http://127.0.0.1:9010/_iweb/healthOpen the console at https://admin.<base>/ and log in with any valid owner
key — the bootstrap IWEB_API_TOKEN, or a delegated key issued in the console.
From the Keys & Audit view you can copy a ready-to-paste deployment prompt containing
the MCP endpoint and key for an AI agent.
MCP
Point an agent at your node
Every JSON-RPC request — including initialize and tools/list — must carry Authorization: Bearer <owner-key> (bootstrap or delegated). Tools cover workspace read/write/delete and domain listing/registration.
{ "mcpServers": { "iweb": { "url": "https://mcp.<base>/mcp",
"headers": { "Authorization": "Bearer <owner-key>" } } } }Security boundary
Untrusted by default, isolated by design
Applications may be copied from the internet or generated by AI, so they are untrusted by default — isolating every application from the node control plane and from each other is the product's security bottom line.
- celld is the trusted tier. Fleet applications (admin, mcp, notes, hello, search, collab) enter the node only through node images you build, run one process per app, and are bounded by a userspace resource watchdog (soft-limit SIGKILL plus per-app restart). There is no celld runtime admission; celld is never a hostile multi-tenant boundary.
- wasm is the untrusted tier and the only runtime admission path. Arbitrary, network-sourced, or AI-generated packages execute as wasi:http 0.2 components under Wasmtime with engine-enforced limits (no socket/TLS/fs capability, host-mediated egress, fuel/epoch/store caps) and host services (KV/SQL/Logging) as the data plane.
- Never place secrets in the workspace. Credentials live only in node environment or Kernel-issued keys. The law lives in openspec/specs/application-sandbox.
Honesty
Current limitations
- TLS/wildcard certificates are a deployment concern (the kernel is HTTP Host-routing inside the container).
- Monitor metrics are per-Kernel-lifecycle, not durable history.
- notes is deployed but not routed (user routes target the wasm tier only).
- wasm publication stays fail-closed behind its acceptance record and switch; celld publication does not exist (image-only supply).