Skip to main content
Admin Modules

Federation & Multi-User Portal

Cross-network health monitoring, per-user dashboard profiles, and the federation of Milky Way and Andromeda into a unified portal

February 25, 2026

Federation & Multi-User Portal

Arcturus-Prime federates two homelab networks — Milky Way (Milky Way, local) and Andromeda (Andromeda, remote) — into a single portal. Each user sees a personalized dashboard with services, widgets, and theme colors tailored to their role and network affinity.

Networks

NetworkGalaxyLocationConnectivity
Milky WayMilky WayLocal (10.42.0.0/24)Direct LAN
AndromedaAndromedaRemote (192.168.20.0/24)Tailscale + CF Tunnels

Services on Andromeda are accessed through Cloudflare Tunnels from Meridian-Host or via the mm-Arcturus-Prime proxy. Services on Milky Way are accessed through the primary tunnel on Altair-Link or directly on LAN.

Federation Health API

GET /api/federation/health checks both networks in parallel and returns filtered status.

Request

Requires authentication. Returns only services the authenticated user has access to.

Response

{
  "networks": {
    "milky-way": { "online": true, "serviceCount": 12 },
    "andromeda": { "online": true, "serviceCount": 8 }
  },
  "userServices": [
    { "id": "plex-bogie", "label": "Plex", "network": "andromeda", "status": "up" },
    { "id": "rutorrent-bogie", "label": "ruTorrent", "network": "andromeda", "status": "up" }
  ]
}

Health Check Sources

NetworkSourceTimeout
Andromedamm-Arcturus-Prime /api/health (container count)8s
Milky WayUptime Kuma /api/status-page/public (heartbeats)8s

Both checks run with Promise.allSettled — one network failing does not block the other. Results are cached for 30 seconds with stale-while-revalidate at 60 seconds.

Dashboard Profiles

Profiles define which widgets a user sees, their ordering, and theme colors. Ten built-in profiles ship with Arcturus-Prime:

Role-Based Profiles

ProfileWidgetsThemeDefault For
adminAll 13 widgetsCyan/VioletAdmin role
membersites, deploy, media suite, editor, workbenchBlue/CyanMember role
demosites, plex, tautulliSlate/BlueDemo role
homelabinfra-status, docker-containers, vm-statusGreen/Cyan
creatorsites, deploy, editor, workbenchAmber/Violet
mediaplex, rutorrent, audiobookshelf, tautulliPink/Violet
beasites, cf-pages, ai-chatPink/Rose

User-Specific Profiles

ProfileWidgetsThemeNetwork
bogie-commandquick-launch, plex, audiobookshelf, rutorrent, tautulli, grafana-embed, storage-overview, speedtestCyan/TealAndromeda
bogie-infrastorage-overview, network-status, grafana-embedGreen/CyanAndromeda
mauvequick-launch, plex, rutorrent, audiobookshelf, ai-chatPink/VioletMilky Way

Profiles are stored in KV at data:dashboard-profiles and managed through /admin/dashboard-profiles.

Widget Registry

Eighteen widgets are available across four categories. Each widget can be gated by role, feature flag, or service assignment.

Infrastructure

WidgetRequiresComponent
infra-statusAdmin roleDashInfraStatus.astro
docker-containersAdmin roleDashDockerContainers.astro
vm-statusAdmin roleDashVmStatus.astro
storage-overviewunraid-dashboard serviceInline (polls /api/mm-Arcturus-Prime/dashboard)
network-statusInline (polls /api/federation/health)

Media

WidgetRequiresComponent
plexplex serviceDashPlex.astro
rutorrentrutorrent serviceDashRutorrent.astro
audiobookshelfaudiobookshelf serviceDashAudiobookshelf.astro
tautullitautulli serviceDashTautulli.astro

Sites

WidgetRequiresComponent
sitessites featureDashSites.astro
deploy-statussites featureDashDeployStatus.astro
cf-pagessites featureDashCfPages.astro

Tools

WidgetRequiresComponent
editoreditor featureDashEditor.astro
workbenchworkbench featureDashWorkbench.astro
ai-chatDashAiChat.astro
quick-launchInline (renders user’s quickLinks)
grafana-embedgrafana serviceInline (iframe)
speedtestspeedtest serviceInline (iframe)

Inline Widgets

Five widgets render inline in the dashboard without a dedicated Astro component:

  • Quick Launch — grid of large tappable buttons from the user’s quickLinks array (defined in their KV user record)
  • Grafana Embed — iframe pointing to the user’s Grafana dashboard in kiosk mode
  • Speedtest — iframe embedding Speedtest Tracker
  • Storage Overview — polls /api/mm-Arcturus-Prime/dashboard every 60 seconds, shows disk usage bars
  • Network Status — polls /api/federation/health every 60 seconds, shows galaxy status dots

User Records

Two new fields were added to UserRecord and AuthUser in src/lib/roles.ts:

FieldTypePurpose
networkAffinity'milky-way' | 'andromeda'User’s primary network
quickLinksQuickLink[]Quick Launch widget buttons

A QuickLink has: label, url, icon (FA class), and optional serviceId.

Example User Records

bogie (member, Andromeda):

  • Services: plex, rutorrent, audiobookshelf, tautulli, grafana, speedtest, unraid-dashboard
  • Profiles: bogie-command, bogie-infra
  • Quick Links: Plex, Audiobooks, Downloads, Grafana, Unraid

mauve (member, Milky Way):

  • Services: plex, rutorrent, audiobookshelf
  • Profiles: mauve
  • Quick Links: Plex, Audiobooks, Downloads

Security Model

  • Service URLs are resolved server-side in SSR — unauthorized users never see them in page source
  • The service registry enforces per-user filtering before any URL is rendered
  • The mm-Arcturus-Prime proxy injects the Bearer token server-side — it is never exposed to the browser
  • Restart API checks both service assignment AND container running state
  • Each CF Tunnel hostname has its own CF Access policy with email allowlists
  • Dual-layer auth: Cloudflare Access (edge) + Arcturus-Prime RBAC (application)

Files

FilePurpose
src/lib/service-registry.tsService definitions, KV storage, resolution
src/lib/widget-registry.tsWidget metadata and filtering
src/lib/dashboard-profiles.tsProfile definitions and KV storage
src/lib/roles.tsUserRecord with networkAffinity, quickLinks
src/pages/api/federation/health.tsCross-network health aggregation
src/pages/api/admin/services.tsAdmin CRUD for service registry
src/pages/api/user/service-restart.tsSafe restart with admin-disable protection
src/pages/api/mm-Arcturus-Prime/[...path].tsProxy with member read-only access
src/pages/dashboard/index.astroDashboard with per-user widget rendering
adminfederationmulti-userprofilesnetworkshealth-checkwidgets