DSH / Atlas
2026-09-11implementedarchitecture

POSIX SSH execution providers

POSIX SSH 执行提供方

Remote coding requires file tools, Bash, terminals, language servers and Node programs to see one filesystem and process world. The [portable-consumer decision](2026-07-28-portable-execution-world-consumers.md) provides those interfaces. The [E2B retirement](../simplification/2026-09-11-remove-e2b-providers.md) preserves their asynchronous semantics while removing an integration whose standard-stream SDK needs a sepa

English

Problem

Remote coding requires file tools, Bash, terminals, language servers and Node programs to see one filesystem and process world. The portable-consumer decision provides those interfaces. The E2B retirement preserves their asynchronous semantics while removing an integration whose standard-stream SDK needs a separate transport project to carry bidirectional PTC control traffic.

SSH supplies authenticated byte channels and per-channel flow control, but an ordinary exec request does not map arbitrary child descriptors. Treating SSH as a replacement for a process owner would leave control-stream bridging, launch publication, EOF, cancellation and disconnected cleanup without an implementation.

Decision

A deployment-owned OpenSSH alias connects the local Harness to an installed POSIX helper. Filesystem, subprocess and sandbox providers share that helper; the Harness retains Cordis objects, model transport, permissions, callbacks and Session persistence. Terminal methods remain asynchronous. Provider paths describe the execution world without a separate local/remote flag.

Confinement is asynchronous and cancellable: the running helper resolves each policy through its loaded sandbox provider before the subprocess provider receives literal argv. ShellExecutor.start() resolves a Promise<ShellProcess> after preparation. Generic job admission remains synchronous; tool-owned JobHooks begin asynchronous shell preparation after preflight, cancel pending preparation and join any late process handle.

Private administrative RPC and each program stream use independent SSH channels. A remote reservation creates the requested stream endpoints before the payload starts. Stdout and stderr cannot carry administrative replies, and pausing one output channel does not consume fd 7’s flow-control window. This trades a larger remote helper for explicit binary transport and bounded stream retention.

Each stream receives a fresh 256-bit TLS pre-shared key through private administrative RPC. TLS 1.2 with PSK-AES256-GCM-SHA384 authenticates both endpoints and protects subsequent bytes before the stream can publish. The key never travels as a stream preface. Socket permissions alone are insufficient: file-effect confinement can permit same-user connections or pathname replacement in writable temporary directories. No administrative Unix listener or stream secret is exposed to the payload. Cancellation transfers to the TLS wrapper after wrapping; cleanup closes that wrapper before the underlying socket so native TLS reads cannot outlive their transport.

Collected stdout and stderr carry bounded tail snapshots through handlers that only update output observations. Capture continues while a snapshot is waiting for transport. Final snapshots preserve raw-byte offsets, and completed spill files use the local provider’s retained-output storage after connection disposal.

Readiness verifies the installed helper script or executable digest and, when a script deployment supplies a PTC bootstrap, that bootstrap's digest. Executable deployments embed the PTC worker and require no separate bootstrap. These checks pin expected deployment artifacts; they do not authenticate a malicious remote operating system. The helper disables Node debugger activation through SIGUSR1: file-effect confinement can still permit same-user signals, which must not expose the helper's unrestricted filesystem and process services. File-effect confinement delegates to the remote local sandbox provider and retains its full/partial disclosure and platform limitations.

Path canonicalization belongs where the files exist. The shared policy resolver preserves absolute execution-world spelling; enforcing providers resolve symlinks and .. on their own filesystem. Headless records and validates cwd through ctx.fs. Host-path projection remains unavailable for SSH; PTC uses an explicitly installed remote bootstrap for script deployments or the helper executable's embedded worker.

A lost connection invalidates pending operations without reconnect or replay. Helper EOF, signals and a heartbeat lease initiate remote native cleanup. The client cannot turn lease expiry into an observed successful termination: an interrupted mutation or launch can have an unknown outcome. Administrative request deadlines, consumer execution deadlines and cleanup remain separate owners.

