Skip to main content

Get started with encryption

Learn how to implement end-to-end encryption in your LiveKit applications.

Overview

This guide shows you how to implement end-to-end encryption (E2EE) in your LiveKit applications. E2EE encrypts both media tracks (audio and video) and data channels (text and byte streams), ensuring that no intermediaries can access your content.

For more information about how E2EE works and what it covers, see the Encryption overview.

Implementation guide

The following implementation examples use the encryption field. To learn more about data channel encryption, see the Encryption overview.

These examples show how to use the built-in key provider with a shared key. If you need to use a custom key provider, see the Using a custom key provider section.

// 1. Initialize the external key provider
const keyProvider = new ExternalE2EEKeyProvider();
// 2. Configure room options
const roomOptions: RoomOptions = {
encryption: {
keyProvider: keyProvider,
// Required for web implementations
worker: new Worker(new URL('livekit-client/e2ee-worker', import.meta.url)),
},
};
// 3. Create and configure the room
const room = new Room(roomOptions);
// 4. Set your externally distributed encryption key
await keyProvider.setKey(yourSecureKey);
// 5. Enable E2EE for all local tracks
await room.setE2EEEnabled(true);
// 6. Connect to the room
await room.connect(url, token);
// 1. Initialize the key provider with options
let keyProvider = BaseKeyProvider(isSharedKey: true, sharedKey: "yourSecureKey")
// 2. Configure room options with E2EE
let roomOptions = RoomOptions(encryptionOptions: E2EEOptions(keyProvider: keyProvider))
// 3. Create the room
let room = Room(roomOptions: roomOptions)
// 4. Connect to the room
try await room.connect(url: url, token: token)
// 1. Initialize the key provider
val keyProvider = BaseKeyProvider()
// 2. Configure room options
val roomOptions = RoomOptions(
encryptionOptions = E2EEOptions(
keyProvider = keyProvider
)
)
// 3. Create and configure the room
val room = LiveKit.create(context, options = roomOptions)
// 4. Set your externally distributed encryption key
keyProvider.setSharedKey(yourSecureKey)
// 5. Connect to the room
room.connect(url, token)
// 1. Initialize the key provider
final keyProvider = await BaseKeyProvider.create();
// 2. Configure room options
final roomOptions = RoomOptions(
encryption: E2EEOptions(
keyProvider: keyProvider,
),
);
// 3. Create and configure the room
final room = Room(options: roomOptions);
// 4. Set your externally distributed encryption key
await keyProvider.setSharedKey(yourSecureKey);
// 5. Connect to the room
await room.connect(url, token);
// 1. Use the hook to create an RNE2EEManager
// with your externally distributed shared key
// (Note: if you need a custom key provider, then you'll need
// to create the key provider and `RNE2EEManager` directly)
const { e2eeManager } = useRNE2EEManager({
sharedKey: yourSecureKey,
dataChannelEncryption: true,
});
// 2. Provide the e2eeManager in your room options
const roomOptions = {
encryption: {
e2eeManager,
},
};
// 3. Pass the room options when creating your room
<LiveKitRoom
serverUrl={url}
token={token}
connect={true}
options={roomOptions}
audio={true}
video={true}
>
</LiveKitRoom>
# 1. Initialize key provider options with a shared key
e2ee_options = rtc.E2EEOptions()
e2ee_options.key_provider_options.shared_key = YOUR_SHARED_KEY
# 2. Configure room options with E2EE
room_options = RoomOptions(
auto_subscribe=True,
e2ee=e2ee_options
)
# 3. Create and connect to the room
room = Room()
await room.connect(url, token, options=room_options)
// 1. Initialize the key provider with options
const keyProviderOptions = {
sharedKey: yourSecureKey, // Your externally distributed encryption key
};
// 2. Configure E2EE options
const e2eeOptions = {
keyProviderOptions,
};
// 3. Create and configure the room
const room = new Room();
// 4. Connect to the room with E2EE enabled
await room.connect(url, token, {
e2ee: e2eeOptions,
}
);

Examples

The following examples include full implementations of E2EE.

Using a custom key provider

If your application requires key rotation during the lifetime of a single room or unique keys per participant (such as when implementing the MEGOLM or MLS protocol), you'll need to implement your own key provider. The full details of that are beyond the scope of this guide, but a brief outline for the JS SDK is provided below (the process is similar in the other SDKs as well):

  1. Extend the BaseKeyProvider class.
  2. Call onSetEncryptionKey with each key/identity pair
  3. Set appropriate ratcheting options (ratchetSalt, ratchetWindowSize, failureTolerance, keyringSize).
  4. Implement the onKeyRatcheted method to handle key updates.
  5. Call ratchetKey() when key rotation is needed.
  6. Pass your custom key provider in the room options, in place of the built-in key provider.