Skip to content

[codex] Allow external dashboard browser links - #2531

Closed
bricelb wants to merge 1 commit into
nesquena:masterfrom
bricelb:codex/dashboard-external-link
Closed

bricelb wants to merge 1 commit into
nesquena:masterfrom
bricelb:codex/dashboard-external-link

Conversation

@bricelb

@bricelb bricelb commented May 18, 2026

Copy link
Copy Markdown

Summary

This PR allows the Official Hermes Dashboard setting to store an external browser URL, such as a Cloudflared hostname, while preserving the existing SSRF protection for server-side dashboard probes.

Problem

My deployment runs Hermes WebUI behind Cloudflared at one hostname and the official Hermes dashboard behind Cloudflared at another hostname:

  • WebUI: https://hermes.example.com
  • Dashboard: https://dashboard.example.com
  • Dashboard local service: http://127.0.0.1:9119 or 0.0.0.0:9119 on the server

The dashboard settings currently reject non-loopback URLs, so https://dashboard.example.com, http://ai.lan:9119, and similar browser-reachable dashboard URLs fail to save. Loopback URLs like http://127.0.0.1:9119 save, but the frontend derives a browser URL from the WebUI hostname and dashboard port. In a proxied deployment this can produce a broken dashboard link instead of opening the public dashboard hostname.

Approach

  • Keep normalize_dashboard_url() unchanged as the loopback-only server-side probe validator.
  • Add normalize_dashboard_link_url() for browser-facing dashboard links. This accepts external http/https base URLs, rejects credentials, paths, query strings, fragments, and invalid ports, and marks whether the URL is loopback.
  • In auto mode with an external browser link, still probe only the default loopback dashboard targets before showing the link.
  • In always mode with an external browser link, return the external URL directly with external: true.
  • Update the frontend to open status.url directly when external is true and avoid showing the loopback-only warning for external browser links.
  • Update the Settings copy to clarify that loopback URLs are probed server-side, while external URLs are browser links only.

Security notes

The server never probes arbitrary external hosts. probe_official_dashboard() still rejects non-loopback hosts, and external URLs are only returned to the browser as links.

Validation

Ran the targeted dashboard tests in the project environment:

python -m pytest tests/test_dashboard_probe.py tests/test_dashboard_link_ui.py

Result: 18 passed.

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Closing as superseded by #2533

Thanks for tackling this @bricelb — the Cloudflared reverse-proxy scenario where the WebUI and Hermes Dashboard sit at different hostnames is a real deployment shape and worth supporting.

#2533 (@AJV20) merged on May 20 2026 in v0.51.95 and ships the same browser-only dashboard link feature:

  • Settings → System now accepts public browser-only Official Hermes Dashboard URLs (e.g. a Cloudflared hostname) for reverse-proxy setups
  • URL sanitization runs against the configured link before save
  • Server-side dashboard probe is skipped for browser-only links (preserves the SSRF protection on the local probe path)

That covers the use case in your PR body.

If there's something the shipped version doesn't cover

If you run into a specific Cloudflared/reverse-proxy scenario that #2533 doesn't handle correctly (e.g. specific URL shapes, IPv6 hosts in proxy URLs, link sanitization that rejects something valid), open a fresh issue with the URL pattern you need to support and we'll address it.

Closing this draft — the feature lives in master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants