Hub mode
pyobs-web-admin can act as a hub to control multiple remote pyobs hosts from a single browser session. When remote hosts are configured, a Hosts section appears at the top of the sidebar; clicking a host switches the active context, and most views (dashboard, config, logs) transparently proxy their actions to that host’s own API instead of the local one.
Setup
On the hub (the machine you browse to), list the remote hosts:
HUB_HOSTS = [
{"name": "obs1", "url": "http://obs1:8765", "token": "shared-secret"},
{"name": "obs2", "url": "http://obs2:8765", "token": "another-secret"},
]
On each remote host (a “spoke”), set the matching token so it accepts requests carrying it:
HUB_TOKEN = "shared-secret" # must match the token the hub sends for this host
Authentication
The hub authenticates to a remote instance via an X-Hub-Token header. A remote instance
that receives a request carrying its configured HUB_TOKEN bypasses the normal
browser-session/CSRF check for that request – this is what lets the hub call it without a
login session of its own. The token is a plain pre-shared string with no other layer on top
of it, so treat it like any other bearer credential: long, random, and secret.
One active host at a time – and the exception
Most hub-aware views (Dashboard, Config, Logs) follow a “one active host at a time” model:
whichever host the sidebar selector points at is the one all actions target, mirroring a
single-host session. A few pages instead need to aggregate every configured host on one
page regardless of the active-host selection – the ACL matrix and per-module ACL editing matrix, the
fleet-wide Overview page, and the fleet-wide Users page (XMPP user management)
all fall into this second category, since their entire purpose is a cross-host view. Each of
those pages queries every HUB_HOSTS entry independently and shows unreachable hosts as a
warning banner rather than failing the whole page or hiding the gap silently.