livekit-token-source 0.1.2

Token sources for the LiveKit Rust SDK
Documentation

LiveKit Token Source

Token sources for the LiveKit Rust SDK. A token source procures the credentials — server URL and participant token — needed to join a LiveKit room. Once a source is constructed, call fetch to obtain a set of credentials.

Fixed and configurable sources

Every token source is one of two kinds, each represented by a trait:

  • Fixed (TokenSourceFixed) — fetch() takes no parameters; the credentials are decided ahead of time and every call resolves the same way.
  • Configurable (TokenSourceConfigurable) — fetch(&options) takes TokenSourceFetchOptions that parameterize the credentials generated for that call: room name, participant identity and metadata, agent dispatch, and so on.

Combined with the mechanism used to procure credentials, this spans the following matrix:

Mechanism Using pre-generated credentials Via an HTTP request to a URL Via fully custom logic
Fixed literal — implement TokenSourceFixed
Configurable — endpoint or development_token_server implement TokenSourceConfigurable

Sources shipped with the crate

Three sources ship with the crate, constructed via factory functions.

literal

A fixed source holding a single set of pre-provisioned credentials, captured at construction and returned as-is on every fetch — no I/O involved.

use livekit_token_source::TokenSourceFixed;

let source = livekit_token_source::literal("wss://example.livekit.cloud", "<participant token>");
let response = source.fetch().await?;

endpoint

A configurable source that fetches credentials from a token endpoint implementing the standard format. Each fetch serializes the options into the standard JSON request body and POSTs it with Content-Type: application/json, plus any headers added via with_header / with_headers (e.g. for authenticating against the endpoint). A 2xx response is parsed as the standard JSON response format; any other status surfaces as TokenSourceError::Server carrying the status and body.

Requests are sent through the process-wide HTTP client from livekit-net: on native builds the built-in client is used automatically; embedders can register their own via livekit_net::set_http_client.

use livekit_token_source::{TokenSourceConfigurable, TokenSourceFetchOptions};

let source = livekit_token_source::endpoint("https://example.com/api/token")
    .with_header("Authorization", "Bearer <endpoint credential>");
let options = TokenSourceFetchOptions::new()
    .with_room_name("my-room")
    .with_participant_identity("user-123");
let response = source.fetch(&options).await?;
// connect with response.server_url / response.participant_token

development_token_server

A configurable source that queries a LiveKit development token server for prototyping. Under the hood it is an endpoint source pre-configured with the LiveKit Cloud development token server URL, authenticating via the X-Sandbox-ID header with the given token server ID.

This mechanism is inherently insecure and must not be used in production.

Custom credential backends

Custom credential backends implement the TokenSourceFixed or TokenSourceConfigurable trait directly; pick the trait by whether the backend accepts per-fetch parameters. Code written against the traits works the same with custom and shipped sources.

use async_trait::async_trait;
use livekit_token_source::{TokenSourceFixed, TokenSourceResponse, TokenSourceResult};

/// Reads credentials from a JSON file, e.g.
/// `{"server_url": "wss://...", "participant_token": "..."}`.
struct FileTokenSource {
    path: std::path::PathBuf,
}

#[async_trait]
impl TokenSourceFixed for FileTokenSource {
    async fn fetch(&self) -> TokenSourceResult<TokenSourceResponse> {
        let contents = std::fs::read_to_string(&self.path).map_err(serde_json::Error::io)?;
        Ok(serde_json::from_str(&contents)?)
    }
}

Caching

Wrap any TokenSourceConfigurable with .cached() to reuse fetched credentials for repeat fetches with equal options, for as long as the token has not expired:

let source = livekit_token_source::endpoint("https://example.com/api/token").cached();

let first = source.fetch(&options).await?;  // hits the endpoint
let second = source.fetch(&options).await?; // served from the cache

By default credentials are kept in memory and considered valid until the token's exp claim; both are customizable via with_store (e.g. keychain- or database-backed persistence, implementing the TokenSourceStore trait) and with_validator.

See examples/token_source for a runnable example.