Mental Model
Understand Traversio's public types and how the main SSH concepts map onto the API.
Start Here
Traversio is an SSH client library for four main jobs:
- run remote commands
- hold an interactive PTY-backed shell
- transfer files with SFTP
- tunnel TCP traffic through SSH
The core ownership rule is:
SSHConnectionowns the real SSH connection- that connection can open channels
- different public wrapper types sit on top of different channel families
The 30-Second Object Graph
SSHClientConfiguration
|
v
SSHClient.connect(...) / SSHClient.withConnection(...)
|
v
SSHConnection -------------------------------------- owns the lifetime
| | | |
| | | |
| | | +--> forwarding helpers
| | | - openDirectTCPIPChannel(...)
| | | - withLocalPortForwarding(...)
| | | - withRemotePortForwardListener(...)
| | | - withRemotePortForwarding(...)
| | |
| | +--> openSFTP(...) --> SFTPClient
| |
| +--> openExec(...) --> SSHSession
|
+--> execute(...) --> SSHExecResult
\
+--> openShell(...) --> SSHSessionThe most important practical rule is:
SSHConnectionis the ownerSSHSession,SFTPClient, and forwarding wrappers are children of that connection- if the connection closes, the child wrappers stop being usable
What These Types Actually Mean
| Public type | What it means | Typical use |
|---|---|---|
SSHClientConfiguration | The target endpoint plus auth, host-trust, and transport policy | Describe how to connect |
SSHConnection | One authenticated SSH connection | Own the lifetime and open work on it |
SSHExecResult | A collected one-shot command result | Run one command and get the full output back |
SSHSession | A wrapper around an SSH session channel | Stream an exec command or drive a shell |
SFTPClient | A wrapper over a session channel with the sftp subsystem | File operations |
SSHDirectTCPIPChannel | A wrapper around a direct-tcpip channel | One raw forwarded TCP stream you speak yourself |
SSHForwardedTCPIPChannel | A wrapper around an accepted forwarded-tcpip channel | Handle one incoming remote-forward connection |
SSHRemotePortForwardListener | A closure-scoped remote listener which yields SSHForwardedTCPIPChannel values | Accept remote-forwarded connections yourself |
Connection, Session, And Channel
If you know OpenSSH terms, Traversio maps onto them like this:
one TCP connection
-> one SSH connection
-> many SSH channels over time
-> "session" channels for shell / exec / subsystem
-> "direct-tcpip" channels for client-initiated TCP forwarding
-> "forwarded-tcpip" channels for accepted remote-forward trafficThese terms describe different layers:
SSHConnectionis the whole authenticated SSH connection.- A channel is one logical conversation running inside that connection.
SSHSessionis the public wrapper for one SSHsessionchannel.SFTPClientis one SFTP subsystem running on onesessionchannel.
This rule matters when you combine features:
- one
SSHConnectioncan carry multiple channels at once - one
sessionchannel can only become one of: shell, exec, or subsystem - if you want many exec commands plus a shell plus SFTP, keep one connection and open separate channels for each job
For a concrete monitoring-oriented example, see Sharing One Connection.
This is why execute(_:) and openExec(_:) both exist:
execute(_:)opens an exec-capablesessionchannel internally, collects everything, and returnsSSHExecResultopenExec(_:)gives you the long-livedSSHSessionwrapper for that same channel family
Shell and streamed exec also share SSHSession:
- both are built on SSH
sessionchannels - shell adds PTY and shell requests
- streamed exec sends an exec request instead
Which API Should You Reach For?
| If you need... | Use this | Why |
|---|---|---|
| one command and one collected result | SSHConnection.execute(_:) | Smallest and simplest path |
| one command with streaming stdout/stderr or stdin writes | SSHConnection.openExec(_:) | Gives you SSHSession.events, write, and sendEOF |
| an interactive terminal | SSHConnection.openShell(...) | Opens a PTY-backed shell as SSHSession |
| to resize that PTY later | SSHSession.resizePseudoTerminal(...) | Sends SSH window-change |
| file reads, writes, metadata, and directory work | SSHConnection.openSFTP(...) | Starts an SFTP client |
| one raw TCP stream through SSH | SSHConnection.openDirectTCPIPChannel(...) | Expert forwarding API |
| a temporary local listener that forwards through SSH | SSHConnection.withLocalPortForwarding(...) | Higher-level closure-scoped helper |
| a temporary local SOCKS proxy that chooses the target per connection | SSHConnection.withDynamicPortForwarding(...) | Higher-level closure-scoped helper |
| a temporary remote listener that you accept from manually | SSHConnection.withRemotePortForwardListener(...) | Yields raw incoming forwarded channels |
| a temporary remote listener bridged back to one local TCP service | SSHConnection.withRemotePortForwarding(...) | Higher-level closure-scoped helper |
Supported Areas
This is the short version of the supported feature set:
- password auth, keyboard-interactive auth, and Ed25519, RSA, and ECDSA public-key auth
- host-key trust through pinning or OpenSSH
known_hosts - optional RFC 4253
zlibor delayed OpenSSH[email protected]compression and automatic local rekey policy - one-shot exec and streamed exec
- PTY-backed interactive shells
- SFTP metadata, listing, reads, writes, rename, remove, mkdir/rmdir, symlink, and readlink
- raw
direct-tcpipforwarding - local, remote, and dynamic forwarding helpers
- outer connection proxies and explicit ProxyJump hop chains
Known limits:
- agent-backed auth and broader credential-loading options
- a finalized cancellation and forwarding-lifecycle contract
- broader interoperability and production hardening
For the fuller matrix, read Implemented Features.
The Lifetime Rule You Need To Know
Traversio's current API is deliberately connection-owned.
SSHConnection closes
-> SSHSession becomes invalid
-> SFTPClient becomes invalid
-> forwarding wrappers become invalidThis applies in both common ownership styles:
- you call
await connection.close()yourself, or - you used
SSHClient.withConnection(...)and the closure already ended
The usual pattern is:
- open one
SSHConnection - open the child wrapper you need
- do the work
- close the connection, or let
withConnection(...)do it
Suggested Reading Order
If you are new to Traversio, this order works well:
- this page for the object model
- Quickstart for the first connection
- Running Commands or Interactive Shell for session usage
- SFTP or Forwarding for the bigger feature areas
- Public API for the type-by-type reference
- Architecture if you want the implementation layers and package boundaries