>_ muxboard

A web dashboard for your tmux sessions - across one host or a whole fleet, with a live terminal in the browser.

A Flask blueprint you embed in your own app. List, create, kill, and attach tmux sessions over SSH, with default-deny auth and a threat model that takes "remote shell over the web" seriously.

muxboard - web1, db1, build
# the dashboard, in one glance
web1  (prod)
  deploy   release-v42   2 windows   attached   [attach] [kill]
  ops      tailing-logs  1 window    idle 4m    [attach] [kill]
db1   (primary)
  ops      migration     1 window    attached   [attach] [kill]
build
  ci       nightly       3 windows   idle 1h    [attach] [kill]

What it does

Everything you would SSH in to do, surfaced in one page that refreshes itself.

Multi-host inventory

Point it at one machine or a fleet over SSH (key or password). A single host is just the n=1 case of the same config.

Live in-browser attach

A real terminal over a WebSocket-to-PTY bridge and xterm.js. Resize, scrollback, and read-along with other clients.

+

Create, kill, list

Spin up a session with a startup command, kill one behind a type-the-name confirm gate, and watch them all in a self-refreshing list.

🔒

Default-deny auth

You must pass an authorizer. A built-in constant-time token gate is included; plug in your own SSO and scope each person to specific users.

Per-user multiplexing

Manage several Unix users' sockets per host via sudo -n -u, so one login can see deploy, ops, and ci sessions.

Caps and teardown

Per-principal and global attach limits, a 6-hour lifetime cap, and full process-group teardown so nothing leaks fds or zombies.

Quickstart

Embed the blueprint in a Flask app. The single-host case is a few lines.

pip install "muxboard @ git+https://github.com/JacobStephens2/muxboard"
import os
from flask import Flask
from muxboard import Host, Muxboard, token_auth

board = Muxboard(
    hosts=[Host(key="local", hostname="localhost",
                tmux_users=("deploy",), local=True)],
    authorize=token_auth(os.environ["MUXBOARD_TOKEN"]),
    allowed_origins=["https://ops.example.com"],
)
app = Flask(__name__)
board.init_app(app, url_prefix="/mux")
board.start()

Full configuration, the fleet example, and the threat model live in the README.

Read the threat model first

muxboard is not a toy widget. Treat it with the seriousness you would treat sshd.

This grants authenticated remote-shell access over the web. A misconfigured gate is a root shell for a stranger. The defaults fail closed - an unconfigured board denies everything - but the security of your deployment is a property of your configuration. The README documents the attack surface, what is already mitigated (command-injection quoting, cross-site WebSocket protection, confirm gates, resource caps), and what you must do yourself (TLS, rate limiting, least-privilege tmux_users).