Skip to content
Guide Reference Download app

Relay API

@claxedo/workspace-relay is the single canonical tunnel process between cloud-hosted browsers and workspace-runtime hosts, whether the host is a cloud VM or a user laptop. One package, one process, one config surface.

The relay verifies short-lived runtime access tokens, calls the configured target resolver / revocation callback, and forwards accepted traffic to the selected host with a freshly minted relay-host token.

TokenDefault TTLIssuerAudiencePurpose
Runtime Access Token (RAT)30 minutesclaxedo-control-planeworkspace-relayUser/browser authorization to reach one workspace and host through the relay.
Host Tunnel Token (HTT)5 minutesclaxedo-control-planeworkspace-relay-host-tunnelWorkspace runtime authorization to register a user-hosted tunnel.
Relay Host Token (RHT)60 secondsworkspace-relayworkspace-host-servicePer-request relay-to-host authorization minted after RAT validation.

RATs and HTTs bind issuer, audience, subject, workspace id, host id, expiry, issue time, and JTI. RATs also bind role. RHTs additionally bind the deployment pair: cloud/cloud-vm or user-hosted/local-worktree.

The relay has no /w/{workspaceId}/* URL prefix of its own — the gateway pattern lives in claxedo-server. The relay is intentionally narrow: it handles tunnel traffic and the auth checks that gate it.

RoutePurposeAuth
WS upgrade + tunnel framingHost-tunnel registration and per-request forwardingHTT (tunnel register) / RAT (per request), minted RHT to host
GET /healthLiveness. Marked unhealthy during drain.none
GET /metricsPrivileged operational data (fragmentation, slow-consumer stats).Authorization: Bearer <CLAXEDO_RELAY_METRICS_TOKEN>; when unset, loopback-only, fail-closed if no remote-address resolver

isRuntimeAccessTokenActive is the revocation/target freshness hook. Production deployments should implement it by calling the control plane (or equivalent authority) on every new HTTP request and WebSocket upgrade. A false result rejects before forwarding.

Long-lived relayed sockets are authorized at establishment time. Already-open SSE, PTY, and WebSocket streams may live until normal close, reconnect, relay drain, host disconnect, or process restart. For immediate stream revocation the control plane must also close the session/runtime channel.

The relay strips client-supplied x-forwarded-for, x-forwarded-host, x-forwarded-proto, x-real-ip, x-claxedo-internal-*, and x-supervisor-* headers. It replaces Authorization with an RHT, sets x-workspace-id, and adds x-forwarded-by: workspace-relay.

For user-hosted targets, Cookie is stripped before forwarding — a user-hosted workspace may run near a developer’s local browser cookie jar. Cloud VM targets may receive cookies when the caller intentionally sends them.

Local development needs none of these — the relay boots on loopback with an ephemeral dev key. These knobs exist for production deployments, where exactly four are required: CLAXEDO_RELAY_RESOLVER_URL, CLAXEDO_RELAY_RESOLVER_TOKEN, one of CLAXEDO_CONTROL_PLANE_JWKS_URL | CLAXEDO_RUNTIME_ACCESS_TOKEN_PUBLIC_KEY_PEM, and CLAXEDO_RELAY_HOST_SIGNING_KEY_PEM. All knobs are environment variables, read in packages/workspace-relay/src/main.ts (Bun process) and src/worker.ts (Cloudflare Worker).

Env varPurpose
CLAXEDO_RELAY_RESOLVER_URLWhere to fetch RuntimeAccessTokenActiveResults (typically claxedo-server/internal/relay/target). Required on the Bun process.
CLAXEDO_RELAY_RESOLVER_TOKENBearer token the relay sends to the resolver. Required in production (fail-closed gate at src/main.ts).
CLAXEDO_CONTROL_PLANE_JWKS_URLRemote JWKS used to verify control-plane-issued tokens (RATs and HTTs). Takes precedence over the inline PEM.
CLAXEDO_RUNTIME_ACCESS_TOKEN_PUBLIC_KEY_PEMInline public key for the same verification (alternative to JWKS). One of the two must be set.
CLAXEDO_RELAY_HOST_SIGNING_KEY_PEMPrivate PEM the relay uses to mint relay-host tokens (RHTs). Required in production — the relay refuses to start with an ephemeral key.
Env varPurpose
CLAXEDO_WORKSPACE_RELAY_HOSTListen hostname. Defaults to 127.0.0.1 (loopback).
CLAXEDO_WORKSPACE_RELAY_PORTListen port. Defaults to 7777.
CLAXEDO_RELAY_ALLOWED_ORIGINSComma-separated browser-origin allowlist for CORS. Replaces the built-in default list (Claxedo/OpenCode app origins plus http://localhost:* dev hosts). Grammar: exact origin, https://*.example.com, http://localhost:*. Works on both the Bun process and the Cloudflare Worker.
CLAXEDO_RELAY_METRICS_TOKENOptional bearer token for /metrics. Without it, /metrics requires a trusted loopback remote-address resolver.
NODE_ENVproduction / development / test. Switches the production fail-closed gates (resolver token, RHT signing key).

Cloudflare Worker (Durable Object deployment)

Section titled “Cloudflare Worker (Durable Object deployment)”
Env varPurpose
CLAXEDO_CENTRAL_URLWorker-only fallback for the resolver base URL when CLAXEDO_RELAY_RESOLVER_URL is unset (one of the two is required).
CLAXEDO_RELAY_LOCATION_HINTDurable Object location hint for relay placement.
CLAXEDO_APP_ORIGINSCloudflare-only, additive origin entries layered on top of the base allowlist (kept for existing deploys; prefer CLAXEDO_RELAY_ALLOWED_ORIGINS for full control).

Additional knobs — RHT key-rotation extras (kid overrides, next-key publication), cache TTLs, drain timeout, forwarding concurrency, synthetic-probe and audit/trace sampling — exist with sensible defaults; see the package source (packages/workspace-relay/src/main.ts, src/worker.ts) if you need them.

The relay owns CORS responses for browser-facing workspace requests. Do not forward upstream CORS headers as the source of truth. Add allowed product origins via CLAXEDO_RELAY_ALLOWED_ORIGINS and keep wildcard origins out of credentialed deployments.

Verification is pluggable via the RelayKey | RelayKeyResolver pair on verifyRuntimeAccessToken and friends, and via the unified TokenVerifier interface in @claxedo/workspace-relay-protocol. A custom verifier is only the crypto/introspection authority; the relay still validates its output into RuntimeAccessTokenClaims, binds the URL workspace id to the claims, applies revocation, and allowlists roles. Missing, unknown, or malformed roles deny. Two reference implementations ship in the protocol package: createHttpTokenVerifier (remote/OIDC introspection) and createStaticTokenVerifier (tests and single-tenant self-hosted setups).


For install instructions, architecture, and deployment shapes, see the workspace-relay package page.