Helper deployment

The explicit launch.kind selects remote node-script or executable invocation independently of the local Harness carrier. A local process.pkg flag cannot describe the remote installation. Protocol 2 includes the remote runtime kind in its readiness response and rejects protocol or launch-kind mismatches, so a client cannot apply script bootstrap rules to an embedded worker. Client and helper protocol upgrades must be deployed together.

The executable embeds Node, the helper, managed subprocess runners and the PTC worker. It reuses the SDK executable packaging decision: pkg --sea preserves a package tree and dynamic module resolution instead of maintaining a separate static plugin registry. That record owns the comparison with bare Node SEA. The embedded runtime serves these private entry points; project commands still depend on the remote machine's development tools.

The four release targets cover Linux and macOS on x64 and arm64, matching the POSIX providers and their supported native resources. Packaging does not add Windows or musl support. Landlock and macOS PTY launchers remain real files beside the executable because the operating system cannot execute paths inside pkg's virtual filesystem. The installation unit is therefore the complete archive directory, with native resources and integrity metadata, rather than the executable alone. The helper runtime reference owns the build matrix, deployment baselines and archive verification commands.

Alternatives considered

Frame every stream over SSH exec stdout/stdin. This avoids Unix-socket forwarding, but requires per-stream credits, queue bounds and independent EOF semantics inside the application protocol. Independent SSH channels use the transport’s existing flow control and keep program output away from administrative framing.

Replace remote file operations with SFTP alone. SFTP supplies file transport but does not directly preserve the existing guarded atomic-write, edit, policy and error semantics. Reusing the remote local filesystem providers keeps those mechanisms with their current owners.

Expose TCP or HTTP endpoints for program streams. This permits independent transports but introduces remote port exposure, endpoint authentication and server deployment beyond the existing SSH connection. Forwarded Unix sockets use the authenticated SSH session and additionally authenticate both stream endpoints with TLS-PSK against same-user connections or pathname replacement.

Move the complete Harness to the remote host. That is a separate deployment model. It moves model credentials, Session storage and plugin state with execution rather than supplying remote implementations of existing capabilities.

Consequences

Remote providers add transport, reservation and disconnection responsibilities even though they reuse local file and process mechanisms. Raw streams, collected tails and remote spill files retain distinct lifetimes. Consumers must release their streams and handles; a helper’s cleanup result cannot be reconstructed after transport loss.

The initial composition scope is POSIX headless and custom profiles. Web workspace consumers with host-filesystem assumptions require their own integration. Network restrictions, process-visibility isolation, hostile-host attestation, persistent remote handles and automatic artifact provisioning are outside this provider family.

The portable-consumer decision remains active; this note supplies its SSH realization. The E2B retirement remains active for the removed integration and its maintenance tradeoff. Neither note is fully superseded.

Verification

Required protocol and lifecycle evidence covers malformed frames, bounds, reservation cancellation, authenticated stream publication and disconnect errors. Native SSH acceptance must exercise remote file guards and symlink identity, Bash confinement, fd 7 binary traffic, control progress under paused output, terminal operations, LSP and Node execution. External-host checks require an explicitly configured disposable remote workspace. Packaged Linux acceptance provisions a disposable OpenSSH container without Node; native-host checks own confinement evidence.

Security evidence requires both a same-user connector and a replaced socket listener that cannot claim a reserved stream, learn its key, alter another run or receive its plaintext output. Process-lifecycle evidence distinguishes direct exit from managed-range quiescence and tests cancellation both before launch publication and after the payload starts. Source and built profile checks verify the installed helper/bootstrap arrangement without transferring host credentials to program environments.

Deferred work

Persistent remote reconnection needs a separate operation-identity and recovery design; it cannot reuse live callback handles after disconnect. Broader Web support needs provider-owned workspace resources. Stronger resource accounting or revised PTC yield/wait and timeout policy belongs to the Node runtime reference, not the SSH administrative request deadline.

