No description
  • Go 58%
  • templ 37.2%
  • JavaScript 3.9%
  • Makefile 0.6%
  • Dockerfile 0.3%
Find a file
zemdregon 104e15accc
Some checks are pending
CI / lint (push) Waiting to run
CI / test (push) Waiting to run
CI / build (push) Waiting to run
CI / docker (push) Blocked by required conditions
chore(deps): bump actions/setup-go to v7 (#26)
* chore(deps): bump actions/setup-go to v7

Self-hosted CI workflows.

* ci: disable setup-go cache on self-hosted runner

cache-save was hanging and failing otherwise-green jobs.
2026-08-10 18:46:08 -05:00
.github chore(deps): bump actions/setup-go to v7 (#26) 2026-08-10 18:46:08 -05:00
assets fix: restore MVP admin monitor, automation, and jellyfin surfaces 2026-08-08 23:14:45 -05:00
docs feat: soft-empty library pages and admin regression tests (#24) 2026-08-10 18:04:29 -05:00
handler feat: soft-empty library pages and admin regression tests (#24) 2026-08-10 18:04:29 -05:00
session Phase 5: Production Hardening 2026-06-11 05:44:40 -05:00
templ feat: soft-empty library pages and admin regression tests (#24) 2026-08-10 18:04:29 -05:00
.env.example feat: formats surface, client IP helpers, and auth/audit hardening 2026-07-22 19:09:18 -05:00
.gitignore chore: remove accidentally committed node_modules 2026-08-08 23:15:19 -05:00
.golangci.yml Phase 5: Production Hardening 2026-06-11 05:44:40 -05:00
CHANGELOG.md Prefer settings capability for Settings discovery (v0.1.10). 2026-08-10 04:56:55 -05:00
clientip.go feat: formats surface, client IP helpers, and auth/audit hardening 2026-07-22 19:09:18 -05:00
CONTRIBUTING.md feat: formats surface, client IP helpers, and auth/audit hardening 2026-07-22 19:09:18 -05:00
Dockerfile Production polish: CSRF, CSP, degraded mode, logging, Docker, fixes 2026-06-11 06:00:23 -05:00
go.mod Pin core/sdk to v0.5.1 for mTLS mesh dial. 2026-08-09 22:42:22 -05:00
go.sum Pin core/sdk to v0.5.1 for mTLS mesh dial. 2026-08-09 22:42:22 -05:00
input.css admin-ui: SSE cluster, responsive layout, CI pipeline, audit logging 2026-06-12 11:41:48 -05:00
LICENSE Initial commit: scaffold admin-ui module 2026-06-10 21:12:26 -05:00
main.go fix: redirect login to public auth origin, exchange on loopback 2026-08-09 17:56:12 -05:00
main_test.go admin-ui: SSE cluster, responsive layout, CI pipeline, audit logging 2026-06-12 11:41:48 -05:00
Makefile Initial commit: scaffold admin-ui module 2026-06-10 21:12:26 -05:00
MEDIA_ADMIN.md feat: formats surface, client IP helpers, and auth/audit hardening 2026-07-22 19:09:18 -05:00
metrics.go Phase 5: Production Hardening 2026-06-11 05:44:40 -05:00
muxcore.json feat: soft-empty library pages and admin regression tests (#24) 2026-08-10 18:04:29 -05:00
muxcore_json_test.go feat: soft-empty library pages and admin regression tests (#24) 2026-08-10 18:04:29 -05:00
package-lock.json fix: restore MVP admin monitor, automation, and jellyfin surfaces 2026-08-08 23:14:45 -05:00
package.json fix: restore MVP admin monitor, automation, and jellyfin surfaces 2026-08-08 23:14:45 -05:00
ratelimit.go feat: formats surface, client IP helpers, and auth/audit hardening 2026-07-22 19:09:18 -05:00
ratelimit_test.go feat: formats surface, client IP helpers, and auth/audit hardening 2026-07-22 19:09:18 -05:00
README.md feat: formats surface, client IP helpers, and auth/audit hardening 2026-07-22 19:09:18 -05:00
SECURITY.md feat: formats surface, client IP helpers, and auth/audit hardening 2026-07-22 19:09:18 -05:00
tailwind.config.js Initial commit: scaffold admin-ui module 2026-06-10 21:12:26 -05:00

MuxCore Admin UI

CI Go Version License: GPL-3.0

Web dashboard for MuxCore — modules, cluster, events, audit, and settings.

A sidecar module that connects to a running muxcored instance via gRPC and serves a browser-based admin interface using Go + Templ + HTMX + Tailwind CSS. No JavaScript framework, no Node.js build step — everything is compiled into a single Go binary.


Quick start

# Build the binary
make build

# Run against a local muxcored (dev mode, no TLS)
export ADMIN_UI_CORE_ADDR=localhost:9090
export ADMIN_UI_INSECURE=true
./admin-ui
# → Listening on :8080

Open http://localhost:8080 in a browser. Login redirects to the auth module (ADMIN_UI_AUTH_ADDR); after login, the browser returns via /auth/callback.


Requirements

  • Go 1.26+
  • A running muxcored instance (v0.1.0+)
  • An auth module reachable at ADMIN_UI_AUTH_ADDR (for login)
  • An Authorizer module registered with core (for admin.access)
  • Tailwind CSS standalone CLI (for CSS builds — make css downloads it)

Configuration

All configuration is via environment variables:

Variable Default Description
ADMIN_UI_ADDR :8080 HTTP listen address
ADMIN_UI_CORE_ADDR localhost:9090 Core gRPC address
ADMIN_UI_INSECURE false Disable TLS for core gRPC (dev only)
ADMIN_UI_AUTH_ADDR http://localhost:9401 Auth module base URL (login + code exchange)
ADMIN_UI_TLS_CERT TLS cert file path (enables HTTPS)
ADMIN_UI_TLS_KEY TLS key file path
ADMIN_UI_SESSION_TTL 30m Session lifetime
ADMIN_UI_LOG_LEVEL info Log level (debug, info, warn, error)
ADMIN_UI_LOG_FORMAT text Log format: text or json
ADMIN_UI_TRUSTED_PROXIES loopback Comma-separated CIDRs whose X-Forwarded-For is trusted (empty → 127.0.0.0/8, ::1/128)

Production deployment

Docker

docker build -t admin-ui .
docker run -d --restart=unless-stopped \
  -p 8080:8080 \
  -e ADMIN_UI_CORE_ADDR=core:9090 \
  -e ADMIN_UI_LOG_FORMAT=json \
  admin-ui

The Docker image uses a multi-stage build: Tailwind CSS is compiled in the first stage, the Go binary is built in the second, and the final runtime is alpine:3.21 (non-root user, ~10MB image).

TLS (HTTPS for the admin UI)

export ADMIN_UI_TLS_CERT=/etc/ssl/cert.pem
export ADMIN_UI_TLS_KEY=/etc/ssl/key.pem
./admin-ui

When TLS is enabled, the session and CSRF cookies are marked Secure.

JSON logging (production)

export ADMIN_UI_LOG_FORMAT=json
export ADMIN_UI_LOG_LEVEL=info

Produces structured JSON log lines for ingestion by log aggregators (Loki, Datadog, Splunk).

Health checks

Endpoint Purpose Response
/health Liveness + readiness {"status":"ok","version":"..."} or {"status":"degraded","version":"..."} (503) when core is down
/metrics Prometheus scraping Plain text Prometheus metrics

Reverse proxy

When placing behind nginx or Caddy, forward:

  • X-Forwarded-For — client IP for rate limiting (honored only when the TCP peer is in ADMIN_UI_TRUSTED_PROXIES; otherwise RemoteAddr is used)

X-Real-IP is not used. Untrusted peers cannot spoof client IP via XFF. CSRF uses a double-submit cookie (csrf-token + X-CSRF-Token), not Origin/Host checks.


Architecture

Browser ──HTTP──→ admin-ui ──gRPC──→ muxcored
                  (Templ + HTMX)     (Discovery, Events, Storage, Mesh, Health)

Auth flow:

  1. Browser → GET /login → redirect to ADMIN_UI_AUTH_ADDR/login?redirect=.../auth/callback
  2. Auth module returns with ?code=... → admin-ui POSTs {code} to ADMIN_UI_AUTH_ADDR/login/exchange
  3. On success, server-side session created (cookie-based, in-memory store)
  4. Every subsequent request validates session cookie and requires Authorizer.Can("admin.access") on admin.ui
  5. CSRF protection via double-submit cookie pattern

Live updates:

  • Dashboard health grid: HTMX polling every 5s
  • Cluster nodes: HTMX + SSE (/cluster/sse, trigger sse:cluster-update)
  • Events: HTMX polling every 3s (stats every 10s)
  • All static assets embedded in binary (zero disk I/O at runtime)

Development

make dev        # Build CSS + run with dev defaults
make css        # Compile Tailwind CSS
make css-watch  # Watch mode for Tailwind
make build      # Build production binary
make test       # Run tests
make lint       # golangci-lint + go vet
make clean      # Remove build artifacts
make fmt        # Format Go + Templ files

License

GPL-3.0