Skip to main content

Gates

FREEHOP / NETWORK MODELSealed signalling
◈Player A
◇Gate
◈Player B

The gate passes encrypted setup messages. It never carries media.

Gates pass sealed signalling messages. They cannot open them and never carry media.

A gate is Freehop’s signalling service. Your app may also run its backend authority and an optional session gateway. It is a blind rendezvous mailbox: peers that announce the same opaque room tag can post sealed envelopes to each other through it, and that is all it does.

What a gate does​

When Ana and Ben join the same room, their clients connect to the gates listed in their tickets and announce the room. The gate tells each of them who else is there, and forwards the envelopes they address to each other. Those envelopes carry everything WebRTC needs to set up a call (session descriptions, ICE candidates, capabilities), sealed with a key that only room members can derive.

Here is the whole conversation from the gate's side, using the frames of the gate protocol:

{"t":"hello","v":1}
{"t":"welcome","v":1,"stun":["stun:gate.example.com:3478"],"limits":{"box":49152,"peersPerRoom":16}}
{"t":"join","room":"Xq3v…43 characters…","peer":"k2Pz…22 characters…"}
{"t":"peers","room":"Xq3v…","peers":["n8Wd…"]}
{"t":"send","room":"Xq3v…","to":"n8Wd…","box":"ylq0Hc9…opaque base64url…"}
{"t":"recv","room":"Xq3v…","from":"n8Wd…","box":"Cq9Lr2T…opaque base64url…"}

The room tag is derived from the room secret with HKDF, so it does not directly reveal your human-readable room name. IP addresses, the WebSocket Origin and traffic patterns can still identify an application or correlate participants. Peer ids are 16 random bytes, fresh for every join.

What a gate sees, and what it cannot see​

The gate learnsThe gate never learns
The IP addresses of the sockets that connect to itThe room secret, or anything derived from it except the tag
Opaque room tags and random peer idsSession descriptions (SDP) and ICE candidates
Envelope sizes and timingCapabilities and gateway credentials
The claims of a gate token, if you use them (expiry, room tag, gate audience)Your users' names or your application's member ids
A single byte of media

A gate also cannot forge or re-route an envelope without detection. Every envelope is bound to its room, sender and recipient, so an envelope that a gate relabels fails authentication at the recipient. A gate cannot add members to a room either: its roster is only a hint, and a peer becomes a member only after an envelope from it authenticates. What a hostile gate can do is drop or delay traffic. Listing several gates in your tickets protects against that. The security model has the details.

How much traffic a gate carries​

Most gate traffic is connection setup. Keepalives, newcomer discovery and recovery can continue afterwards:

  • About 15 to 35 KB per pair of peers at call setup.
  • Roughly zero afterwards. Every link carries a pre-negotiated data channel, and once it is open the peers send each other's envelopes over it instead of through the gate.
  • In the home-lab network tests the gate's total for a whole simulated scenario was 30 to 210 KB, including retries of pairs that never connected.

The gate enforces this by construction. Its byte budgets make media tunnelling impractical: a single five-peer join needs about 100 KB, while media needs megabytes per minute.

BoundValue
WebSocket frame64 KiB
Sealed envelope (box)48 KiB
Bytes a socket makes the gate forward (fan-out included)512 KiB burst, refilled at 2 KiB/s
Messages per socket40 per second, burst 400
Rooms per socket / peers per room4 / 16
Sockets per source address (an IPv6 /64 counts as one address)32
Sockets still being admitted256 in total, 8 per address; torn down within 1 s when refused
hello deadline / idle timeout5 s / 90 s
Unflushed output before a socket is closed1 MiB per socket, 32 MiB for the whole gate

Many gates, and no gates at all​

A ticket can list up to eight gates. Clients connect to every one of them and announce the room on each, and gates are interchangeable: any one of them may disappear.

  • Peers on different gates still meet. Say Ana only reaches gate-1, Ben only reaches gate-2, and Cleo reaches both. Cleo connects to both of them and reports her links in her sealed capabilities. Ana's envelopes for Ben then travel through Cleo's data channel, forwarded once, until Ana and Ben have their own link.
  • Calls survive a total gate outage. An established call does not depend on any gate. In home-lab browser tests, peers kept exchanging media (about 600 audio packets per peer in 6 seconds) after every gate was shut down.
  • A public WebTorrent tracker works as a gate. A gate URL of the form bt+wss://tracker.openwebtorrent.com makes the client use that tracker as its mailbox. The swarm's info_hash is the first 20 ASCII characters of the hex-encoded, decoded room tag (80 bits of tag material), and the envelopes ride in the offer and answer fields that trackers already relay. Like a Freehop gate, a tracker sees connection metadata but cannot decrypt envelopes. The live call on this site uses public trackers as its only gates. Torrent trackers as gates explains how it works and when to use it.

Admission: open or token-gated​

A gate is either open or token-gated. With a token secret, every client must present a token minted with the same secret: base64url(claims) "." base64url(HMAC-SHA256(secret, body)), with claims { exp, room?, aud }. A token that names a room tag may only join that room. Its audience must match this gate’s exact public URL.

You rarely mint tokens yourself: configure the authority’s gateTokenSecrets map with each gate URL and signing key, and every ticket carries a token bound to its room. Your gate then serves only your own rooms. See Gate service.

STUN on the side​

A gate can also answer STUN Binding requests on UDP (IPv4 and IPv6), so that peers learn their public addresses without a third-party STUN server. It answers Binding requests only, rate-limits each source address and never relays anything. Configure those URLs in the authority's stun option or the client's application options. Clients ignore welcome.stun, so a hostile mailbox cannot choose additional hosts for the browser to contact.

What the gate sees, live​

Type a message below. Your browser seals it exactly the way Freehop seals signalling (HKDF room key, AES-256-GCM, room and peers bound as additional data) and shows you the frame the gate receives. Then tamper with it the way a hostile gate would, and watch the recipient reject it.

What the gate sees

Ana's browserhas the secret
Room secret…
Ana's peer id…

Sealed in this page with Freehop's own crypto.mjs: HKDF-SHA256 derives the room tag and an AES-256-GCM key from the secret.

The gateno key

Ana to gate

…

Gate to Ben

…

The gate also sees connecting IP addresses. This frame reveals a room tag, peer ids, 0 bytes and the time. Your 101-byte message is inside the box.

Ben's browserhas the secret
How the envelope is sealed
salt = "peerlane/v1/freehop-demo"
tag  = base64url(HKDF-SHA256(secret, salt, "room-tag"))
key  = HKDF-SHA256(secret, salt, "envelope-key")  // AES-256-GCM
aad  = "peerlane/v1|" + tag + "|" + from + "|" + to
box  = base64url(iv[12] || AES-GCM(key, iv, plaintext, aad))

Any room member holds this key and could claim another sender id. The envelope protects against outsiders, not impersonation by a member. Wire strings still say peerlane, Freehop's codename. The tag here is ….

Next​

Gates only introduce peers. Paths and escalation explains how the peers then find a route for their media.