7f77772e15
One page embedded in the binary (crates/horizon-server/panel: HTML, CSS and JS, no framework or CDN): status, live TPS, MSPT, RAM and CPU graphs over the last 10 minutes, players with op and kick, the console, and backups with restore, plus restart and stop. It listens on [panel] bind, 127.0.0.1:8130 by default; a tailnet address reaches it from the owner's devices, and any other address is refused unless allow_public is set. `horizon-server panel` prints a one-time login link (10 minutes) that becomes an HttpOnly, SameSite=Strict session cookie. The Host header must name the panel, every POST needs X-Horizon: 1, failed logins are rate-limited, and the page is served with a strict Content-Security-Policy. The control API gains GET /api/v1/metrics and, with the token only, POST /api/v1/panel/login. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>