https://box-<id>.share.example.com/, that a teammate, a designer, or a
phone opens in a browser with no Tesser login. The box’s first declared port
is served there, and every other port at
https://box-<id>--<port>.share.example.com/, so each port is its own site
the way localhost:<port> is.
The gateway is a Cloudflare Worker you deploy into your own Cloudflare
account, behind a Cloudflare Access application. Access decides who may open
a box. Each shared box dials the Worker over an outbound websocket, so
nothing reaches into the network the boxes run in, and the Worker holds no
secret.
Opening a sleeping box’s address wakes it, with a page that shows the
progress and turns into the app when it answers. Traffic through the gateway
keeps the box awake. A box is served only while it has a live share: tesser share <box> prints the box’s gateway address next to the review link, and
tesser share <box> --revoke, or the share expiring, takes it off within a
few seconds.
An org running in its own AWS account can run the gateway inside its VPC
instead, behind its VPN; see Serve shared boxes on your own
domain.
Pick the host
Boxes hang off one host,<host>, and each box takes one label in front of
it. Cloudflare’s free certificate covers a zone’s apex and one level below
it, so:
- A zone used only for the gateway, such as
examplereview.com, gives boxesbox-<id>.examplereview.comwith the free certificate. - A host one level down in your main zone, such as
share.example.com, puts boxes two levels deep. Their certificate needs Advanced Certificate Manager with Total TLS on the zone.
Set it up
You need a Cloudflare zone for<host> and Zero
Trust on the same account
(the free plan covers 50 users).
-
Point
<host>and*.<host>at Cloudflare with two proxied DNS records. The address does not matter; the Worker answers every request: -
In Zero Trust, add a self-hosted Access application on
*.<host>with the policies that say who may open shared boxes, such as your company’s email domain. Leave<host>itself outside it: boxes dial in there, and the Worker checks their tickets. Copy the application’s audience tag. -
Deploy the Worker from a project of its own:
index.tswrangler.jsonc
-
Point the org at it. Only an org admin can:
https://<host>/__tesser/health answers ok once the Worker is live. Share
a box with tesser share <box> and open the gateway address it prints.
How it works
- Boxes dial out. While a box is shared, Tesser hands it a ticket it
signs for your gateway, and the box keeps one websocket open to
wss://<host>/__tesser/box. The Worker checks the ticket againsthttps://api.tesser.sh/.well-known/jwks.json, so a box can only ever answer for itself. A revoke tells the box to hang up. - One Durable Object per box holds that socket and carries every request and websocket for the box over it, with flow control on bodies in both directions.
- Viewers come through Access. The Worker checks the
Cf-Access-Jwt-Assertionheader on every request against your team’s keys and the application’s audience tag. - Waking needs no secret. When a viewer opens a sleeping box, the Worker passes the viewer’s Access token to Tesser, which checks it against the team and audience you set and wakes the box.
http://localhost:<port>, so Vite’s allowedHosts and Next’s
allowedDevOrigins need nothing added. The gateway adds a small script to
each page that sends the page’s fetch, XMLHttpRequest, WebSocket, and
EventSource calls, links, and forms aimed at localhost:<port> through the
gateway, and redirects to localhost:<port> come back as gateway addresses.
Each port’s site keeps its own cookies, where localhost shares them across
ports, and a third-party sign-in only returns to a gateway address if the
provider allows it as a callback.