Skip to content
/ relay Public

Cloudflare Durable Objects relay — zero-access encrypted message forwarding

Notifications You must be signed in to change notification settings

Termopus/relay

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 

Repository files navigation

Termopus

Termopus Relay

Zero-access encrypted message relay on Cloudflare's edge

Cloudflare Workers Durable Objects TypeScript


Overview

The Termopus Relay is a Cloudflare Workers application that forwards encrypted messages between the phone and bridge. It operates on a strict zero-access model — all messages are AES-256-GCM encrypted blobs that the relay cannot decrypt. It simply routes bytes between endpoints.

Architecture

                    Cloudflare Edge (200+ cities)
┌──────────────────────────────────────────────────────┐
│                                                      │
│   Phone ──WebSocket──► SessionRelay ──WebSocket──► Bridge
│                        (Durable Object)              │
│                                                      │
│   • Cannot decrypt messages                          │
│   • Forwards opaque blobs only                       │
│   • Session state lives at the edge                  │
│                                                      │
└──────────────────────────────────────────────────────┘

Core: SessionRelay Durable Object

Each pairing session gets its own Durable Object instance, providing:

Multi-Phone Support

  • Up to 3 phones connected simultaneously per session
  • LRU eviction when limit is reached — oldest phone disconnected gracefully
  • Each phone identified by device ID from mTLS certificate

First-Response-Wins Dedup

When Claude asks for permission and multiple phones are connected:

  • First response (Allow/Deny) wins and is forwarded to bridge
  • Duplicate responses tracked by requestId and silently dropped
  • Prevents conflicting approvals from different devices

Push Notifications

  • FCM silent push sent when Claude waits for user input
  • Wakes the app even when backgrounded or phone is locked
  • Notification includes session context for quick triage

Connection Authentication

Role Authentication
Bridge (computer) Bearer token — first connection stores token, subsequent connections must match
Phone mTLS client certificate — CF-Access-Client-Id verified against provisioned devices KV

Subscription Enforcement

4-tier phased rollout controlled by SUBSCRIPTION_ENFORCEMENT env var:

Mode Behavior
off No enforcement (development)
log Log expired subscriptions, allow through
new_only Block new connections with expired subs, allow existing
on Full enforcement — valid subscription required

API

WebSocket  wss://relay.termopus.com/{sessionId}?role=computer
WebSocket  wss://relay.termopus.com/{sessionId}?role=phone

That's it. Two WebSocket endpoints. Everything else is handled by the Durable Object.

Infrastructure

Component Service
Runtime Cloudflare Workers
State Durable Objects (per-session)
Storage Cloudflare KV (tokens, devices, subscriptions)
Push Firebase Cloud Messaging (FCM)
Auth Cloudflare Access (mTLS)

Cross-Bridge Tracking

Each device has an active_sessions:{deviceId} key in KV with 24-hour TTL, tracking how many active bridge connections exist. This enforces the MAX_BRIDGES limit per subscription tier.


About

Cloudflare Durable Objects relay — zero-access encrypted message forwarding

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published