中文

问题

远端编码需要文件工具、Bash、终端、语言服务器与 Node 程序看到同一个文件系统与进程环境。可移植消费方决策提供这些接口。E2B 退役决策保留其异步语义,同时移除一个需要单独传输项目才能通过标准流库承载双向 PTC 控制流的集成。

SSH 提供经过认证的字节通道及逐通道流量控制,但普通 exec 请求不映射任意子进程描述符。若把 SSH 当作进程管理器的替代品,控制流桥接、启动发布、EOF、取消及断连清理就会缺少实现。

决策

部署方持有的 OpenSSH 主机别名将本地 Harness 连接到已安装的 POSIX 辅助程序。文件系统、子进程及沙箱提供方共享该辅助程序;Harness 保留 Cordis 对象、模型传输、权限、回调与 Session 持久化。终端方法保持异步。提供方路径描述执行环境,无需额外的本地/远端标记。

限制解析支持异步与取消:正在运行的辅助程序通过已加载的沙箱提供方解析每次策略,然后子进程提供方取得可直接执行的 argv。ShellExecutor.start() 在准备完成后返回 Promise<ShellProcess>。通用任务准入保持同步;由工具负责的 JobHooks 在预检后启动异步 shell 准备,取消待完成的准备并等待任何延迟出现的进程句柄结束。

私有管理 RPC 与各条程序流使用独立 SSH 通道。远端预留操作在程序启动前创建请求的流端点。stdout 与 stderr 无法承载管理回复,暂停一条输出通道也不会占用 fd 7 的流控窗口。这用更大的远端辅助程序换取显式二进制传输与有界流保留。

每条流通过私有管理 RPC 获得新的 256 位 TLS 预共享密钥。TLS 1.2 配合 PSK-AES256-GCM-SHA384 在流发布前认证两端并保护后续字节。密钥绝不作为流前缀传输。仅靠套接字权限不足:文件效果限制可能允许同用户连接,或允许在可写临时目录中替换路径名。程序不会获得管理 Unix 监听端点或流密钥。包装完成后,取消责任转移到 TLS 包装流;清理先关闭该流,再关闭底层套接字,确保原生 TLS 读取不会超过传输层的生命周期。

收集的 stdout 与 stderr 通过仅更新输出观测的处理器传递有界尾部快照。快照等待传输时,输出捕获继续进行。最终快照保留原始字节偏移,已完成的 spill 文件在连接释放后使用本地提供方的保留输出存储。

就绪流程验证已安装辅助脚本或可执行文件的摘要;脚本部署提供 PTC 引导程序时,还验证该引导程序的摘要。可执行文件部署内嵌 PTC 工作进程,无需单独的引导程序。这些检查固定预期部署产物,不用于认证恶意远端操作系统。辅助程序禁用通过 SIGUSR1 启动 Node 调试器:文件效果限制仍可能允许同用户信号,这些信号不得暴露辅助程序不受限的文件系统和进程服务。文件效果限制委托给远端本地沙箱提供方,保留其完整/部分执行披露及平台限制。

路径规范化属于文件实际存在的位置。共享策略解析器保留执行环境中的绝对路径写法;执行限制的提供方在自己的文件系统上解析符号链接与 ..。headless 通过 ctx.fs 记录和验证 cwd。SSH 不提供主机路径投影;PTC 在脚本部署中使用显式安装的远端引导程序,在可执行文件部署中使用辅助程序内嵌的工作进程。

连接丢失会使待处理操作失效,不进行重连或重放。辅助进程 EOF、信号及心跳租期会启动远端原生清理。客户端不能把租期到期当作观察到的成功终止:被中断的修改或启动可能结果未知。管理请求截止时限、消费方执行截止时限及清理分别由各自归属方负责。

辅助程序部署

