Forward SSH gateway channels to sandbox loopback - #57
Merged
Merged
Conversation
czpython
force-pushed
the
codex/gateway-loopback
branch
from
September 28, 2026 07:54
f547fec to
050184b
Compare
czpython
force-pushed
the
codex/gateway-loopback
branch
from
September 28, 2026 08:08
050184b to
1cfa0bb
Compare
The gateway accepts a direct-tcpip channel to 127.0.0.1 or localhost and refuses all other destinations. It forwards the channel through a tunnel into the sandbox, which the provider opens with open_gateway_tunnel. For docker-sbx, the tunnel goes through `sbx ssh proxy` to sandboxd. All channels of one caller connection share one tunnel. It closes when the caller disconnects.
czpython
force-pushed
the
codex/gateway-loopback
branch
from
September 28, 2026 08:14
1cfa0bb to
096a12e
Compare
This was referenced Sep 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The SSH gateway refused every direct-tcpip channel. Thus a client could not reach the Chat bridge or VNC on the sandbox loopback.
The gateway now accepts a channel to
127.0.0.1orlocalhostand refuses all other destinations. It forwards the channel through an SSH tunnel into the sandbox. The provider opens this tunnel withopen_gateway_tunnel. Fordocker-sbx, the tunnel goes throughsbx ssh proxyto sandboxd. sandboxd authenticates the OS user on its local socket, so the gateway uses no key. All channels of one caller connection share one tunnel, and it closes when the caller disconnects.The sandbox image does not change. The gateway runs no process in the sandbox for forwarding.
sandboxd has two limits:
ChannelOpenError. A client that starts a missing service must treat an immediate end of data as "not running".::1. The channel stays open with no data. Thus the gateway refuses::1.Validation:
uv run pytest: 734 passed on SQLite. Ruff, format checks, and Pyright passed.DockerSbxProvider.open_gateway_tunnelforwarded to a real sandbox. A 4 MiB transfer with half-close passed.localhostpassed.::1and10.0.0.1were refused. Thesbx ssh proxyprocess stopped after the caller disconnected.Not tested: the Chat and VNC workflows, the
images/sbximage, and Postgres.Fixes #56.
The change also applies the review checklist to
gateway/server.py.GatewayConnection.hosthas noNonedefault,castreplaces theassert isinstancechecks, the single-use host-key and SFTP-extension helpers are inlined, andsftp_backend()is nowget_sftp_backend().