Implemented Features
A concrete feature matrix for the Traversio library.
Overview
The table below summarizes the current Traversio feature surface.
| Area | Supported | Deferred / Missing |
|---|---|---|
| Transport and wire | Identification exchange, binary framing, encrypted packets for aes128-ctr / aes256-ctr with HMAC-SHA-2 and OpenSSH ETM or UMAC MACs, OpenSSH [email protected] / [email protected], OpenSSH [email protected], RFC 4253 zlib plus OpenSSH delayed [email protected] compression when explicitly requested, OpenSSH strict-kex sequencing and NEWKEYS sequence-number reset handling, packet-threshold and idle-time automatic local rekey, post-auth idle keepalive, parser state across partial reads, Apple 26+ TCP transport | Broader algorithm matrix, reconnect policy, hardened long-session validation |
| Key exchange and auth | SSH_MSG_KEXINIT, curve25519-sha256, [email protected], ecdh-sha2-nistp256, Ed25519/RSA SHA-2/ECDSA host-key verification, explicit opt-in legacy ssh-rsa host-key and RSA auth compatibility through SSHLegacyAlgorithmOptions, Ed25519 and ECDSA P-256 OpenSSH host-certificate verification, password auth, keyboard-interactive callbacks, Ed25519/RSA/ECDSA public-key auth, OpenSSH Ed25519/ECDSA/RSA key-file loading with optional bcrypt + AES passphrase decryption, and OpenSSH key-pair generation for the same public-key algorithms | Broader host-key coverage and agent-backed auth |
| Host trust | Explicit trust policy, exact raw-key pinning, trusted key sets, first-seen and changed-key helpers with caller-owned persistence, async trust callbacks, and OpenSSH known_hosts loading for exact, wildcard, negated, hashed, CIDR, @revoked, and @cert-authority entries, including optional host/IP-aware lookup names | Built-in trust-store persistence, broader host-certificate algorithm coverage beyond today's Ed25519 and ECDSA P-256 paths |
| Exec and shell | Session-channel open, pre-start SSH env requests, exec, PTY plus shell startup, explicit connection ownership, explicit shell close, write support, PTY resize through SSH window-change, signal delivery through SSH signal, remote exit-signal event exposure, shell and streamed-exec event delivery through nextEvent() and events, transcript collection plus events iteration with best-effort channel-close on cancellation, receive-window replenishment, remote-window-aware chunked writes, and concurrent session-channel use on one connection | Broader cancellation semantics and a broader terminal-control surface |
| SFTP | Version exchange, metadata, concurrent request-id-routed path and handle operations, path and handle attribute mutation, path and handle filesystem queries, public file handles, directory listing, file reads including bounded concurrent whole-file reads on one handle plus cumulative progress callbacks, whole-file writes with optional bounded concurrent request windows, resumable whole-file uploads from the current remote size, cumulative progress callbacks, and optional fsync, rename, remove, mkdir/rmdir, symlink, readlink, extension-aware [email protected] use | Broader resumable transfer coverage, deeper transfer-engine tuning, broader extension coverage, hardened recovery |
| Forwarding | Typed TCP/IP forwarding coders, a public raw direct-tcpip channel wrapper, a public forwarding event stream through nextEvent() / events, best-effort channel-close on events-iterator cancellation for raw TCP/IP channel wrappers, an Apple 26+ local-forwarding helper, an Apple 26+ local dynamic SOCKS helper, an Apple 26+ raw remote-forward listener, an Apple 26+ remote-forwarding bridge helper, outermost-hop SOCKS5 / HTTP CONNECT transport proxies through SSHClientConfiguration.connectionProxy, explicit proxyJumpHosts hop chaining in SSHClientConfiguration, live OpenSSH forwarding validation for raw, local, dynamic, remote-bridge data paths plus ProxyJump, and a local Docker proxy matrix for connectionProxy validation | Finalized shutdown/lifecycle semantics, broader interoperability coverage, and any broader routing or mailbox/dispatcher layer beyond the current helper model |
| Diagnostics and logging | Stable SSHClientError wrappers for connection and post-auth failures, negotiated transport snapshots including effective integrity reporting, remote disconnect/debug context, structured SSHClientLogHandler sinks, a built-in bounded SSHClientLogRecorder export helper, OSLog helpers for the public connection entry points, explicit setup/reply timeout mapping including keepalive timeout failures, and direct SSH-port latency measurement through SSHClient.measurePortLatency(host:port:options:) | Broader long-running retention/redaction guidance, proxy-aware latency utilities, and any later stability guarantees for additional diagnostic detail |
Authentication
Supported:
- password authentication through
.password(String) - generic keyboard-interactive authentication through
.keyboardInteractive(submethods:responseProvider:) - Ed25519, RSA, and ECDSA public-key authentication through:
.ed25519PrivateKey(rawRepresentation: [UInt8]),.rsaPrivateKey(pkcs1DERRepresentation: [UInt8]),.ecdsaP256PrivateKey(rawRepresentation: [UInt8]),.ecdsaP384PrivateKey(rawRepresentation: [UInt8]),.ecdsaP521PrivateKey(rawRepresentation: [UInt8]),try .ed25519PrivateKey(openSSHPrivateKey: String),try .ed25519PrivateKey(contentsOfOpenSSHPrivateKeyFile: String),try .rsaPrivateKey(openSSHPrivateKey: String),try .rsaPrivateKey(contentsOfOpenSSHPrivateKeyFile: String),try .ecdsaPrivateKey(openSSHPrivateKey: String),try .ecdsaPrivateKey(contentsOfOpenSSHPrivateKeyFile: String), andtry SSHOpenSSHKeyPair.generate(...)with Ed25519, ECDSA P-256/P-384/P-521, or RSA - explicit per-connection and per-hop legacy RSA compatibility through
SSHLegacyAlgorithmOptions.sshRSA, which appendsssh-rsahost-key negotiation and lets RSA auth retry the SHA-1 path when an older server still offerspublickey
Deferred:
- SSH agent support
- keychain-backed credential loading or other product-owned credential stores
Transport profile:
- KEX means
curve25519-sha256,[email protected], andecdh-sha2-nistp256 - packet protection includes:
aes128-ctr/aes256-ctrwithhmac-sha2-256,hmac-sha2-512,[email protected],[email protected],[email protected],[email protected],[email protected], and[email protected], plus OpenSSH[email protected]and[email protected], plus OpenSSH[email protected] - the client now advertises OpenSSH
[email protected]and enforces the initial strict-kex ordering andNEWKEYSsequence-reset rules when the peer offers the matching server marker - compression includes
none, RFC 4253zlib, and delayed OpenSSH[email protected] - both RFC 4253
zliband delayed OpenSSH zlib are opt-in throughSSHClientConfiguration.compressionPreferenceor the matching per-hopSSHProxyJumpHost.compressionPreference
Transport Algorithm Snapshot
This is the transport algorithm table for the documented implementation:
| Category | Implemented | Notes |
|---|---|---|
KexAlgorithms | curve25519-sha256, [email protected], ecdh-sha2-nistp256 | The initial proposal also advertises ext-info-c and [email protected], but those are OpenSSH/extension markers rather than real key-exchange methods. Rekey proposals omit those markers. |
Ciphers | aes128-ctr, aes256-ctr, [email protected], [email protected], [email protected] | AES-CTR uses a separate MAC. OpenSSH AES-GCM and Chacha20-Poly1305 are AEAD paths. |
MACs | [email protected], [email protected], [email protected], [email protected], hmac-sha2-256, hmac-sha2-512, [email protected], [email protected] | MAC negotiation matters only on the AES-CTR path. OpenSSH AES-GCM and Chacha20-Poly1305 do not use a separate negotiated MAC. |
Compression | none, zlib, [email protected] | RFC 4253 zlib activates once encrypted transport is active after each key exchange. OpenSSH [email protected] waits until user authentication has completed. |
Host Trust
Supported:
- trust-any for disposable test environments and controlled tooling
- exact single-key pinning
- exact trusted key sets
- trust-on-first-use helper with caller-owned load/store closures and compare-and-set store context
- optional changed-key resolution through
trustOnFirstUse(..., onStoredHostKeyMismatch: ...) - async callback-based trust evaluation under upper-layer control
known_hostsimport from a file path for exact, wildcard, negated, hashed, CIDR,@revoked, and@cert-authorityentries, with optional additional lookup names for host/IP-aware matching
Deferred:
- built-in trust-store persistence
- broader host-certificate algorithm coverage beyond the current Ed25519 and ECDSA P-256 certificate paths
Shell And Exec
Live validation:
- command execution against OpenSSH
- concurrent exec on one OpenSSH connection
- monitoring-shaped concurrent exec batches on one OpenSSH connection
- PTY-backed shell startup against OpenSSH
- one shared OpenSSH connection carrying shell, exec, and SFTP at the same time
- one shared OpenSSH connection carrying shell, SFTP, and monitoring exec batches at the same time
- interleaved control traffic such as early
CHANNEL_WINDOW_ADJUST - receive-window replenishment and outbound chunking
Practical limits:
- the shell wrapper is intentionally small
- the newer incremental surfaces are
SSHConnection.openExec(_:)plus the unifiedSSHSessionevent stream execute(_:environment:),openExec(_:environment:), andopenShell(..., environment:)now send pre-start RFC 4254envrequests when you provideSSHSessionEnvironmentVariablevaluesSSHSession.resizePseudoTerminal(...)andSSHSession.sendSignal(_:)now exist for PTY-backed shells and streamed exec sessions, and Traversio now also exposes remoteexit-signalevents throughSSHSessionEventplus collected outputs- one
SSHSessionmaps to one SSHsessionchannel, so one channel is dedicated to one purpose - the older chunked reader covers stdout only
- wrapper lifetime follows the owning
SSHConnection
SFTP
Supported public methods:
closerealPathlstatstatsetAttributesfileSystemAttributesopenFilelistDirectoryreadFilewriteFilemakeDirectoryremoveFileremoveDirectoryrenamereadLinkcreateSymbolicLink
Behavior notes:
- one
SFTPClientroutes replies by request ID, so path and handle calls can overlap on the same subsystem channel openFilereturns a publicSFTPFileHandle, and that handle shares the same request router and channel window as the parentSFTPClientreadFile(..., maxConcurrentReads:progress:),writeFile(..., maxConcurrentWrites:progress:), andSFTPFileHandle.readAll(...)can keep a bounded number of SFTP requests in flight on one handle while preserving whole-file convenience APIsSFTPFileHandle.readChunks(...)now exposes handle-level streamed reads as anAsyncSequence, andSFTPFileHandle.write(contentsOf:startingAt:progress:)now consumes caller-provided chunk streams for offset-based uploadsresumeUploadFile(...)andresumeDownloadFile(...)now resume whole-file transfers from the server-reported remote file size and throw focused public errors when the caller's local and remote sizes are incompatible or the server omits size metadata- those same whole-file helpers now also emit cumulative
SSHSFTPTransferProgressvalues during transfer work writeFiletruncates existing content by defaultwriteFile(syncAfterWrite: true)requires OpenSSH[email protected]support- rename prefers the OpenSSH extension when advertised
Forwarding
Supported public surface:
SSHConnection.openDirectTCPIPChannel(...)for expert raw byte streams over adirect-tcpipchannelSSHConnection.withLocalPortForwarding(...)on Apple 26+ for a closure-scoped local listener backed by the same channel pathSSHConnection.withDynamicPortForwarding(...)on Apple 26+ for a closure-scoped local SOCKS proxy which opensdirect-tcpipchannels on demandSSHConnection.withRemotePortForwardListener(...)on Apple 26+ for a closure-scoped remote listener plus raw incomingforwarded-tcpipchannelsSSHConnection.withRemotePortForwarding(...)on Apple 26+ for a closure-scoped remote listener that bridges back to one local TCP endpointSSHClientConfiguration.connectionProxyfor an outermost-hop SOCKS5 or HTTP CONNECT transport proxy before the first SSH handshake startsSSHClientConfiguration.proxyJumpHostsplusSSHProxyJumpHostfor explicit multi-hop jump-host chainingSSHDirectTCPIPChannel.nextEvent()/eventsandSSHForwardedTCPIPChannel.nextEvent()/eventsfor incremental data plus EOF delivery without giving up the older chunk/transcript helpers
Limits:
- the Apple 26+ local-forwarding helper uses a best-effort shutdown model: Traversio stops bridging data at scope exit and closes late accepted local connections, but does not promise that the bound port becomes immediately unconnectable
- accepted local-forward, dynamic-forward, and fixed remote-forward bridge failures are now isolated per connection instead of poisoning the whole forwarding scope
- the remote-forward listener and helper are closure-scoped helpers
- live validation covers the raw-listener and fixed remote-bridge data paths against OpenSSH
- the remote-forwarding helper keeps multiple accepted remote connections active and bridges them back to one fixed local TCP endpoint
- dynamic forwarding is live-validated on the SOCKS5 path in both no-auth and username/password modes, while SOCKS4 and SOCKS4a keep deterministic-only coverage
- ProxyJump has real OpenSSH live validation, and outer SOCKS5 / HTTP CONNECT connection proxies also have local Docker live-validation coverage
- broader forwarding validation beyond OpenSSH-family servers and the local proxy matrix remains release work
Validation Snapshot
Already live-validated against the configured OpenSSH target:
- shell and exec
- baseline
exec trueagainst the local Ubuntu 24 OpenSSH 9.6p1 matrix target after enabling the client strict-kex marker exec trueagainst the local Ubuntu 24 OpenSSH 9.6p1 AEAD-only matrix targetexec trueagainst the local Ubuntu 24 OpenSSH 9.6p1 ETM-only matrix targetexec trueagainst the local Ubuntu 24 OpenSSH 9.6p1 UMAC-only matrix targetexec trueagainst the local Ubuntu 24 OpenSSH 9.6p1 Chacha20-Poly1305-only matrix target- concurrent exec on one connection
- monitoring exec batches on one connection
- one shared connection carrying shell, exec, and SFTP
- one shared connection carrying shell, SFTP, and monitoring exec batches
- SFTP metadata
- directory listing
- file reads
- sequential writes
- rename, including
[email protected] - symlink and readlink
- password-authenticated authorized-key installation plus public-key re-login
- ECDSA public-key auth
- forwarding raw-listener, fixed local forwarding, dynamic SOCKS forwarding on the SOCKS5 path, and fixed-endpoint remote-bridge data paths
- outer SOCKS5 / HTTP CONNECT connection proxies, including SOCKS5 username/password and HTTP CONNECT Basic auth, through the local Dante/Tinyproxy matrix
- ProxyJump / explicit jump-host chaining
- keyboard-interactive auth against a temporary local AsyncSSH server
Not yet live-validated:
- SOCKS4 and SOCKS4a dynamic-forwarding paths
- non-Docker / enterprise-style outer connection proxies for the SSH transport itself