显式的 launch.kind 选择远端的 node-script 或 executable 调用方式,与本地 Harness 的运行载体相互独立。本地 process.pkg 标志无法描述远端安装。协议 2 在就绪响应中包含远端运行时类型,并拒绝协议版本或启动类型不匹配,避免客户端把脚本引导规则用于内嵌工作进程。客户端与辅助程序的协议升级必须一起部署。

可执行文件内嵌 Node、辅助程序、托管子进程运行器与 PTC 工作进程。它复用 SDK 可执行文件打包决策:pkg --sea 保留包目录树与动态模块解析,无需维护独立的静态插件注册表。该记录负责与裸 Node SEA 的方案比较。内嵌运行时服务于这些私有入口;项目命令仍依赖远端机器的开发工具。

四个发布目标覆盖 Linux 和 macOS 的 x64 与 arm64,对应 POSIX 提供方及其支持的原生资源。打包不会增加 Windows 或 musl 支持。Landlock 与 macOS PTY 启动器保留为可执行文件旁的真实文件,因为操作系统无法执行 pkg 虚拟文件系统中的路径。因此,安装单元是包含原生资源与完整性元数据的完整归档目录,而非单个可执行文件。辅助程序运行时参考负责构建矩阵、部署基线及归档验证命令。

考虑过的替代方案

在 SSH exec stdout/stdin 上为所有流分帧。 这避免了 Unix 套接字转发,但要求应用协议自行实现逐流额度、队列上限及独立 EOF 语义。独立 SSH 通道使用传输层既有流控,并将程序输出与管理帧分开。

仅用 SFTP 替代远端文件操作。 SFTP 提供文件传输,但不直接保留既有的带保护原子写入、编辑、策略及错误语义。复用远端本地文件系统提供方,使这些机制继续归属现有实现。

通过 TCP 或 HTTP 端点提供程序流。 这允许独立传输,但会在现有 SSH 连接之外引入远端端口暴露、端点认证及服务器部署。转发 Unix 套接字使用已认证的 SSH 会话,并通过 TLS-PSK 额外认证流的两端,以防御同用户连接或路径名替换。

把完整 Harness 移到远端主机。 这是另一种部署模型,会将模型凭据、Session 存储及插件状态随执行一起迁移,而不是提供现有能力的远端实现。

影响

远端提供方虽然复用本地文件与进程机制,仍增加传输、预留及断连责任。原始流、收集尾部及远端 spill 文件保留各自生命周期。消费方必须释放流与句柄;传输丢失后无法重建辅助进程的清理结果。

初始组合范围为 POSIX headless 与自定义配置组合。假定可访问主机文件系统的 Web 工作区消费方需要独立集成。网络限制、进程可见性隔离、恶意主机证明、持久远端句柄及自动产物配置不属于本提供方家族。

可移植消费方决策继续有效;本文提供其 SSH 实现。E2B 退役决策仍负责已移除集成及维护取舍。两篇记录均未被完全取代。

验证

必要的协议及生命周期证据覆盖畸形消息、上限、预留取消、经过认证的流发布及断连错误。原生 SSH 验收必须覆盖远端文件保护与符号链接身份、Bash 限制、fd 7 二进制流、输出暂停时的控制进展、终端操作、LSP 及 Node 执行。外部主机检查要求显式配置的可丢弃远端工作区。打包产物的 Linux 验收会创建未安装 Node 的可丢弃 OpenSSH 容器;原生主机检查负责限制执行的证据。

安全证据要求同时尝试同用户连接与替换套接字监听端点,并确认其无法占用预留流、获知流密钥、修改另一执行或收到其明文输出。进程生命周期证据区分直接退出与托管进程范围静止,并测试启动发布前及程序启动后的取消。源码与构建后配置组合检查验证已安装辅助程序/引导安排,不向程序环境传递主机凭据。

延后工作

持久远端重连需要独立的操作身份与恢复设计,不能在断连后复用活跃回调句柄。更广泛的 Web 支持需要由提供方负责的工作区资源。更强的资源计量或修订后的 PTC yield/wait 与超时策略属于 Node 运行时参考,不属于 SSH 管理请求截止时限。