Kibitz is a privacy tool, so being precise about what is open, what isn't, and exactly who can see what is
itself part of the product. Here's that, with a threat model and a public roadmap. For how a call connects
cryptographically, see the Security page.
What's open source
The pieces you actually run are public, under the kibitz-chat GitHub organization:
The app build — the redistributable, self-contained build of kibitz.chat. Host it anywhere (any static host, or content-addressed on IPFS) so a copy can outlive this site: kibitz-chat/kibitz.
A reference app — Whist, a full multiplayer game built entirely on Kibitz's headless engine: kibitz-chat/whist.
Open source vs build artifact vs private
Open & redistributable: the compiled build of the app and the LAN hub. Anyone can host them; running your own copy depends on nothing of ours.
Documented, so you can reimplement: the protocol (below) and the embed/SDK API. You don't have to trust a binary — the wire format is described.
Not published: the operator's deployment configuration — the specific domains, signaling-worker handle, and TURN credentials behind kibitz.chat. These are operational secrets, not part of what you run; the build points at its own /api/* and a copy can point at your own.
The protocol, in one screen
A room is a link. The name maps to a deterministic peer id; the first browser to claim it is the authority.
Content (peer-to-peer): chat, payment links, annotations, and opaque app messages (co-browse, game state) travel directly between browsers over DTLS-encrypted data connections — one per pair, alongside the media. No participant relays anyone else's content; a directed sendTo reaches only its recipient. The emoji safety code verifies the media connection specifically; per-data-channel verification is a planned follow-up.
Presence (coordinated by the first participant): the roster, knock-to-admit lobby, lock, and reset are coordinated by whoever claimed the room — membership signalling, not message content. Content gating follows the roster: an un-admitted peer never appears in it, so no one's data mesh connects to it.
Media (mesh, end-to-end encrypted): audio/video flow directly between browsers (DTLS-SRTP); no server decodes, mixes, or records them. This is the part you verify yourself with the safety code.
Signaling only introduces browsers and carries key fingerprints; a TURN relay (only when a direct link is impossible) forwards ciphertext it can't read.
Threat model — who can see what
Other participants: the media (it's their call too) and the whole data channel. Vet who has the link; use the knock-to-admit lobby or lock the room to control entry.
The room authority (the first participant's browser): coordinates presence (roster, lobby, lock) — so it knows who is in the room, but it does not relay or see chat / links / co-browse, which go peer-to-peer. For media and content it's just a normal peer.
The signaling broker: connection metadata only (a temporary peer id, the room name, IP-bearing ICE candidates) — never content, and it stores none. Because key fingerprints pass here, a compromised broker is the one party that could attempt to MITM a future call — exactly what the safety code catches. It can't touch a call in progress.
The TURN relay: ciphertext, IP addresses, and traffic volume only. It cannot decrypt the media. Most calls never use it.
The operator (us): can be made to take the site down, but not to silently reach into calls — per-call keys are ephemeral and held only by the two browsers.
Nothing is stored: rooms vanish when everyone leaves; chat lives only in the open panels. There is no database to subpoena.
Reproduce / run your own
The build is redistributable and the protocol is documented, so you needn't depend on kibitz.chat — host the
build, or point a copy at your own signaling worker and TURN. Developers can even test against the real engine
offline: joinRoom(room, { transport: createLocalBus() }) runs the full room transport in memory (see the
docs).
Public roadmap
Shipped: embeddable widget + headless engine, E2EE media, peer-to-peer data channel
(chat / co-browse / sendTo go directly between browsers — no participant relays content), the safety
code (per-peer SAS), knock-to-admit lobby, screen-share stage, shared annotation, transport-only payment links,
room moderation (remove + block-rejoin, lock, reset), role labels, per-person mute/volume, keyboard shortcuts +
push-to-talk, connection diagnostics (direct/relay + RTT/loss), and an in-memory presence test transport.
Planned / under consideration: per-data-channel safety-code verification; first-class agent
identity & capability permissions; expiring and one-time invite links; local captions/transcripts; broader
browser coverage (Firefox sidebar, Safari fallback) + a compatibility matrix; an npm package with generated API
docs; and app templates beyond Whist. Priorities shift with feedback — tell us what you need.
Reporting a security issue
Please report vulnerabilities privately to
[email protected] rather than disclosing publicly, and give a
reasonable chance to fix.