diff --git a/.env.example b/.env.example index d6dddae..e61d725 100644 --- a/.env.example +++ b/.env.example @@ -39,16 +39,13 @@ HERMES_MATRIX_ACCESS_TOKEN= HERMES_API_SERVER_KEY= # --- hermes web dashboard (hermes.apps.williamturner.eu) --- -# Two independent auth layers: Hermes's own login (basic auth — its docs call this -# "not suitable for direct public-internet exposure" alone) plus a Traefik-level basic -# auth gate in front of it. Both required, different credentials recommended. +# Hermes's own login gate — mandatory once its dashboard is bound non-loopback (needed +# for Traefik, a separate container, to reach it at all), so this can't be turned off +# while the dashboard is reachable through Traefik. HERMES_DASHBOARD_USERNAME=william HERMES_DASHBOARD_PASSWORD= # 32+ random bytes — `openssl rand -base64 32` HERMES_DASHBOARD_SECRET= -# htpasswd-format "user:hash" for Traefik's basicauth middleware. Generate with: -# python3 -c "import crypt; print('someuser:' + crypt.crypt('somepassword', crypt.mksalt(crypt.METHOD_SHA512)))" -TRAEFIK_HERMES_AUTH_HASH= # --- portainer (GitOps redeploy) --- PORTAINER_STACK_WEBHOOK_URL= diff --git a/docker-compose.yml b/docker-compose.yml index 4c98a23..b8f5238 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -112,14 +112,11 @@ services: - "traefik.http.routers.hermes-dashboard.rule=Host(`${HERMES_DASHBOARD_HOSTNAME}`)" - "traefik.http.routers.hermes-dashboard.entrypoints=websecure" - "traefik.http.routers.hermes-dashboard.tls.certresolver=letsencrypt" - # Second, independent auth layer in front of Hermes's own login page — its docs - # explicitly call basic-auth-only "not suitable for direct public-internet - # exposure" and cite a real June 2026 incident where scanners reached exposed - # dashboards and drove agents into planting SSH-key backdoors. This means an - # attacker has to clear Traefik's gate before ever reaching Hermes's own auth, - # not just guess one password. - - "traefik.http.routers.hermes-dashboard.middlewares=hermes-dashboard-auth" - - "traefik.http.middlewares.hermes-dashboard-auth.basicauth.users=${TRAEFIK_HERMES_AUTH_HASH}" + # Just TLS termination + routing — no Traefik-level auth middleware. Hermes's own + # login gate is not optional here anyway: it fails closed at startup once its bind + # isn't loopback-only (required for Traefik, a separate container, to reach it at + # all), so a second gate in front of it would only add friction, not remove Hermes's + # own one. One password, at Hermes's own login page. - "traefik.http.services.hermes-dashboard.loadbalancer.server.port=9119" claude-agent: