feat(envd): add WebSocket raw TCP tunnel endpoint#2942
Conversation
Add a GET /tunnel WebSocket endpoint to envd that relays raw TCP bytes between a client and a target host:port inside the sandbox. The target is given via host/port query params, validated and dialed before the upgrade so bad params return 400 and connection failures 502 as normal HTTP responses; after the 101 upgrade the connection is a verbatim bidirectional relay with a keepalive ping to survive the upstream proxies' idle timeouts. Auth reuses the existing X-Access-Token header check, and the endpoint is documented in the OpenAPI spec and generated like every other envd route. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR SummaryMedium Risk Overview The PR description says envd 0.7.0 but Reviewed by Cursor Bugbot for commit cee340d. Bugbot is set up for automated code reviews on this repo. Configure here. |
❌ 7 Tests Failed:
View the top 3 failed test(s) by shortest run time
View the full list of 4 ❄️ flaky test(s)
To view more test analytics, go to the Test Analytics Dashboard |
There was a problem hiding this comment.
Code Review
In packages/envd/internal/api/tunnel.go, the keepalive ping is sent using the request context without a timeout, which can cause the ping to block indefinitely if the connection becomes silently dead. Additionally, if the ping fails, the goroutine exits without closing the connection, leading to a silent socket and goroutine leak. Wrapping the ping in a short timeout context and explicitly closing the connection on failure ensures resources are cleaned up promptly.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1143e5a. Configure here.
Bound each keepalive ping with a 5s timeout so a silently-dead connection can't block the ping indefinitely, and close the WebSocket when a ping fails so the relay's io.Copy calls unblock and the tunnel tears down promptly instead of lingering until an upstream proxy idle timeout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@mishushakov Can you check how big the websocket library is, just to be sure? |
|
@ValentaTomas according to Claude: The WebSocket library used in envd is Size
The So it's a very lightweight addition: a small, self-contained library with no transitive third-party dependencies pulled into the envd build. |

Adds a
GET /tunnelWebSocket endpoint to envd that tunnels raw TCP to a targethost:portinside the sandbox: the target is passed viahost/portquery params, validated and dialed before the upgrade so bad params return 400 and connection failures 502 as ordinary HTTP responses, and after the 101 upgrade the connection becomes a verbatim bidirectional byte relay (binary frames, no framing) with a 30s keepalive ping to survive the upstream proxies' idle timeouts. Authentication reuses the existingX-Access-Tokenheader check, and the endpoint is defined inspec/envd.yamland generated (api.gen.go) like every other envd route. The default host islocalhost; any host is allowed since the sandbox is the user's own environment. Includes unit tests covering the echo relay, host defaulting, and the auth/400/502 paths, and bumps the envd version to 0.7.0 (it usesgithub.com/coder/websocket, already vendored elsewhere in the repo at v1.8.13).🤖 Generated with Claude Code