From 6cc3ffda3eb937408b00bd1a483e959eee735381 Mon Sep 17 00:00:00 2001 From: Santiago Gonzalez Date: Fri, 3 Jul 2026 17:28:14 -0500 Subject: [PATCH] fix: stop dashboard restart loop and harden default API server key The dashboard s6 service was crash-looping forever: HERMES_DASHBOARD_HOST binds to 0.0.0.0 (required so hermes-agent.dappnode:8081 is reachable from the DAppNode network) and HERMES_DASHBOARD_INSECURE no longer bypasses the auth gate on non-loopback binds (upstream hardening, June 2026, closing an exploited hole where scanners found --insecure --host 0.0.0.0 dashboards and planted SSH-key-injecting MCP persistence). With no auth provider configured, hermes dashboard hard-exits on every start, and the s6 finish script restarts it unconditionally, flooding the logs. Configure the bundled username/password auth provider with static credentials (matching this package's existing convention for API_SERVER_KEY and the already-unauthenticated ttyd terminal - the real trust boundary here is the DAppNode network/VPN, not this credential), plus a pinned signing secret and a 30-day session so the one login persists across restarts. Separately, the API server (port 3000) was refusing to start for the same reason: upstream now rejects any API_SERVER_KEY under 16 chars as a guessable placeholder (that endpoint dispatches terminal-capable agent work). Replaced with a strong static key. Known limitation (see PR description): actually logging in still 500s due to an unrelated upstream regression in the dashboard's auto-SSO redirect, tracked upstream and not yet released - the crash loop is fixed, but full dashboard login needs that fix to ship first. --- docker-compose.yml | 15 +++++++++++++-- getting-started.md | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 80b709e..310fa2d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,14 +16,25 @@ services: API_SERVER_ENABLED: "true" API_SERVER_PORT: "3000" API_SERVER_HOST: 0.0.0.0 - API_SERVER_KEY: dappnode + # Must be 16+ chars and not a known placeholder — upstream now refuses + # to start the API server (terminal-capable agent dispatch) with a + # weak/guessable key, even on loopback binds. + API_SERVER_KEY: "e128aa3f5120f9ebbb83488241b6698423914c575826fbfb4542bfdc65954f2e" API_SERVER_CORS_ORIGINS: "*" GATEWAY_ALLOW_ALL_USERS: "true" # Enable the upstream s6 dashboard service on the DAppNode port (8081). HERMES_DASHBOARD: "true" HERMES_DASHBOARD_HOST: 0.0.0.0 HERMES_DASHBOARD_PORT: "8081" - HERMES_DASHBOARD_INSECURE: "true" + # Non-loopback binds require a registered auth provider (upstream fail-closed + # hardening, June 2026) — HERMES_DASHBOARD_INSECURE no longer bypasses this. + # Use the bundled username/password provider with the same static-credential + # convention as API_SERVER_KEY above; the actual trust boundary is the + # DAppNode private network / VPN, not this credential. + HERMES_DASHBOARD_BASIC_AUTH_USERNAME: dappnode + HERMES_DASHBOARD_BASIC_AUTH_PASSWORD: dappnode + HERMES_DASHBOARD_BASIC_AUTH_SECRET: "UKJuFVZecdpgo1ZdqBojtM8ujvEVDxLSS7sIGtY1E4Y=" + HERMES_DASHBOARD_BASIC_AUTH_TTL_SECONDS: "2592000" volumes: - hermes_data:/opt/data logging: diff --git a/getting-started.md b/getting-started.md index 0898f36..c87f8ab 100644 --- a/getting-started.md +++ b/getting-started.md @@ -6,4 +6,4 @@ A **self-hosted AI agent** by [Nous Research](https://nousresearch.com) that run 1. **Set up a provider** — Open the [Setup Wizard](http://hermes-agent.dappnode:8080) and pick an AI provider. 2. **Talk to Hermes** — Message your bot on Telegram/Discord, run `hermes chat` in the [Web Terminal](http://hermes-agent.dappnode:7681), or connect any OpenAI-compatible client to `http://hermes-agent.dappnode:3000`. -3. **Manage your agent** — The [Dashboard](http://hermes-agent.dappnode:8081) lets you view sessions, manage API keys, configure skills, set up scheduled tasks, and check logs. +3. **Manage your agent** — Open the [Dashboard](http://hermes-agent.dappnode:8081) (login: `dappnode` / `dappnode`) to view sessions, manage API keys, configure skills, set up scheduled tasks, and check logs. Change the credentials via the `HERMES_DASHBOARD_BASIC_AUTH_USERNAME`/`_PASSWORD` environment variables (or `dashboard.basic_auth` in `config.yaml`) if you want a private login.