https://box-<id>.tesser.review/, and every other port at
https://box-<id>--<port>.tesser.review/, with nothing to set up. Only the
org’s active members can open these addresses. The first visit sends them to
tesser.sh to sign in with their Tesserc account, and the sign-in lasts 12
hours on that address. Setting up a share gateway with tesser gateway set
moves the org’s boxes off tesser.review and onto your own domain.
A share gateway gives every shared box its own address on your domain, such
as https://box-<id>.share.example.com/, that a teammate, a designer, or a
phone opens in a browser with no Tesserc 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 in a browser wakes it, with a page that
shows the progress and turns into the app when it answers. Only a person
opening the page wakes the box. A request from curl or a script gets a 503
response saying the box is asleep, and a page that loads without someone
clicking or typing the address shows a Wake it button instead. 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, Tesserc 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 Tesserc, 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.
Image, stylesheet, and other resource URLs aimed at localhost:<port> are
rewritten the same way, including ones the page’s scripts add later.
The ports a page can reach this way are the box’s own declared ports plus
the ports it reaches through its dependencies: each [deps] port on the box,
and the ports of the boxes behind them, followed down the dependency chain.
That chain only passes through the boxes of the person who shared the box
and the org’s shared instances. A port served by another member’s own box is
not reachable, and the gateway answers 404 for it. After a tesser wire
changes the box’s dependencies, the reachable ports update on their own.
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.