Traversio

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:

  • SSHConnection owns 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(...) --> SSHSession

The most important practical rule is:

  • SSHConnection is the owner
  • SSHSession, 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 typeWhat it meansTypical use
SSHClientConfigurationThe target endpoint plus auth, host-trust, and transport policyDescribe how to connect
SSHConnectionOne authenticated SSH connectionOwn the lifetime and open work on it
SSHExecResultA collected one-shot command resultRun one command and get the full output back
SSHSessionA wrapper around an SSH session channelStream an exec command or drive a shell
SFTPClientA wrapper over a session channel with the sftp subsystemFile operations
SSHDirectTCPIPChannelA wrapper around a direct-tcpip channelOne raw forwarded TCP stream you speak yourself
SSHForwardedTCPIPChannelA wrapper around an accepted forwarded-tcpip channelHandle one incoming remote-forward connection
SSHRemotePortForwardListenerA closure-scoped remote listener which yields SSHForwardedTCPIPChannel valuesAccept 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 traffic

These terms describe different layers:

  • SSHConnection is the whole authenticated SSH connection.
  • A channel is one logical conversation running inside that connection.
  • SSHSession is the public wrapper for one SSH session channel.
  • SFTPClient is one SFTP subsystem running on one session channel.

This rule matters when you combine features:

  • one SSHConnection can carry multiple channels at once
  • one session channel 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-capable session channel internally, collects everything, and returns SSHExecResult
  • openExec(_:) gives you the long-lived SSHSession wrapper for that same channel family

Shell and streamed exec also share SSHSession:

  • both are built on SSH session channels
  • shell adds PTY and shell requests
  • streamed exec sends an exec request instead

Which API Should You Reach For?

If you need...Use thisWhy
one command and one collected resultSSHConnection.execute(_:)Smallest and simplest path
one command with streaming stdout/stderr or stdin writesSSHConnection.openExec(_:)Gives you SSHSession.events, write, and sendEOF
an interactive terminalSSHConnection.openShell(...)Opens a PTY-backed shell as SSHSession
to resize that PTY laterSSHSession.resizePseudoTerminal(...)Sends SSH window-change
file reads, writes, metadata, and directory workSSHConnection.openSFTP(...)Starts an SFTP client
one raw TCP stream through SSHSSHConnection.openDirectTCPIPChannel(...)Expert forwarding API
a temporary local listener that forwards through SSHSSHConnection.withLocalPortForwarding(...)Higher-level closure-scoped helper
a temporary local SOCKS proxy that chooses the target per connectionSSHConnection.withDynamicPortForwarding(...)Higher-level closure-scoped helper
a temporary remote listener that you accept from manuallySSHConnection.withRemotePortForwardListener(...)Yields raw incoming forwarded channels
a temporary remote listener bridged back to one local TCP serviceSSHConnection.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 zlib or 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-tcpip forwarding
  • 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 invalid

This 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:

  1. open one SSHConnection
  2. open the child wrapper you need
  3. do the work
  4. close the connection, or let withConnection(...) do it

Suggested Reading Order

If you are new to Traversio, this order works well:

  1. this page for the object model
  2. Quickstart for the first connection
  3. Running Commands or Interactive Shell for session usage
  4. SFTP or Forwarding for the bigger feature areas
  5. Public API for the type-by-type reference
  6. Architecture if you want the implementation layers and package boundaries

On this page