tmux-party/README.md
2026-06-01 18:01:26 +02:00

6.8 KiB

tmux-party

l'esprit de la fête

Share a live tmux session with your buddies on a wide range of UNICES!

tmux-party ships party, a POSIX shell utility. One person hosts a party, and others join the fun! Wanna pair-program, mentor, debug an outage together, or demo a workflow? ssh in, party join & off you go!

Built for small, mutually trusted groups: a hacklab, a tech team, a circle of friends, not strangers across the internet. Inspired by epic sessions running GNU's screen -x way back when, now on BSD's tmux modern codebase!

Requirements

  • POSIX shell (/bin/sh)
  • tmux ≥ 3.3 (for server-access), running when you invoke the script
  • A shared system group (default name party, override via TMUX_PARTY_GROUP). Every host and guest must be a member.
  • write(1), optional: used to ping invited guests. Silently skipped when absent.

Install

make install                       # installs to /usr/local
make install PREFIX=$HOME/.local   # or any prefix you prefer

Installs party to $(PREFIX)/bin and party.1 to $(PREFIX)/share/man/man1; man party is the full reference. make uninstall removes both.

On illumos/Solaris the default prefix is /opt/party and the install needs root (pfexec make install) for the system bindir and /etc/default/login. The Makefile is plain POSIX make (works with /usr/bin/make, BSD make, GNU make).

Quick start

One-time setup, as root. Create the group and add members:

groupadd party
usermod -aG party alice
usermod -aG party bob
# alice and bob log out and back in so the new group takes effect

Host a party, then invite from inside it:

party host standup        # spawn a dedicated party tmux server
party invite alice        # add alice to the allowlist (read/write)
party invite bob -r       # invite bob as a read-only watcher

Guests join:

party list                # see what's running on this host
party join standup        # attach (auto-attaches if only one party is running)
party leave               # detach and clean up

The party group is the partyline: filesystem access to party sockets is shared among members, and tmux server-access decides who is actually let into a given session. No shared install directory is needed: each party keeps its own state under its own per-party private directory.

How it works

party host spawns a dedicated tmux server for the party (separate from your personal tmux) so inviting someone exposes only the party, not your other sessions. Each party gets a private directory at ${PARTY_SOCKET_DIR}/party-${USER}:${PARTY_NAME}.d/, holding the tmux socket and a join/leave notification helper. Guests never type the path; party join reads the roster and handles the attach.

Two gates protect every party, and both must pass:

  • Filesystem gate: the per-party directory is chgrp'd to TMUX_PARTY_GROUP at mode 0750; the socket is g+rw. Non-members can't traverse in or reach the socket.
  • Auth gate: tmux server-access allowlist, editable only by the host. A user who clears the FS gate but isn't on the allowlist is rejected at the protocol layer.

Party metadata (host, server pid, group, creation time) lives in a roster file beside the socket. It's bookkeeping only, as security-relevant fields (host user, socket path) are re-derived from the directory on every read, never trusted from the file.

Configuration

Variable Default Purpose
TMUX_PARTY_GROUP party Shared group for socket access. Override to reuse an existing group (wheel, users, staff), or pass --group <name> to party host.
PARTY_SOCKET_DIR /tmp Where each party's private directory (socket + roster) is created.
PARTY_TMUX tmux tmux binary to use. Override if tmux ≥ 3.3 lives at a non-standard path.

Support

The mechanism is identical everywhere: group ownership and mode bits plus tmux server-access. No ACL syscalls involved, so the trust path is one piece of code, not a per-OS matrix.

Platform Status
Linux supported, validated on Debian 13 & Alpine v3.21
FreeBSD UFS or ZFS supported, validated on FreeBSD 15.0 ZFS
illumos LX-branded zones supported, validated on 4.4 BrandZ linux
illumos native, Solaris supported, validated on omnios-r151058
NetBSD, DragonFly unconfirmed, should work, tests welcome
OpenBSD supported, validated on OpenBSD 7.8
macOS supported, validated on Darwin 25.5.0

Security

party assumes you already know and trust everyone you add to the group; it is not a public access-control system. Both gates above protect each party, and the auth gate (tmux server-access) is authoritative, with the filesystem gate as defense in depth.

Three honest caveats, with the full detail in man party:

  • On ACL-enabled filesystems (ZFS, HFS+/APFS), inherited ACLs can override the mode bits, so the FS gate is best-effort. The auth gate still holds.
  • A party's existence is not hidden the way attaching is. That confidentiality rides on the FS gate.
  • Active guests share one tmux server, where any write-capable invitee is trusted by design. Invite read-only (-r) if you do not trust that far.

Status

party is pre-release. The on-disk layout (per-party directory, roster format, socket path) may change between commits, with no upgrade migration, so close running parties before pulling. A stale roster pointing at an unreadable socket simply won't be discovered; old tmux servers left running must be killed by hand.

Reference

Subcommand Effect
party host [name] Spawn a dedicated party tmux server. Only the host is on the allowlist.
party invite alice [-r] Add alice to the allowlist. -r / --read-only invites as a watcher.
party voice alice Promote alice to read/write.
party mute alice Demote alice to read-only.
party kick alice Revoke alice's invite, disconnect her, kill her guest session.
party detach alice Disconnect alice; keep her on the allowlist.
party list List live parties on this host.
party who [--short] Show invited and attached users for the current party.
party status Show the caller's own state: hosting, attached, or idle.
party close Tear down the party server and its roster entry. Host-only.
party join [name] [--passive] Join a party. Auto-attaches when one is running; picker otherwise. --passive attaches read-only to the host's view (watcher mode).
party leave Detach and clean up the per-guest session.
party role [active|passive|switch] Flip your clients between guest and host session. No arg prints the current role.
party --help Help text.

Credits

Written by veg and kol3rby in the context of the UNIX Social Club. Issues and contributions welcome.