Porthole
Sharing a session

Named invites

Give each person their own private join link, and see who actually joined.

A plain session link is a capability: anyone holding it can connect. A password narrows that to anyone holding the password. Neither tells you who joined.

--allow issues one secret per person.

porthole host --allow Ali --allow Sana --allow "Dev Team Lead"

Porthole prints a personal link for each name:

  Invited 3 people — send each person their own link:

    Ali              https://porthole.professorhusnain.com/s/p3rx9kma?name=Ali#key=…
    Sana             https://porthole.professorhusnain.com/s/p3rx9kma?name=Sana#key=…
    Dev Team Lead    https://porthole.professorhusnain.com/s/p3rx9kma?name=Dev+Team+Lead#key=…

    Anyone without a link cannot join. A forwarded link works,
    so treat these like passwords.

Send each person theirs. When they open it they are admitted without a prompt — their secret and their name are both in the link — and your terminal names them as they connect.

What this gives you

  • Only invited people can join. A session link on its own is not enough.
  • You learn who joined. Connect and disconnect messages carry the name you chose for them.
  • You can invite one person without inviting a group. Revoking one link does not mean rotating a shared password for everyone else.

What this does not give you

An invite is a secret, not an identity

A secret can be passed on. If Ali forwards their link, whoever opens it joins as Ali, and nothing on your terminal will say otherwise.

Names are labels you chose, not verified identities. Treat invite links with the same care as passwords: send them over a channel you trust, one person per link, and end the session if one gets loose.

This is a deliberate trade. Verified identity would mean the signaling server holding an OAuth client secret, exposing a callback endpoint, and seeing the identity of every viewer — on a product whose entire claim is that the server sees nothing. Per-person secrets deliver what invites are actually for, without breaking that.

Where the secret travels

The secret is in the URL fragment (#key=…), never the query string. Browsers do not transmit fragments, so the secret stays on the recipient's machine. As a query parameter it would be sent in the request line to whatever serves the viewer and recorded in its access logs before any script could strip it — and the viewer is served through a CDN edge, so those logs are not yours to control.

The viewer removes the secret from the address bar as soon as it reads it, so it does not linger in browser history or leak through Referer.

Each secret is 16 characters from a 31-symbol alphabet — about 79 bits, and the server applies per-token exponential backoff to failed attempts on top of that.

Rules

  • Names must be distinct. Two people sharing a name would make "who joined" ambiguous, which is the feature's whole point, so it is refused.
  • Names cannot be empty.
  • Invites stack with --readonly, --mask, --expire, and everything else.
porthole host --allow Ali --allow Sana --readonly --expire 45m

Joining from a terminal

An invite link works with porthole join as well as in a browser — the secret is read from the link and never printed:

porthole join "https://porthole.professorhusnain.com/s/p3rx9kma?name=Ali#key=…"

Quote it. The # starts a comment in most shells, which would strip the secret before Porthole ever sees it.

On this page