Skip to content

Transports And Remote Access

RoyalTerminal does not treat a terminal session as "always a local PTY". The public transport surface is broader than that on purpose: local shells, child processes, SSH, raw TCP, Telnet, and serial all fit into the same session model.

One session model, several transport families

Every transport starts from ITerminalTransportOptions and a stable TransportId. That shared boundary is what lets TerminalControl, TerminalSessionService, settings UI, and profile persistence all work across very different backends.

TransportOptions typeTypical use
Local PTYPtyTransportOptionsInteractive shell with ConPTY or forkpty
Child process pipePipeTransportOptionsOutput capture, automation, or non-interactive process IO
SSHSshTransportOptionsRemote shell sessions and tunneling
Raw TCPRawTcpTransportOptionsPlain byte streams
TelnetTelnetTransportOptionsLegacy text terminals with negotiation
SerialSerialTransportOptionsDevices, consoles, and embedded targets

The common runtime boundary

The transport layer is deliberately small and composable:

TypeWhy it matters
ITerminalTransportOptionsShared startup contract for all transports.
TerminalSessionDimensionsShared logical and pixel dimensions.
ITerminalTransportRunning transport abstraction.
ITerminalPtyTransportOptional capability for transports backed by a PTY.
ITerminalTransportProviderFactory participant for one transport family.
ITerminalTransportFactoryFactory used by hosts and session services.
CompositeTerminalTransportFactoryMulti-provider selector used throughout the repo.
TerminalTransportIdsShared string ids for all standard transports.
TerminalCommandSpecExecutable path plus argument list.

The pattern is simple: build the options record, pass it to a factory, and let the session service wire the result to the active VT processor.

Local process and PTY sessions

Local shells use the PTY path because that is what full-screen TUIs and interactive shells expect. Pipe mode exists for simpler process IO scenarios that do not want a pseudo-terminal.

PTY-facing contracts and implementations

TypePurpose
IPtyMinimal pseudo-terminal abstraction.
IPtyFactoryFactory for creating PTYs.
DefaultPtyFactoryPlatform-selecting PTY factory.
UnixPtyUnix forkpty implementation.
WindowsPtyWindows ConPTY implementation.
PtyTerminalTransportPTY-backed transport runtime.
PtyTerminalTransportProviderProvider for PTY sessions.
PtyTransportOptionsPTY startup options.

Pipe process sessions

TypePurpose
PipeTerminalTransportChild-process pipe transport.
PipeTerminalTransportProviderProvider for pipe sessions.
PipeTransportOptionsPipe process options, including stderr merge behavior.

Network and device transports

These transports all stay intentionally small. They are useful because they let the rest of the stack remain transport-agnostic.

TypePurpose
RawTcpTerminalTransportPlain TCP transport runtime.
RawTcpTerminalTransportProviderProvider for raw TCP sessions.
RawTcpTransportOptionsHost and port for raw TCP sessions.
TelnetTerminalTransportTelnet transport runtime.
TelnetTerminalTransportProviderProvider for Telnet sessions.
TelnetTransportOptionsTelnet host, port, terminal type, and optional startup command.
SerialTerminalTransportSerial line transport runtime.
SerialTerminalTransportProviderProvider for serial sessions.
TerminalSerialParitySerial parity enum.
TerminalSerialStopBitsSerial stop-bit enum.
TerminalSerialHandshakeSerial handshake enum.
SerialTransportOptionsSerial port name, baud rate, data bits, parity, stop bits, handshake, and newline settings.

SSH as a first-class remote session

SSH is the richest transport in the library because it has to cover trust, credentials, PTY requests, terminal type, environment bootstrap, proxies, forwarding, and operational policy.

Runtime SSH option model

TypePurpose
SshEndpointOptionsHost, port, and username.
SshAuthenticationOptionsRuntime auth choices: password, keys, and agent usage.
SshProxyTypeProxy type enum.
SshProxyOptionsProxy connection settings.
SshPortForwardModeLocal, remote, or dynamic forwarding mode.
SshPortForwardOptionsOne forwarding rule.
SshX11OptionsX11 forwarding settings.
SshPolicyOptionsKeepalive and connect timeout settings.
SshTransportOptionsFull SSH startup options including endpoint, auth, environment, proxy, forwarding, X11, and host-key pinning.

Host-key trust policy

RoyalTerminal keeps host-key validation pluggable instead of burying it inside the SSH transport:

TypePurpose
SshHostKeyInfoHost-key metadata passed into validators.
ISshHostKeyValidatorTrust-policy contract.
KnownHostsSshHostKeyValidatorOpenSSH known_hosts validator.
ExpectedFingerprintSshHostKeyValidatorStrict fingerprint pinning validator.
RejectAllSshHostKeyValidatorExplicit deny-all validator.

SSH.NET integration

The default SSH runtime is built on SSH.NET, but the auth method list is still extensible:

TypePurpose
ISshNetAuthenticationMethodContributorAdds auth methods to the SSH.NET runtime.
NullSshCredentialProviderNo-op credential provider for externally managed auth.
SshNetTerminalTransportSSH.NET transport runtime.
SshNetTerminalTransportProviderProvider for SshTransportOptions.
SshNetAgentAuthenticationMethodContributorAgent-backed auth contributor package.

Secret storage and credential resolution

RoyalTerminal separates credential lookup, secret persistence, and secret protection. That makes the SSH transport easier to host in real applications with policy constraints.

Secret and credential contracts

TypePurpose
SshCredentialRequestRequest for credentials.
SshResolvedCredentialsResolved credential payload.
ISshCredentialProviderAsync credential source contract.
ISshSecretStoreSecret persistence contract.
ISshSecretProtectorSecret protector contract.

Built-in secret stores and protectors

TypePurpose
InMemorySshSecretStoreIn-memory store for tests or short-lived sessions.
EnvironmentVariableSshSecretStoreEnvironment-variable backed store.
JsonFileSshSecretStorePlain JSON file store.
ProtectedJsonFileSshSecretStoreJSON file store protected by an ISshSecretProtector.
CompositeSshSecretStoreMulti-store lookup chain.
SecretStoreSshCredentialProviderCredential provider backed by a secret store.
NoOpSshSecretProtectorPass-through protector.
DpapiSshSecretScopeWindows DPAPI scope enum.
DpapiSshSecretProtectorWindows DPAPI protector.
AesGcmSshSecretProtectorCross-platform AES-GCM file-key protector.
SshSecretProtectionFactoryFactory for default protectors and stores.
SshShellBootstrapCommandBuilderSafe bootstrap command builder for environment variables and startup commands.

How the articles map to the code

The runtime transport implementations live in the transport packages, but the durable document model for configuring them lives in Sessions, Profiles, And Settings. That separation is deliberate:

  • this article is about starting and running sessions
  • the session/profile article is about saving and editing them

That is the same split Ghostty uses between conceptual feature pages and lower-level reference material.

MIT Licensed