Skip to main content

The runspec console chat-room server — a dumb message pipe with presence: console SSH-tunnel door + OIDC-authenticated browser web door

Project description

runspec-room

The server behind the runspec-console chat room — a dumb message pipe with presence. It holds, per room, the connected participants, their live presence, and a durable transcript, and it does three things: accept connections, stamp + persist each inbound message, and broadcast every message / presence change to everyone else in the room. All the intelligence stays in the consoles — the server never runs anything.

See docs/design/console-room-server.md for the full design and decisions.

Status — complete server (S1–S3)

Two front doors, one process:

  • Console door — an NDJSON listener on localhost, which each runspec-console reaches by opening a direct-tcpip channel over its existing pooled SSH connection. A console's right to be in the room is its SSH access — no new exposed port, no second credential.
  • Browser door — a WebSocket endpoint (/ws) plus a small vanilla static frontend (transcript / composer / presence) with recent-history backscroll for people. Authenticated via OIDC (no passwords stored); identity comes from the signed-cookie session. TLS is self-terminated or left to a reverse proxy.

Run it

pip install -e .

# Full server (browser + console doors):
console-room --port 8080 --ndjson-port 8765 --db ./console_room.db

# Console door only (no web deps needed):
console-room --ndjson-only --ndjson-port 8765 --db ./console_room.db

The console door stays on localhost — consoles tunnel in. Open the browser door at the web port.

Enabling login (OIDC) + TLS

Without OIDC config the browser door runs in dev mode — unauthenticated, identity from a ?user= join form (a warning is logged; don't expose it). Set the OIDC env vars to require single sign-on:

export CONSOLE_ROOM_OIDC_ISSUER="https://login.microsoftonline.com/<tenant>/v2.0"
# or CONSOLE_ROOM_OIDC_METADATA_URL=<discovery doc URL>
export CONSOLE_ROOM_OIDC_CLIENT_ID="…"
export CONSOLE_ROOM_OIDC_CLIENT_SECRET="…"
export CONSOLE_ROOM_SESSION_SECRET="$(openssl rand -hex 32)"
export CONSOLE_ROOM_PUBLIC_URL="https://room.example.com"   # for the redirect_uri
# register  $CONSOLE_ROOM_PUBLIC_URL/auth/callback  as the redirect URI at your IdP

console-room --host 0.0.0.0 --port 443 \
  --tls-cert /etc/ssl/room.crt --tls-key /etc/ssl/room.key

uvicorn is proxy-header-aware (X-Forwarded-Proto), so you can drop --tls-* and let nginx/Caddy terminate TLS instead.

Wire protocol (NDJSON, one JSON object per line)

Console → server:

{"type":"hello",   "room":"ops", "user":"alice@web01"}
{"type":"message", "room":"ops", "text":"rolling out"}
{"type":"presence","room":"ops", "status":"available"}

The first frame must be hello — that's how a console declares its identity (the server can't see the OS user over the tunnel). The name is bound to the connection and stamped onto every later message; per-frame user fields are ignored, so a frame can't spoof a different sender.

Server → client:

{"type":"message", "room":"ops", "sender":"alice@web01", "text":"rolling out", "id":"…", "ts":0.0}
{"type":"presence","room":"ops", "user":"alice@web01", "status":"available"}

The server echoes a sender's own message back (with the assigned id/ts); a console drops its own echo so it never re-reacts to its own messages.

Browsers speak the same message / presence schema over the WebSocket — but their identity comes from the connection (the ?user=&room= query in dev, the OIDC session in S3), so they send no hello frame.

Develop

pip install -e ".[dev]"
pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

runspec_room-0.4.0.tar.gz (28.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

runspec_room-0.4.0-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

Details for the file runspec_room-0.4.0.tar.gz.

File metadata

  • Download URL: runspec_room-0.4.0.tar.gz
  • Upload date:
  • Size: 28.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for runspec_room-0.4.0.tar.gz
Algorithm Hash digest
SHA256 f879f61c46d645d3119e164ef2a65ec226e7745790d9d63c8d734ef362568275
MD5 1b4ddd7a0e5ad06ac2935bdfd0cbab37
BLAKE2b-256 0d874f8f51bf61e1648c8d65fab5436a1cb3cabcf90b8dd57aab6cf808b4f1d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for runspec_room-0.4.0.tar.gz:

Publisher: room-release.yml on JasonFinestone/runspec

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file runspec_room-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: runspec_room-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 25.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for runspec_room-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7795ff11776e6fa0133fc29dd2661a497c3d8ed64edb1303d89ea96e51ee1259
MD5 c880d968b436764c607140f6bdf66ce5
BLAKE2b-256 6e566457c0fa9420f6bfed23d6d90aa8b2aa7f2c7c5d905083b0c3ff1a1d9f74

See more details on using hashes here.

Provenance

The following attestation bundles were made for runspec_room-0.4.0-py3-none-any.whl:

Publisher: room-release.yml on JasonFinestone/runspec

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page