WebSocket API
The backend does not handle WebSocket connections directly. Real-time communication goes through the Cloudflare office-router Worker, which uses Durable Objects to maintain persistent WebSocket connections with clients.
Durable Object connection token
Status: The backend endpoint for minting the office-router JWT is implemented but currently not routed — the route registration is commented out in
cmd/api/main.go. The service (internal/platform/cloudflare/auth/) and handler (GenerateDOUrl) are complete and ready to be wired.
Intended flow
Client
│ 1. POST /api/v1/cloudflare/request-access (authenticated, currently disabled)
▼
Backend
│ 2. Mints a short-lived JWT signed with RSA-2048 private key
│ Subject: WorkOS user ID
│ Claims: userId, orgId, role
│ TTL: 60 seconds
▼
Client
│ 3. WebSocket upgrade to office-router Worker, JWT in header
▼
office-router Worker (Cloudflare)
│ 4. Validates JWT against backend RSA public key (CONN_JWT_PUBLIC_KEY in wrangler.jsonc)
│ 5. Opens WebSocketServer Durable Object for the org
Token details
| Field | Value |
|---|---|
| Algorithm | RS256 |
| Issuer | JWT_ISSUER env var |
| Audience | JWT_AUDIENCE env var |
| Subject | WorkOS user ID |
| Custom claims | userId, orgId, role |
| TTL | 60 seconds (handshake only) |
| Signing key | JWT_PRIVATE_KEY env var (RSA-2048 PEM, backend only) |
| Verification key | CONN_JWT_PUBLIC_KEY in office-router wrangler.jsonc |
Supabase Realtime token
A separate active endpoint generates JWTs for Supabase Realtime subscriptions (not for the office-router). See ../../features/realtime.md.
| Field | Value |
|---|---|
| Endpoint | POST /api/v1/realtime/token |
| Algorithm | HS256 |
| Signing key | SUPABASE_JWT_SECRET env var |
| Issuer | qubital-backend (hardcoded) |
| Audience | authenticated (Supabase RLS requirement) |
| TTL | 3600 seconds |
Related
../../features/realtime.md— Supabase Realtime token feature../../platform/services/cloudflare/— office-router Worker and Durable Objects architecture../../configuration.md—JWT_ISSUER,JWT_AUDIENCE,JWT_PRIVATE_KEY,WEBSOCKET_BASE_URL,SUPABASE_JWT_SECRET