TacitusMail
All posts
Feature

Audio and video calls, encrypted end-to-end, on web and iOS

Tacitus now ships peer-to-peer WebRTC calls between users. Media never touches our servers — it flows directly between browsers and iPhones with DTLS-SRTP encryption. CallKit on iOS rings the lock screen.

Two weeks of WebRTC plumbing are live. From the conversation header you can now tap the phone or camera icon and start a call to any other Tacitus user — same in the iOS app, same in the web client.

How the media flows

WebRTC negotiates a direct UDP path between the two browsers (or one browser and one iPhone). If NAT traversal fails we fall back to our Coturn relay, but the relay still only ever sees DTLS-SRTP encrypted frames — the media key exchange happens between the peers. Our server never sees your audio or video.

Signalling

The offer/answer/ICE exchange goes over the same /ws/signaling WebSocket that the chat uses, as a set of typed envelopes: call_invite, call_ringing, call_offer, call_answer, call_ice, call_end. A Redis pub/sub bus fans the envelopes across web replicas so two users on different backend servers can still reach each other.

iOS

The iOS app is a full CallKit citizen. Incoming calls ring the lock screen, answer from the lock screen, the call lives in Recents like a phone call. The entitlement for unrestricted VoIP push is still pending with Apple; until it clears, the app has to be in foreground (or recently backgrounded) to ring — once the entitlement lands, calls will wake the device via PushKit.

T
The Tacitus Mail team
Engineering posts and release notes from the people who write the code.

More from the blog