Control panel — product north star & build order
The canonical "what we're building and in what order" — HostSSH as a class-of-its-own server control plane (deploy + browser-root access + hardening + monitoring + AI), the verified implementation status, the security build order, and the license-code business model.
Control panel — product north star & build order
This is the synthesis doc: the one place that says what HostSSH is, what's actually built, and the order we build the rest. It links out to the detailed specs rather than duplicating them. It supersedes any "Coolify-class" framing — that's the feature floor, not our identity.
Coolify deploys your apps. HostSSH runs your server. One package on any machine → deploy + browser-root access + hardening + monitoring + an AI co-pilot that operates the box — fully owned, license-coded, white-labelable. We host, maintain, and support it; customers unlock it with a license code from their account.
The product in one picture
┌──────────────────────────────────────────────┐
Customer ─ browser ─► │ Control Plane (Next.js · app.hostssh.com) │
(passkey/WebAuthn) │ god+customer console · /v1 API · SSH-CA │
│ license/cert minter · audit custodian │
└───────────────┬──────────────────────────────┘
│ ONE egress-only spine (agent dials out; ZERO inbound ports)
│ heartbeat ▲ telemetry ▼ signed jobs + desired-version + PTY ws
┌───────────────┴──────────────────────────────┐
│ Agent (one static Go binary, per box) │
│ daemon + CLI + on-box panel + harden + PTY │
│ ├─ Build: HostPack (Railpack/MIT → BuildKit)│
│ ├─ Run: Docker/Podman │
│ ├─ Route: Traefik (auto Let's Encrypt) │
│ ├─ Harden: internal/harden (one-click+drift) │
│ ├─ Access: SSH cert-only + PTY ws (recorded) │
│ └─ Protect: restic / .hsi (capture/restore) │
└───────────────┬──────────────────────────────┘
▼ encrypted .hsi + WORM audit
┌──────────────────────────────────────────────┐
│ Customer-owned storage (R2/S3) — no-hostage │
└──────────────────────────────────────────────┘
Three planes + one spine. The split already exists in code; we fill the gaps. Detail: Architecture, agent-protocol.
What's actually true (status — keep honest)
- Proven on metal: build→run→route — Phase 1 on
.223, 2026-06-22. The real agent built (HostPack/ Railpack→BuildKit), ran (Docker), and routed (our Traefik) a sample app; verified by curl. See PLATFORM. - Built, not yet wired: the Go agent (deploy/db/logs/drill/retention/license-gate/heartbeat, stdlib-only)
and the Next.js god console exist — but the control-plane
/v1/*endpoints the agent already calls do not exist, and dashboard deploys are simulated (lib/platform/store.ts). - Spec, not implemented (security spine — verified fail-open): plain
http.Client(no mTLS),Activate()doesn't verify the token,install.shfetches an unsigned binary. agent-protocol is the target, not current reality. - Greenfield "wow" surfaces (the differentiators): browser-root-SSH, the hardening engine, real host monitoring — designed (hardening, web-ssh), not yet built.
Build order (non-negotiable sequencing)
The crown jewel (browser-root-SSH) ships last, behind the security spine — shipping it first is how you lose a customer's box.
- Supply-chain + transport spine — sign the binary + verify in the installer (embedded key); mTLS +
control-plane cert pinning, reject non-TLS;
Activate()verifies the token before storing; signed fingerprint-bound grace refresh; append-only off-box hash-chained audit; license-allowlist CI gate. - Close the loop — build
/v1/license/activate,/v1/telemetry/heartbeat,/v1/fleet/*,/v1/jobs/{id}/stream; push realgopsutilhost metrics on the existing heartbeat; flip the dashboard'splatformMode()seam from simulated → live. (Highest leverage, almost no new product.) 2.5 HostPack Phase 0 — ship the prose-not-code defaults (--init, Traefik healthchecks, glibc pinning,install.shprovisions buildkitd + base pre-pull). See hostpack. - Hardening engine v1 —
internal/harden+ Security Score; one-click "Secure my server" with armed auto-revert. The headline trust feature; ships before the riskier PTY. See hardening. - On-box panel + jobs SSE — embedded React SPA on the agent (same component tree as cloud, two DataAdapters), local-autonomous during a control-plane outage.
- Browser-root-SSH — SSH-CA (HSM/KMS, per-tenant), WebAuthn step-up, ≤5-min single-host certs, recorded PTY, kill-switch — pen-tested before any customer box. See web-ssh.
License-code business model
(Synthesis from the locked direction + agent-protocol; the adversarial license-bypass red-team is the one design pass still owed — run it when the API throttle clears.)
- Account → license code. Each account issues plan-tiered codes (per-server and/or per-seat) from a "Your license keys" UI. We host, maintain, support; the code is the unlock + support entitlement + billing anchor.
- Activation. One-liner installs the agent →
POST /v1/license/activate {key, fingerprint}→ control plane verifies, binds the seat, mints an ed25519 token (plan, seats, features, expiry) + a per-agent client cert. The agent embeds the public key and verifies offline. - Enforcement. Two-layer: offline ed25519 verify on every privileged action + a daily heartbeat that confirms not-revoked/within-seats and returns a fresh short-TTL token. 14-day offline grace so a box is never bricked. Capture/restore are NEVER gated — the no-hostage invariant.
- Anti-bypass (must hold): fingerprint is a hint only (copyable by root) — the real boundary is short-TTL signed tokens + server-side seat enforcement + heartbeat revocation; grace refresh requires a signed response (a bare HTTP 200 must not refresh grace, else revocation is defeated). Cloud-only features are server-side entitlement-checked, not client-trusted.
- Billing. Stripe drives plan → entitlement mapping;
license/transferrebinds a seat on migrate/rebuild so customers never burn a seat doing the thing the product exists to do.
Component stack — 100% ownable (verified)
Every external piece is permissive (MIT/ISC/Apache-2.0/BSD/MPL) — no GPL/AGPL/SSPL. Licenses re-verified against source where they were previously mis-stated.
| Component | Role | License |
|---|---|---|
| HostSSH agent / control plane | our IP | Proprietary (Girard-Media) |
| Railpack (HostPack engine) | build → OCI | MIT (was mis-doc'd Apache-2.0) |
| BuildKit · containerd · docker/cli · x/* | build backend / runtime | Apache-2.0 / BSD |
creack/pty · @xterm/xterm | browser-root PTY + terminal | MIT |
coder/websocket | outbound PTY / low-latency jobs | ISC |
golang.org/x/crypto/ssh + ed25519 | SSH cert-only gateway + CA | BSD-3 |
shirou/gopsutil | host metrics on the heartbeat | BSD-3 |
| CrowdSec (Security Engine) | intrusion prevention | MIT (use over GPL fail2ban) |
| cloudflared / Tailscale (BYO) | egress-only transport | Apache-2.0 / BSD-3 |
| restic + rclone | backup drill / retention / .hsi | BSD-2 / MIT |
| Coolify-hosted Postgres + pgvector | state/telemetry/license/audit | PostgreSQL License |
| Recharts / visx / uPlot (pick one) | dashboard charts (NEVER Grafana=AGPL) | MIT |
Banned (verified copyleft/source-available): Grafana (AGPL), Cockpit (LGPL/GPL), Netdata (GPL), fail2ban (GPL), Teleport (AGPL/SSPL-adjacent), CIS-CAT (proprietary).
Open decisions (owner)
- SSH-CA topology — per-tenant CA (recommended, limits blast radius) vs fleet-wide; KMS vs HSM for the key. The single most valuable secret; can't defer past the Web-SSH phase.
- Canonical registry host —
registry.girardmedia.comvsregistry.hostssh.comfor HostPack base images (bakes into config + engine constants). - Binary distribution — GitHub Releases (third party in trust path) vs R2 + Worker behind
dl.hostssh.com(fully owned; recommended). - Root default — the vision says "starting with root"; recommend default = named non-root principal, root as an explicit WebAuthn-gated elevation (second-approver on prod).
- Charts library — pick one before Phase-1 dashboard work multiplies the choice.
Detailed specs
PLATFORM · agent-protocol · hostpack · hardening · control-plane-dashboard · Architecture · Security · Licensing · user: Web-SSH · user: Hardening