Skip to content

Instance Group Bridge ​

The Instance Group Bridge (target release 2.8.0) synchronizes future plain-text messages between one group on two independent EdgeChat HTTPS sites. It does not create remote accounts or export message history.

Scope and security boundary ​

  • Both sides must use HTTPS root origins reachable through the public Cloudflare Worker boundary. IPs, localhost, private/special domains, and redirects are rejected.
  • Public, private, and general groups are supported. Direct messages are not. Each group can have only one non-revoked binding; invitations and pending claims occupy the slot.
  • Only site administrators can create, claim, confirm, pause, resume, or unlink a binding. The server rechecks administrator and group-management authorization.
  • Each site encrypts its own long-term credential with the existing keyring. Master keys are never exchanged, and no manual Secret is added.
  • WAF/Access should allow the protocol route, but /admin/instance-bridge must remain protected by the normal authenticated admin boundary.

Create a binding ​

  1. An administrator on A opens “Instance Group Bridge” in the admin sidebar, selects a group, and creates an invitation.
  2. A receives a one-time bootstrap invitation containing a 256-bit random credential. It expires after 10 minutes and is shown only once. Never put it in a URL, log, ticket, or commit.
  3. An administrator on B pastes the invitation, selects a public, private, or general group, and agrees to export future plain text only. During the claim, B generates a separate long-term random key and sends it to A over HTTPS; both sites encrypt their local copy.
  4. A verifies B's HTTPS origin and group name/summary, then confirms. Signed control tasks activate both sides, and repeated protocol deliveries do not activate twice.
  5. Refresh the page to inspect invited, claiming, pending, activating, active, or revoked state. Pause indicators and discard counts are shown separately.

There is one binding per group. B chooses the group to accept, and A must explicitly confirm the peer origin and group name rather than trusting the invitation alone.

Synchronized content ​

  • Only new, locally authored plain-text messages enter the bridge: sender_kind=local and source=edgechat.
  • Markdown bodies use the receiving site's safe renderer. Replies send only their body, without quotes, mention permissions, or remote IDs.
  • Attachments, attachment descriptions, external-source messages, history, edits, and recalls are not synchronized. A delivered copy is not removed when the source site deletes its copy.
  • Stable event IDs make message and receipt writes idempotent in one transaction.

Messages originating from Telegram or another external source are not locally authored and are never forwarded through the instance bridge.

  • Each side has an independent pause switch. Pausing stops local send/receive, clears local backlog, and notifies the peer to clear its backlog.
  • Resume uses the target revision generation, not a remote clock watermark. Messages from an older revision must not be replayed; paused backlog is discarded.
  • Unlink immediately revokes local receive eligibility and cancels backlog. A minimal credential tombstone remains for up to 7 days to retry the remote unlink notification; an in-flight request may still complete remotely.
  • Retry only wakes unexpired tasks early. It cannot revive cancelled, expired, or discarded messages.

Delivery limits ​

  • Each binding holds at most 1,000 queued messages. Overflow records a visible discard count without blocking local chat.
  • A message is retried for at most 24 hours with backoff from 30 seconds to 1 hour. Network timeout is 10 seconds and each round handles at most 10 messages.
  • A global compensation cron runs every 15 minutes to recover missed wakeups and perform bounded expiry cleanup; the database queue remains the source of truth.
  • The admin page distinguishes network/timeout, authentication/protocol error, remote pause/unlink, backlog full, and expiration, and shows the discarded-message count separately.

Deployment and recovery ​

New installations apply migration 2026-09-19-instance-bridge and INSTANCE_BRIDGE Durable Object migration v3 while retaining existing DO classes and the primary keyring. The protocol route uses the global_fetch_strictly_public flag to restrict public fetch behavior. Apply migrations before the Worker release; normal updates must not overwrite the keyring, and pause all bindings before rollback.

The frontend demo only simulates the workflow and sends no cross-site traffic. Production deployments and the GitHub Actions template reuse existing resources and secrets; no new manual Secret is required.

Built on Cloudflare · Designed for self-hosting