self-hosted · open-source stack · one box
~ $
id8
The place where ideas become running software.
Ideas, terminals, files, hosting, and feedback — a complete loop on
one small server you own.
capture ❯ shape ❯ promote ❯ build ❯ host ❯ share ❯ learn
part 1 · the flywheel
Spoken idea to live URL, without leaving one interface
01capturean idea arrives by voice, phone share-sheet, or web form
02shapean AI intake advisor interviews you, scores clarity, sizes the effort
03promoteone click makes it a real project — files, roadmap, terminals
04buildpersistent web terminals + in-browser editor, from any device
05hostone click runs it as a supervised service on a real hostname
06share & learnapp gallery + feedback overlay, straight back onto the roadmap
Every stage lives on the same box, in the same UI, against the same data.
part 1 · data autonomy
Your ideas, code, and data never leave hardware you control
Everything is local
Every idea, file, log line, and account lives in plain files and SQLite on one machine you own.
No SaaS custody
No third party stores your work. The only cloud piece is an optional proxy that holds zero data.
Leave anytime
State is ordinary files — copy the folder and you have everything. No export request, no lock-in.
Private by default
Reachable over an encrypted private network. Publishing to the internet is an explicit, per-app decision.
part 1 · fast iteration · low cost
Minutes from idea to running app, for the price of one small VM
fastOne sitting, end to end
- Voice capture → scaffolded project → open terminal → hosted app
- Terminals survive restarts; sessions reattach from any browser — including a phone
- Push-to-deploy: git push restarts the live app
cheapNo platform tax
- Runs comfortably on one 4-core VM (the reference box)
- No per-seat licences, no metered platform fees
- Optional public edge: a ~$5/mo VPS + one domain
- No GPU, no cluster, no container platform
part 1 · multi-user
A shared workshop with real walls
Invite-based
The admin mints an invite; members sign in with passkeys — no passwords anywhere.
Real OS isolation
Each member is a genuine OS user with a private home. Members can't read each other's files; shells hold no admin rights. Kernel-enforced, not roles in a database.
The full loop
Everyone gets their own ideas, projects, terminals, and test apps.
Two-tier publishing
Members deploy privately for the group; the admin gates what becomes public.
part 1 · flexible back ends
Swap the back ends, keep the platform
pluggable todayChosen by config
- LLM intake advisor — hosted API or offline mock
- Snapshots — btrfs / rsync / plain copy, auto-detected
- Terminals — POSIX pty on Linux, winpty on Windows
- Hypervisor — Hyper-V, Proxmox, or cloud VPS
seams speccedReady to slot in
- Model gateway — any LLM provider behind one endpoint
- Speech-to-text / voice routes with pluggable engines
- Email, Teams notifications, document generation
- Apps discover services at runtime —
/api/id8/services
The platform owns the seam; what's behind it can change without rewriting apps.
part 2 · technical brief
How it works, what's done, what's next
For the infrastructure admin: architecture, security model, operations, and the engineered roadmap.
332automated tests
37MCP tools
45dated specs
5runtime dependencies
part 2 · stack
Every component is boring, open-source, and widely deployed
Runs on
Debian 12Python 3.11Flask
SQLite · WALCaddysystemd
TailscaleWebAuthnOAuth 2.0
ufwWebDAVgit
Deliberately absent
DockerKubernetesORM
npm / build stepmessage queueexternal DB
Five third-party Python packages total. Raw sqlite3 with an idempotent migrator; vanilla JS from CDN.
Any Debian admin can read the whole system: units, a Caddyfile, Python files, SQLite files.
part 2 · architecture
One box, one proxy hop, clear trust boundaries
Browser / PWApasskey session
MCP clientOAuth 2.0 / bearer
WebDAV mountBasic over TLS
❯
Edge VPS · CaddyTLS :443 · holds no data
❯tailnet
WireGuard
id8 box — one Debian 12 VM
Caddy :80 → Flask appUI · API · MCP · WebDAV
PTY daemon :5905shells survive app restarts
Hosted appssystemd units · own uid
Privilege helperone root binary · one sudoers rule
SQLite (WAL) + workspace treeall state, all files, one disk
Public requests carry a proxy-stamped header and require a passkey session.
The tailnet is the private path. The edge stores nothing — all state stays on the box.
part 2 · security model
Passkeys at the edge, kernel boundaries inside
Public edge
Every request via the VPS needs a WebAuthn passkey session — no passwords, phishing-resistant.
Private path
The WireGuard tailnet is the operator's boundary; ufw exposes nothing else.
API access
Full OAuth 2.0 server: RFC 8414 / 9728 discovery, RFC 7591 registration, PKCE-S256, refresh rotation, hashed tokens, read-only scope.
Privilege
The web app runs unprivileged. All root operations go through one auditable helper under a single sudoers rule. Member shells: own uid, no sudo.
Hosted apps
Per-app tokens, origin-locked CORS, cgroup limits + systemd sandbox — on by default.
part 2 · status
What's built and verified today
| surface | state |
| Core pipeline | Persistent terminals, file browser + editor, run-control → systemd, Caddy routing. Live on the reference VM. |
| Ideas | Idea market with full-text search, AI intake advisor, idea hub, promote-to-project. Live. |
| Multi-user | Passkey accounts, invites, per-member OS users, admin-gated publishing. Verified on-box. |
| App platform | Services SDK, identity, logging with redaction, health grid, gallery, feedback → roadmap. Live. |
| Access | MCP (37 tools) + OAuth over public HTTPS, WebDAV share, mobile PWA. Live; PWA rolling out. |
| Operations | Snapshots, app hardening + limits, scheduled tasks, git push-to-deploy. Built, rolling out. |
332 automated tests · every feature has a dated spec in-repo before code
part 2 · multi-user isolation
OS-level isolation, not application-level roles
membersReal Linux users
- Dedicated uid range, home
0700
- Shells spawn through the vetted helper and drop to the member uid
- Member→member reads: Permission denied — verified on-box
- Member apps run as their uid via
systemd-run --uid
platformBrokered, scoped, gated
- id8 brokers member files via POSIX ACLs — no shared write surface
- Every owned table carries
user_id; stores auto-scope queries
- Publishing: member requests → admin approves → hostname route
- Next rung: per-member network namespaces, then containers
part 2 · app platform
Hosted apps get a platform, not just a port
Zero-config wiring
Every app receives $ID8_ENDPOINT + $ID8_APP_TOKEN; one stdlib-only client shim.
Identity
Apps ask /api/id8/session who's calling — no auth code to write.
Logging
Structured logs with secrets redacted at insert; live SSE tail; journald crash capture.
Health & discovery
A manifest-driven poller probes backing services; apps query availability at runtime.
Distribution
Cross-user app gallery + one-line feedback overlay; notes promote straight onto the roadmap.
Lifecycle
Limits, schedules, snapshots, and push-to-deploy — per-app controls in the owner's hub.
part 2 · data sovereignty
All state is files on one disk you control
where data livesFour things, one disk
- One SQLite database — ideas, users, roadmap, sessions, logs
- Two directory trees — code workspace + documents
- Config: one env file + one TOML port registry
- The edge VPS stores nothing — a proxy rule and a cert
backup storyCopyable by design
- WAL-safe online backup script
- Snapshots: btrfs CoW or rsync rotation; restores shield
.git / .venv
- Specced: Litestream continuous DB replication off-box
- Disaster recovery = restore files + run the provisioner
part 2 · operations
Administered like any Debian box — plus a settings UI
systemd everywhere
The app, the PTY daemon, Caddy, every hosted app, every schedule. systemctl status tells the whole story.
Settings UI
Runtime config with default-vs-override badges, service restarts, routes, ports, tokens, passkeys, users.
One env file
Every knob is an ID8_* variable in id8.env — nothing hard-coded.
Observability
Health grid with per-kind probes; centralized logs with live tail; journald crash capture.
Recovery CLIs
Token mint, auth reset, DB init — self-service and idempotent.
part 2 · deployability
Bare metal to live in under an hour
01installpreseeded Debian 12 netinst — unattended, headless, SSH key baked in
02provisionprovision-id8.sh — idempotent: packages, units, Caddy, firewall, schema
03edgeoptional: provision-edge.sh on any $5 VPS — TLS + wildcard app domains
04useopen the browser — dashboard, terminals, ideas
Provisioners for Hyper-V (proven end-to-end), Proxmox, and cloud-init.
Re-runs converge without clobbering data. The box address is a stable tailnet name — the VM can migrate hypervisors without republishing.
part 2 · auditability
No opaque state — every action leaves an inspectable trace
DataEvery record is a SQLite row, readable with the stock sqlite3 CLI. No vendor formats.
CodePlatform and apps are plain files under git; deploys are pushes with hooks you can read.
IdeasAppend-only event trail per idea — the audit log doubles as the activity sparkline.
OperationsLogs, feedback, publishes, scheduled runs: timestamped rows with user ids.
PrivilegeRoot actions funnel through one helper — the privileged API fits on one screen.
Specs45 dated design documents record why every subsystem is the way it is.
part 2 · availability
Honest posture today, engineered path up
todaySingle box, stated plainly
- systemd restarts crashed services automatically
- App restarts don't kill terminals — separate PTY daemon
- WAL-safe backups + snapshots with retention
- Downtime = the VM itself; acceptable for a team workshop
planned · speccedThe path up
- Litestream streaming DB replication — HA rung 1
- Node metrics, upgrade reporting, fail2ban on the edge
- Lease-based failover between boxes
- Container isolation ladder → portable packaging
part 2 · minimal hosting requirements
What it actually takes to run id8
| tier | requirement |
| Required | One small VM — Debian 12, 2–4 vCPU, a few GB RAM, ordinary disk. Reference: a 4-core guest on a workstation hypervisor. |
| Private access | A free-tier Tailscale account (or any WireGuard mesh) — secure reach from anywhere. |
| Public (optional) | Any ~$5/mo VPS running Caddy + one domain. Terminates TLS, forwards over the tailnet, stores nothing. |
| Not required | GPU · container platform · managed database · object storage · load balancer · third-party auth |
Total infrastructure cost: the VM you already have, plus optionally ~$5/mo and a domain.
part 2 · roadmap
An engineered trajectory — every item is a written spec
nearRolling out
- Snapshots, hardening, schedules, push-to-deploy → the fleet
- Member SFTP access (chrooted)
- Per-member VS Code (code-server)
- Per-member network namespaces
platformServices
- Model gateway — one endpoint, any LLM provider
- Services marketplace + per-app roles
- Email · Teams · document generation
- On-box voice (STT / TTS routes)
resilience · v2Hardening
- Litestream DB replication
- Box observability & upkeep
- Container isolation ladder
- Multi-box failover
45 dated specs in-repo · specs are written before code · the backlog is versioned with the source.