in livekit flutter is end to end for group call al...
# ask-ai
e
in livekit flutter is end to end for group call already implemented or do i have to create keys and exchange them by myself?
t
Thanks for reaching out, Ahmad. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — great question. You're asking whether LiveKit's Flutter SDK already implements end-to-end encryption (E2EE) for group calls or if you must generate and exchange keys yourself. Short answer: • Yes — the LiveKit Flutter SDK includes built‑in E2EE for group calls. You do not need to manually create and exchange encryption keys for the standard implementation. What that means: • Media frames are encrypted on the client and decrypted only by intended recipients, so the LiveKit server cannot read plaintext media. • The SDK handles frame-level encryption/decryption, key management, and key rotation internally. • Encryption runs in a separate worker thread (so it won’t block your main UI thread). Customization: • If you need custom key management (for example, integrating with your own PKI or custom secure key exchange), you can implement your own key provider. That’s optional — required only if the built‑in behavior doesn’t meet your security or integration requirements. If you'd like, I can: • Point you to the specific Flutter API calls and a short example to enable E2EE in your app. • Describe how to implement a custom key provider and where to plug it in. Which would help you most right now — a quick setup example or details on custom key providers? Sources: client-sdk-flutter | livekit/livekit_composite | DeepWiki | client-sdk-js | livekit/livekit_composite | DeepWiki | client-sdk-swift | livekit/livekit_composite | DeepWiki
e
how does livekit do the key exchange and does it do use Signal Protocol and does it change the keys when a user leaves instead or ratcheting them?
t
Thanks — I’ll answer your three parts: how LiveKit does key exchange, whether it uses Signal Protocol, and how keys change when users leave vs. ratcheting. Acknowledgement • You asked how LiveKit exchanges keys, whether it uses the Signal Protocol, and whether keys change when a user leaves or via ratcheting. I’ll address each point clearly. How key exchange works • LiveKit uses a centralized key‑provider pattern. A designated participant (commonly the room owner or the appointed key provider) generates and distributes encryption keys to participants. • Keys are sent over the signaling channel (the same channel used for room signaling) and the client SDK’s
KeyProvider
interface runs in a separate worker to handle generation, distribution, and local encryption/decryption. • The SDK handles frame-level encryption and decryption, and the worker performs these operations off the main thread so UI/networking isn’t blocked. Does LiveKit use the Signal Protocol? • No. LiveKit does not use the Signal Protocol or its double‑ratchet / prekey mechanisms. • Instead, LiveKit implements a custom E2EE approach designed for real‑time media in WebRTC, focused on frame encryption, efficient distribution to multiple participants, and key rotation appropriate for group calls. What happens when a user leaves — rotation vs. ratcheting • When a participant leaves, LiveKit performs key rotation: the key provider generates new encryption keys and distributes them to the remaining participants so subsequent media is encrypted under the new keys. This ensures forward secrecy from the moment the leaving user is removed. • LiveKit also supports explicit or periodic key ratcheting during a session (e.g., calling
ratchet()
to advance keys or scheduled ratchets). This provides ongoing key evolution but is not the Signal double‑ratchet algorithm; it updates the key/salt used for frame encryption rather than using Diffie‑Hellman chains. • In short: leaving triggers a key rotation to remove access for departed participants; independent ratcheting can also be used to periodically advance keys for added security. If helpful, I can: • Provide the Flutter API calls or a short code example showing where to enable E2EE and where a custom
KeyProvider
plugs in. • Show an example flow for rotating keys on participant leave or invoking a ratchet programmatically. Which would you like next — a small Flutter example to enable E2EE, or the steps to implement a custom
KeyProvider
? Sources: client-sdk-js | livekit/livekit_composite | DeepWiki | examples/other | livekit/livekit_composite | DeepWiki
e
ok i don't want to use your centralized key‑provider pattern i want to exchange the keys myself for these scenarios when a user starts a call and when a user answers a call and when a user joins an existing call how would i set the shared key and rotate when someone leaves and wouldn't setting the key mid video call disrupt or lag the video/audio?
t
Thanks — I hear that you want to bypass LiveKit’s centralized key‑provider and do your own key exchange for these specific events: when a user starts a call, when a user answers, and when a user joins an existing call — plus rotate keys when someone leaves. You also want to know whether changing keys mid‑call will disrupt audio/video. Short answer • The LiveKit Flutter SDK does not expose APIs to manually set or inject E2EE shared keys or to replace the built‑in key provider. You cannot directly perform the custom key exchange and key injection workflows you described using the documented Flutter SDK surface. • Because those hooks aren’t exposed, rotating or injecting keys mid‑call via the Flutter SDK is not supported. What that means for your scenarios • Start a call / answer a call / join an existing call: You cannot plug in your own out‑of‑band key exchange flow that directly sets the SDK’s active encrypt/decrypt keys from Flutter code. • Rotate when someone leaves: LiveKit performs key rotation via its key provider pattern; there is no documented Flutter API to force an arbitrary key rotation by supplying new raw keys. • Mid‑call key changes and media disruption: The SDK runs encryption in a worker thread to minimize blocking, but there is no documented method to inject keys mid‑stream, so we cannot confirm behavior for an unsupported path. In general, changing keys at the RTP/frame level does require careful handoff (and short pauses or rekey steps can briefly affect decoding), but the Flutter SDK does not provide supported hooks to manage that directly. Options and recommended approaches • Use the built‑in KeyProvider pattern: The supported path is to implement a custom KeyProvider (the SDK supports plugging a key provider implementation in other SDKs) or use the existing provider behavior so key generation/distribution and rotation are handled by the SDK. This gives you reliable, supported rotation on participant leave and periodic ratcheting without touching low‑level WebRTC internals. • If you need full control over key exchange: ◦ You would need to implement your exchange outside the LiveKit Flutter SDK and then modify the native WebRTC layer or the LiveKit client implementation to accept injected keys — this is not supported or documented in the Flutter SDK and would require significant native/engine changes. ◦ That path carries risk: unsupported modifications can break future upgrades, and low‑level key switches can cause brief decoding issues unless carefully synchronized across participants and RTP streams. • Alternative hybrid approach: ◦ Keep the SDK’s encryption enabled but perform your key agreement out‑of‑band and have your custom key provider translate your agreed key material into whatever the SDK’s KeyProvider expects. This requires a KeyProvider integration point that is not exposed in Flutter today; it’s feasible on platforms/SDKs where KeyProvider wiring is documented. If you want to proceed, tell me which of these you prefer and I’ll tailor next steps: • I want the supported route: show me how to implement or configure the SDK’s KeyProvider behavior (I can provide examples for platforms where it’s exposed). • I want to explore a native modification: I understand this is unsupported and want high‑level pointers on where to look in the native/WebRTC stack. • I want to design an out‑of‑band exchange that works with a KeyProvider (if you can run KeyProvider code on a platform that supports it). Which option do you want to pursue? If you pick one, please share your target platforms (Android, iOS, web) and whether you’re using pure Flutter or embedding native code — that will help me give focused guidance. Sources: client-sdk-flutter | livekit/livekit_composite | DeepWiki | client-sdk-js | livekit/livekit_composite | DeepWiki
e
but there are methods like setSharedKey and setRawKey what are these for if i simply exchange the keys and use these wouldn't that work?
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!