What changed
Roder 0.1.14 focuses on hosted deployments and remote-runner safety. Hosted gateways can now resolve external bearer credentials into tenant contexts, authenticate browser WebSockets through the roder.remote.v1 subprotocol, and apply a deployment request policy before JSON-RPC dispatch. That policy can rewrite or deny requests centrally, while health probes stay unauthenticated for schedulers.
Open hosted WebSocket connections now revalidate their bearer before every request and on a bounded idle timer. If an external credential expires or a service account is revoked, request dispatch and notifications stop without waiting for the client to reconnect. The gateway also evicts idle tenant runtimes and stops that lifecycle loop during shutdown.
Runner-bound threads now create or resume a remote session only when an approved native workspace tool first executes. Text-only turns and host-executed MCP work do not wake a sandbox. If initialization fails, Roder retries later and does not fall back to local filesystem tools.
Why it matters
- Hosted deployments can serve browser clients without putting tokens in query strings. Browser WebSockets can authenticate with subprotocols, while native clients can continue using bearer headers.
- Credential revocation takes effect on open sockets. That matters for service-account rotation and external identity providers because a revoked credential stops both calls and outbound notifications.
- Tenant data paths are collision-resistant for externally resolved tenant ids. Existing lowercase slug tenant directories keep their original paths, while arbitrary external ids map under a hashed directory layout.
- Remote runner work is lazier and safer. A selected sandbox is not touched until a tool actually needs the workspace, and hosted runtimes can disable local workspaces entirely so malformed runner bindings fail closed.
- Long remote commands have a real cancellation story.
exec_commandcan run one-shot commands through a remote runner with deadlines, output truncation, and Codex-shaped results; timeouts and interruptions request provider cancellation. - Thread-scoped MCP bearer tokens can be refreshed on
turn/startwithout persisting the credential in thread metadata.
Using it
Browser-hosted SDK clients should use the hosted client defaults, which offer roder.remote.v1 and bearer.<token> during the WebSocket handshake:
import { HostedClient } from "@roderai/sdk";
const hosted = await HostedClient.connect({ url, token });
await hosted.whoami();
Native hosts that control WebSocket headers can still use bearer headers. Hosted deployments should keep allow_local_workspaces = false unless local host execution is explicitly intended, configure remote-runner destinations for workspace tools, and rely on the gateway request policy for deployment-specific allow or deny rules.
For MCP tools that require per-thread credentials, pass the short-lived token on turn/start. Roder refreshes the volatile thread credential for that turn without copying it into persisted thread metadata.