You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Certificate pinning is available for native platforms through `RoomOptions.networkOptions`. It applies to SDK-owned WSS signaling and internal HTTPS requests. It does not apply to WebRTC media, TURN, or application-owned token endpoints.
203
+
204
+
Certificate pinning is not supported on Flutter web because browsers do not expose certificate material to application code. Configuring it on web is treated as a misconfiguration and fails fast: `Room.connect` throws `UnsupportedError` instead of silently connecting without pinning. Only enable `certificatePinning` on web builds if you want that behavior, otherwise leave it unset when targeting web.
205
+
206
+
On native platforms, validation runs during TLS connection setup after the peer certificate is available and before the SDK writes HTTP or WSS request bytes. If validation fails, request headers and bodies are not sent.
207
+
208
+
Rules are selected by host. Exact hosts like `project.livekit.cloud`, single-label wildcards like `*.livekit.cloud`, multi-label wildcards like `**.livekit.cloud`, and `*` are supported. `*.livekit.cloud` matches `project.livekit.cloud`, but not `a.b.livekit.cloud`. `**.livekit.cloud` matches both. Rules with empty `hosts` apply to every SDK-owned TLS connection.
209
+
210
+
Hosts that match no rule are connected with platform trust only, and the SDK logs a warning. Keep in mind the SDK also connects to hosts you did not write yourself: LiveKit Cloud region failover uses server-provided regional hostnames like `project.region.production.livekit.cloud`, which carry more labels than your project URL. Use `**.livekit.cloud` so pinning also covers those hosts, and make sure the pin set includes the keys the regional endpoints serve.
211
+
212
+
All rules that match the connection host are applied. Within one check type, any configured value may match. Across check types, each configured type must pass. For example, two matching SPKI rules are treated as one accepted pin set, while SPKI pins plus exact leaf certificates require both the SPKI check and the exact leaf certificate check to pass.
213
+
214
+
Use SPKI SHA-256 pins when possible. `primaryPins` and `backupPins` are both accepted. Backup pins are useful for certificate rotation because the SDK accepts either set.
215
+
216
+
SPKI pins are matched against the leaf certificate's public key only. Unlike OkHttp or HPKP, the rest of the chain is not checked because Dart does not expose it, so pinning an intermediate or root CA key never matches and fails every connection. Pin leaf keys, and use backup pins for the future leaf keys you plan to rotate to.
Prefix the output with `sha256/` before passing it to `primaryPins` or `backupPins`.
251
+
252
+
Certificate rules can also enforce exact leaf certificates or a custom TLS trust store.
253
+
254
+
Use `pinnedLeafCertificates` to require an exact peer leaf certificate after TLS trust validation succeeds. Renewing or changing the leaf certificate requires shipping updated pinned certificates.
255
+
256
+
By itself, `pinnedLeafCertificates` does not trust private or self-signed certificates. For private PKI, also configure `trustedCertificates` with the leaf, intermediate, or root certificate that should anchor TLS validation.
257
+
258
+
```dart
259
+
final certificate = await CertificateBytes.fromAsset(
260
+
'assets/livekit_leaf_cert.pem',
261
+
);
262
+
263
+
final roomOptions = RoomOptions(
264
+
networkOptions: NetworkOptions(
265
+
certificatePinning: CertificatePinningOptions(
266
+
rules: [
267
+
CertificatePinningRule(
268
+
hosts: ['my-project.livekit.cloud'],
269
+
pinnedLeafCertificates: [certificate],
270
+
trustedCertificates: [certificate],
271
+
),
272
+
],
273
+
),
274
+
),
275
+
);
276
+
```
277
+
278
+
Use `trustedCertificates` to validate TLS against a custom trust store, similar to `SecurityContext.setTrustedCertificatesBytes`. The SDK builds a per-connection trust store from these certificates and does not include the platform trusted roots for that host. The bytes can contain a leaf, intermediate, or root certificate.
279
+
280
+
```dart
281
+
final certificate = await CertificateBytes.fromAsset(
282
+
'assets/livekit_intermediate_ca.pem',
283
+
);
284
+
285
+
final roomOptions = RoomOptions(
286
+
networkOptions: NetworkOptions(
287
+
certificatePinning: CertificatePinningOptions(
288
+
rules: [
289
+
CertificatePinningRule(
290
+
hosts: ['**.livekit.cloud'],
291
+
trustedCertificates: [certificate],
292
+
),
293
+
],
294
+
),
295
+
),
296
+
);
297
+
```
298
+
299
+
When a pinning rule matches a host, the SDK owns TLS setup for that connection and `HttpOverrides.global` or `HttpClient.badCertificateCallback` are not consulted. An app that relies on a bad certificate callback to accept a self-signed server certificate will see a `HandshakeException` once pinning is enabled for that host. Use `trustedCertificates` to trust the self-signed or private CA certificate instead.
300
+
200
301
### Screen sharing
201
302
202
303
Screen sharing is supported across all platforms. You can enable it with:
0 commit comments