Witbitz docs PlatformTrustAll docs

The live call — what protects it, and what you can check

The other pages here describe the async Space: a sealed ledger, a content-blind platform, a decrypt-once render. A live call is a different guarantee with a different shape, and conflating the two is the easiest mistake to make about Witbitz. This page is the call's half.

One line: a call's audio, video and chat are end-to-end encrypted between browsers and no server in the path can decode them — but the way you'd verify that is currently not exposed in Witbitz Call's UI (§4), and unlike upstream Kibitz, media here goes through a relay by default (§2).

Witbitz Call is the Kibitz engine, rebranded — a pinned dependency, not a fork. The mechanisms below are Kibitz's; the configuration is ours, and it differs in two ways that matter. Engine-level detail: kibitz.chat/security.


1. Media — end-to-end encrypted

Calls use WebRTC. Audio and video are encrypted with DTLS-SRTP, and the keys are negotiated directly between the participating browsers — they never leave the devices. There is no SFU or media server that decodes, mixes or records anything. Chat, shared links and directed messages travel the same way, over direct DTLS-encrypted data channels between each pair; no participant relays another's content.

The single assumption is that those keys are exchanged honestly. That happens in signalling (§3), and §4 is how you'd check it.

2. ⚑ The relay is the default here, not the exception

Upstream Kibitz uses a TURN relay only when a direct connection is impossible, and says most calls never need one. Witbitz Call sets FORCE_RELAY_DEFAULT = true (kibitz/src/core/callMedia.ts) — direct-first was tried and regressed three separate times on real networks, so relay-on is the deliberate default. A ?relay URL parameter overrides it.

What that means, stated plainly:

3. Signalling — introductions only, and the one party that could attack

Two browsers cannot find each other unaided. A signalling server briefly exchanges setup data: a temporary peer id, the room name from the link, and ICE candidates (which contain IP addresses). It sees connection metadata, never call content, and stores none of it.

Witbitz Call uses Kibitz's signalling broker (signal.kibitz.chat) — Witbitz has no equivalent service. So for the live-call path there is a third party in the introduction step, and it is worth naming rather than glossing.

It matters because signalling is also where the browsers publish their certificate fingerprints. A compromised or compelled signalling server is the one party that could attempt to sit in the middle of a future call by substituting a key during setup. A relay cannot — it only ever sees ciphertext. That is exactly the attack §4 exists to catch.

4. ⚑ Verifying it — the safety code, and why you cannot use it here today

Every WebRTC "end-to-end" claim ultimately trusts the signalling channel to deliver the right keys. The mechanism that removes that trust is a safety code: a short emoji code derived from the two browsers' actual DTLS certificates — the ones really used on the wire, not the ones named in signalling. Same idea as Signal's safety numbers. Matching codes mean nobody is in the middle; differing codes mean somebody is.

The engine implements this fully, including re-warning if a peer reconnects with different key material, and an SSH-style alarm when a previously verified name reappears with a different key.

It is not reachable in Witbitz Call. The brand sets VITE_BRAND_HIDE_PRIVACY_CHROME=1, which suppresses the shield button that opens Verify (kibitz/src/widget/SecondaryControls.tsx). The call is still end-to-end encrypted — the flag hides UI, it does not change cryptography — but the affordance that would let you check that claim is currently switched off.

That is the honest position: on this path you are trusting the signalling server, where upstream Kibitz would let you verify it. If the call matters to you at that level, use kibitz.chat, where the shield is present. Exposing it here is a UI decision, not a protocol one, and it is the single change that would make this page's §1 claim checkable rather than asserted.

5. Offline — a room on one Wi-Fi, with no internet

For a plane, a cabin, a venue with dead cell: one Android device runs a LAN hub, everyone else opens the app on the same Wi-Fi, and the room works with no internet at all. The download and setup are at witbitz.chat/call/host.

Like the internet broker, the hub is a coordination point — it sees who is in the room and carries the handshakes. Content stays end-to-end encrypted: browser-to-browser when they can connect directly, or relayed through the hub's own LAN TURN as ciphertext where they cannot (on phone Wi-Fi, iOS hides each device behind an mDNS name the other cannot resolve). The hub never reads it, and it is a box you run on your own network.

6. What this protects — and what it does not

Protected: the content of the call, from the network and from Witbitz. It cannot be recorded server-side because the media never reaches a server in readable form.

Not protected, and not hidden:

7. The agent in the call

An agent joins as a participant, and the capability layer governs it: every peer carries a grant of what it may perceive (media, chat, roster, directed data) and act. Humans default to full, agents to read-only. It is engine-enforced per peer — a withheld peer never receives the bytes — so a read-only agent gets chat but no audio or screen share and can post nothing until granted. The same Grant vocabulary crosses to the async Space unchanged (the verified room §7).

8. How this differs from a Space — do not conflate them

Live call Async Space
Guarantee E2EE between browsers; no server decodes content-blind at rest; one decrypt-once render
Who could read it nobody in the path — but see §3, §4 the render, transiently, while a member is present
Verified by a safety code — not currently exposed (§4) four checks you run in a terminal (verify)
Persistence ephemeral; the room vanishes when everyone leaves a sealed ledger that persists
The moat claim standard WebRTC, done carefully the double blind

The platform's verifiable-privacy argument is about the Space. The call is a well-built E2EE call — a different and more conventional guarantee. Saying so plainly is the point of this page.

9. Where the code is

Concern Where
Media, relay policy (FORCE_RELAY_DEFAULT) kibitz/src/core/callMedia.ts
Safety code / verify UI (hidden by the brand flag) kibitz/src/widget/SecondaryControls.tsx
Capability grants kibitz/src/core/capabilities.ts
TURN credentials (ours, same-origin) witbitz infra/turn.tf/api/turn
The engine, open source (Apache-2.0) github.com/kibitz-chat/kibitz

Machine-readable source: the-live-call.md · every doc in one fetch: llms-full.txt · ← the-double-blind · delegated-authority