[ops] herodemo public URL has no auth — hero_proxy ready, runbook lacks the auth subsection #182

Closed
opened 2026-04-25 01:09:01 +00:00 by mik-tf · 2 comments
Owner

Symptom

https://herodemo.gent01.grid.tf/ is currently publicly accessible with no authentication. Any visitor can browse:

  • Office documents (real edit access via OnlyOffice now)
  • Files / Photos / Videos via the Files island
  • AI Assistant (consuming our LLM tokens)
  • OSIS Business data via the native Business island
  • Knowledge libraries

For an evaluation demo this is intentional. For anything beyond that — even just preventing scraping/abuse — we need a gate.

Root cause

Configuration gap, not a code gap. hero_proxy (the canonical auth boundary, see home#118) supports four auth_mode values:

  • none — open (default for new domains)
  • bearer — pre-shared bearer token
  • oauth — OAuth provider (Google / GitHub / generic OIDC)
  • optional — guest-first; identity claims forwarded if logged in

hero_demo/docs/ops/DEPLOYMENT_NU_HERO_OS.md does not include any auth setup step, so the herodemo deploy lands with auth_mode=none (db.rs:345 default).

Evidence

  • hero_proxy/crates/hero_proxy_server/src/proxy.rs:1-8,145-159,204-248 — auth modes, OAuth redirect flow, claims injection
  • hero_proxy/crates/hero_proxy_server/src/db.rs:345auth_mode TEXT DEFAULT 'none'
  • hero_os/crates/hero_os_app/src/main.rs:1049 — comment "Guest-mode: no backend auth check" (auth removed from hero_os_app in 2026-04 refactor)
  • hero_proxy/README.md:174-192 — CLI commands for adding domain auth
  • hero_auth/README.md:1-29 — JWT issuer (HS256), Unix socket RPC, OAuth2 server

Fix path (canonical, ~5 minutes per environment)

Per the deployment runbook, after service_install_all runs, configure hero_proxy for the demo domain:

# OAuth (production-grade, requires Google/GitHub credentials)
proxy oauth set google google "$GOOGLE_CLIENT_ID" "$GOOGLE_CLIENT_SECRET"
proxy domain add herodemo.gent01.grid.tf socket /home/driver/hero/var/sockets/hero_router/ui.sock \
  --auth-mode oauth --oauth-provider google

Or for a simpler shared-secret demo gate:

# Bearer (single shared token; everyone uses the same Authorization header)
TOKEN=$(openssl rand -hex 32)
proxy domain add herodemo.gent01.grid.tf socket /home/driver/hero/var/sockets/hero_router/ui.sock \
  --auth-mode bearer --bearer-token "$TOKEN"
# Distribute $TOKEN out-of-band to demo viewers

Or for guest-first with optional login (best of both — public read, but identity captured for those who log in):

proxy domain add herodemo.gent01.grid.tf socket /home/driver/hero/var/sockets/hero_router/ui.sock \
  --auth-mode optional

auth_mode=optional was added in commit 6c7ecbb (2026-04-14) precisely for this guest-first demo case.

Why nginx basic auth is NOT the right answer

  • Duplicates hero_proxy's auth at a different layer
  • Breaks X-Hero-Context / X-Hero-Claims injection that downstream services depend on
  • No SSO / OAuth / session cookies — degraded UX
  • Unprofessional alongside hero_proxy's polished OAuth flow

Action items

  • Update hero_demo/docs/ops/DEPLOYMENT_NU_HERO_OS.md with an "Auth" subsection covering all three modes (oauth / bearer / optional)
  • Add an env-driven setup snippet to hero_skills so HERO_AUTH_MODE=oauth (or =bearer, =optional) at install time configures hero_proxy automatically
  • Document the canonical socket target for hero_proxy domain routes — /home/driver/hero/var/sockets/hero_router/ui.sock (the unified entrypoint)
  • Decide herodemo's policy: does it stay open for evaluation, or do we gate it? If gating, which mode? Default for the runbook should reflect the team's chosen norm.

Demo state on herodemo (2026-04-24)

  • Public URL accessible without auth — by design for this evaluation phase
  • hero_proxy is installed and ready; just needs domain route with auth_mode set
  • Filing this so the gating decision and the runbook update happen in one place
  • home#118 — auth migration to hero_proxy
  • home#160 — consolidated demo state
  • hero_proxy repo (auth) and hero_auth repo (JWT issuer) — both production-ready

Signed-off-by: mik-tf

## Symptom `https://herodemo.gent01.grid.tf/` is currently **publicly accessible with no authentication**. Any visitor can browse: - Office documents (real edit access via OnlyOffice now) - Files / Photos / Videos via the Files island - AI Assistant (consuming our LLM tokens) - OSIS Business data via the native Business island - Knowledge libraries For an **evaluation demo** this is intentional. For anything beyond that — even just preventing scraping/abuse — we need a gate. ## Root cause Configuration gap, not a code gap. `hero_proxy` (the canonical auth boundary, see [home#118](https://forge.ourworld.tf/lhumina_code/home/issues/118)) supports four `auth_mode` values: - `none` — open (default for new domains) - `bearer` — pre-shared bearer token - `oauth` — OAuth provider (Google / GitHub / generic OIDC) - `optional` — guest-first; identity claims forwarded if logged in `hero_demo/docs/ops/DEPLOYMENT_NU_HERO_OS.md` does not include any auth setup step, so the herodemo deploy lands with `auth_mode=none` (db.rs:345 default). ## Evidence - `hero_proxy/crates/hero_proxy_server/src/proxy.rs:1-8,145-159,204-248` — auth modes, OAuth redirect flow, claims injection - `hero_proxy/crates/hero_proxy_server/src/db.rs:345` — `auth_mode TEXT DEFAULT 'none'` - `hero_os/crates/hero_os_app/src/main.rs:1049` — comment "Guest-mode: no backend auth check" (auth removed from hero_os_app in 2026-04 refactor) - `hero_proxy/README.md:174-192` — CLI commands for adding domain auth - `hero_auth/README.md:1-29` — JWT issuer (HS256), Unix socket RPC, OAuth2 server ## Fix path (canonical, ~5 minutes per environment) Per the deployment runbook, after `service_install_all` runs, configure hero_proxy for the demo domain: ```bash # OAuth (production-grade, requires Google/GitHub credentials) proxy oauth set google google "$GOOGLE_CLIENT_ID" "$GOOGLE_CLIENT_SECRET" proxy domain add herodemo.gent01.grid.tf socket /home/driver/hero/var/sockets/hero_router/ui.sock \ --auth-mode oauth --oauth-provider google ``` Or for a simpler shared-secret demo gate: ```bash # Bearer (single shared token; everyone uses the same Authorization header) TOKEN=$(openssl rand -hex 32) proxy domain add herodemo.gent01.grid.tf socket /home/driver/hero/var/sockets/hero_router/ui.sock \ --auth-mode bearer --bearer-token "$TOKEN" # Distribute $TOKEN out-of-band to demo viewers ``` Or for **guest-first with optional login** (best of both — public read, but identity captured for those who log in): ```bash proxy domain add herodemo.gent01.grid.tf socket /home/driver/hero/var/sockets/hero_router/ui.sock \ --auth-mode optional ``` `auth_mode=optional` was added in commit `6c7ecbb` (2026-04-14) precisely for this guest-first demo case. ## Why nginx basic auth is NOT the right answer - Duplicates hero_proxy's auth at a different layer - Breaks `X-Hero-Context` / `X-Hero-Claims` injection that downstream services depend on - No SSO / OAuth / session cookies — degraded UX - Unprofessional alongside hero_proxy's polished OAuth flow ## Action items - [ ] Update `hero_demo/docs/ops/DEPLOYMENT_NU_HERO_OS.md` with an "Auth" subsection covering all three modes (oauth / bearer / optional) - [ ] Add an env-driven setup snippet to `hero_skills` so `HERO_AUTH_MODE=oauth` (or `=bearer`, `=optional`) at install time configures hero_proxy automatically - [ ] Document the canonical socket target for hero_proxy domain routes — `/home/driver/hero/var/sockets/hero_router/ui.sock` (the unified entrypoint) - [ ] Decide herodemo's policy: does it stay open for evaluation, or do we gate it? If gating, which mode? Default for the runbook should reflect the team's chosen norm. ## Demo state on herodemo (2026-04-24) - Public URL accessible without auth — by design for this evaluation phase - hero_proxy is installed and ready; just needs domain route with auth_mode set - Filing this so the gating decision and the runbook update happen in one place ## Related - [home#118](https://forge.ourworld.tf/lhumina_code/home/issues/118) — auth migration to hero_proxy - [home#160](https://forge.ourworld.tf/lhumina_code/home/issues/160) — consolidated demo state - `hero_proxy` repo (auth) and `hero_auth` repo (JWT issuer) — both production-ready Signed-off-by: mik-tf
Author
Owner

Demo hotfix landed 2026-04-25

Per user request, basic auth gating is now live on herodemo:

  • nginx-light installed on VM
  • htpasswd: admin / admin123 (single demo credential)
  • nginx listens on 10.1.2.2:9988 (the port TF Grid gateway forwards to)
  • hero_router moved to 10.1.2.2:9990 via hero_proc action edit (--ui-port 9990)
  • nginx config supports WebSocket upgrade (map $http_upgrade -> Connection upgrade) and disables proxy buffering for OnlyOffice's long-polling

Verified:

curl https://herodemo.gent01.grid.tf/         -> 401
curl -u admin:admin123 https://herodemo.gent01.grid.tf/  -> 200

This is not the canonical Hero auth path. The proper answer remains hero_proxy with auth_mode oauth/bearer/optional (this issue's body covers it). Demo VM is gated for now; production/long-term should land hero_proxy auth via the runbook.

Snapshot is overdue and will capture this state.

Signed-off-by: mik-tf

## Demo hotfix landed 2026-04-25 Per user request, basic auth gating is now live on herodemo: - nginx-light installed on VM - htpasswd: admin / admin123 (single demo credential) - nginx listens on 10.1.2.2:9988 (the port TF Grid gateway forwards to) - hero_router moved to 10.1.2.2:9990 via hero_proc action edit (`--ui-port 9990`) - nginx config supports WebSocket upgrade (map $http_upgrade -> Connection upgrade) and disables proxy buffering for OnlyOffice's long-polling Verified: ``` curl https://herodemo.gent01.grid.tf/ -> 401 curl -u admin:admin123 https://herodemo.gent01.grid.tf/ -> 200 ``` This is **not** the canonical Hero auth path. The proper answer remains hero_proxy with auth_mode oauth/bearer/optional (this issue's body covers it). Demo VM is gated for now; production/long-term should land hero_proxy auth via the runbook. Snapshot is overdue and will capture this state. Signed-off-by: mik-tf
Author
Owner

Deploy-side complete on hero_skills/development:

  • Demo nginx basic-auth: basic_auth_setup (commit 011dd83, PR #129)
  • Canonical hero_proxy auth-mode: proxy_auth_setup (commit f17e99c, PR #130)

Long-term consolidation onto the canonical path tracked at #186 — once that lands, the demo helper goes away. Closing this issue since both deploy paths ship.

Deploy-side complete on `hero_skills/development`: - Demo nginx basic-auth: `basic_auth_setup` (commit `011dd83`, [PR #129](https://forge.ourworld.tf/lhumina_code/hero_skills/pulls/129)) - Canonical hero_proxy auth-mode: `proxy_auth_setup` (commit `f17e99c`, [PR #130](https://forge.ourworld.tf/lhumina_code/hero_skills/pulls/130)) Long-term consolidation onto the canonical path tracked at https://forge.ourworld.tf/lhumina_code/home/issues/186 — once that lands, the demo helper goes away. Closing this issue since both deploy paths ship.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/home#182
No description provided.