This release fixes port forwards that hang waiting for the other side to finish, and API and provisioning keys no longer depend on the member who created them. The gateway also gets two settings for large fleets.
Port forwards finish when either side does
When one side of an ssh -L or ssh -R forward finished sending, the gateway never passed the EOF on to the other side, so anything that reads until EOF hung. The gateway now forwards the EOF in both directions. A client that closes its forward also releases it right away, so an idle device no longer keeps it open until the session ends (#7749).
Upgrading? The gateway forwards the client's EOF only to agents running v0.29.2 or later, since older agents close the device socket on EOF and would lose the reply. Update agents to get the fix in both directions.
API keys outlive their creator
An API key belongs to its namespace and has its own role. Before, when a member left the namespace, was removed, or was demoted to observer, every key that member had created was deleted. A demotion to operator kept them. Keys now survive their creator on every path, and neither API keys nor provisioning keys record who created them. Creating an API key still caps its role at the creator's (#7774).
Upgrading? Migration
054drops the creator column from API keys and provisioning keys. A rollback recreates it as nullable, with no creators filled in.
Gateway settings for large fleets
Two new environment variables tune the gateway's Caddy proxy. Left unset, the gateway keeps Caddy's defaults.
SHELLHUB_GATEWAY_API_MAX_CONNScaps the connections from the gateway to the API. Under a burst of API requests, the gateway dials a new connection for almost every request. Those dials share source ports with every agent tunnel, and with a large fleet they time out and return 502. With the cap set, requests above it wait for a pooled connection instead (#7778).SHELLHUB_GATEWAY_STREAM_BUFFER_SIZEsets the buffer size on the agent and web terminal routes. Caddy holds two of these buffers for every connected device, so the default multiplies by the fleet size (#7776).
Also in this release
Fixes
- Agents from before v0.15, which keep a device token without a tenant, can reconnect again. Since v0.27 they got 401 on reconnect until the agent restarted (#7773)
- The MFA recovery dialog reports errors by status and stays open so you can retry (#7766)
- The console cancels its setup check when you leave the page, so a fresh install no longer shows the app briefly before redirecting to setup (#7766)
Under the hood
- Key name validation and the one-time secret panel are shared between API keys and provisioning keys (#7769)
- TypeScript 7 in the UI, Node 24.22.1 pinned across the repo, mockery v3.9.0 (#7766, #7771)
- Test and OpenAPI example fixes (#7770, #7772, #7775, #7777)
Full Changelog: v0.29.1...v0.29.2