A minimal, self-contained pair of Go binaries to record SSH sessions and
watch them live or replay them later. No server-side component: everything
runs on your local box, under ~/.ssh-watch/.
ssh-cast— drop-in wrapper aroundsshthat records the session.ssh-watch— lists recorded sessions and attaches to a live one or replays it.
Why
We started giving AI coding agents direct SSH access to real machines — staging boxes, build servers, sometimes production. That's useful, but an agent driving a shell is not the same as a human driving one: it can run for a long time unattended, it can go off-script, and when something goes wrong there's no one at the keyboard who watched it happen.
ssh-cast exists so that every agent-initiated SSH session leaves a
recording, and so a human can tail it live instead of finding out after the
fact. Point an agent's ssh calls at ssh-cast instead, and you get:
- Live observability —
ssh-watchcan attach to a running session and watch the agent's terminal output in real time, the same way you'd watch atmuxpane over someone's shoulder. - An audit trail — every session is saved as a standard asciinema v2
.castfile, so you can replay exactly what an agent typed and saw, after the fact, at normal speed or fast-forwarded. - No behavior change for the agent — it's a thin wrapper around the real
sshbinary running under a pty, so keys,ssh_config, andknown_hostsall behave exactly as they would if the agent calledsshdirectly. The agent doesn't need to know it's being recorded.
This is intentionally narrow: it captures the PTY byte stream, not
structured commands, and it only sees sessions actually launched through it
(an agent using its own SSH library instead of the ssh binary bypasses it
entirely — see Design constraints). It's an
observability tool, not a sandbox or a security boundary.
Build
Requires Go 1.21+. Dependencies are vendored, so builds don't need network access.
go build -o bin/ssh-cast ./cmd/ssh-cast go build -o bin/ssh-watch ./cmd/ssh-watch
Packaging (.deb)
make build # cross-compiles both binaries for GOOS=linux (ARCH=amd64 by default) make deb # build + package into dist/ssh-cast_<version>_<arch>.deb make deb ARCH=arm64 # override target arch make clean
Makefile builds always target GOOS=linux, since both binaries only make
sense on a system with /usr/bin/ssh. Requires dpkg-deb on the build host
(Debian/Ubuntu, or a container/CI image with dpkg-dev) — not available for
local iteration on a non-Linux dev box. If you're on Windows, run it from a
Linux environment (WSL, a container) rather than a Windows-mounted path;
dpkg-deb rejects the permission bits that DrvFs mounts report.
Usage
Recording a session
Use ssh-cast exactly like ssh — same arguments, same behavior:
ssh-cast user@host
ssh-cast user@host "uptime"Point an agent's SSH invocations at ssh-cast (e.g. alias ssh to it, or
configure the agent's SSH command) and every session it opens gets recorded
automatically.
Watching and replaying
ssh-watch # list sessions (● marks ones currently live) ssh-watch <session> # attach live if running, else replay the recording ssh-watch -r <session> # force replay with original timing ssh-watch -R <session> # replay as fast as possible, no timing waits
On disk
Each ssh-cast invocation creates ~/.ssh-watch/<timestamp>-<pid>/:
meta.json— target host/user, start/end time, pid, and whether the session is still live.session.cast— the recording, in asciinema v2 format.live.sock— a local unix socket, present only while the session runs.
Nothing here is network-exposed; the live socket is unix-domain and local-only by design.
Design constraints
- Wraps the
sshbinary, not a library — it only sees sessions launched through it. Not a security control. - Captures the raw PTY stream only; no command-level parsing or structured events yet.
- No webhook/notification hooks yet (planned, not implemented).