Skip to content

SSH session-recording transport (CastV2 stream to recorders) — tsr-0h2 follow-up #28

@GeiserX

Description

@GeiserX

Context

v0.7.3 (#25) closed the SSH recording-policy bypass by carrying recorders/on_recording_failure into the domain SshAction and fail-closing (refusing) a session when a matched rule requires recording but no recorder transport exists. This is the faithful interim for a turnkey server with no recorder.

Ask (the deferred half)

Implement the actual recorder transport so a record-required session can proceed while being recorded (relaxing the interim fail-closed to Go's true default). Mirror Go tailscale.com/ssh/tailssh:

  1. Dial the recorders (tailnet ip:port) — the connect path (sessionrecording/connect.go: V1 /record vs V2 with the ack frame).
  2. Stream the PTY session in asciinema CastV2 format — the cast header (sessionrecording/header.go) + [t, "o", data] body frames, tee'd from the PTY I/O (src/ssh/shell.rs PTY read/write).
  3. On recorder-connect failure, apply on_recording_failure: Go default is fail-open (proceed unrecorded) UNLESS reject_session_with_message is set (fail-closed). Once this transport exists, replace the interim "always fail-closed when recording required" with that exact Go semantics.

Greenfield I/O (a self-contained sub-protocol). Behind the ssh cargo feature.

Also deferred from #25

hold_and_delegate (check-mode): currently the field is carried but a rule bearing it is not silently accepted. Implementing the delegate round-trip needs a live control channel (Noise DoNoiseRequest-equivalent) the turnkey server may not have — verify and design before building.

Created using Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions