From a0d7922650dea6f0a04453b29e332afb6db66271 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Wed, 8 Oct 2025 15:14:46 -0400 Subject: [PATCH 1/8] docs: add initial draft of tokensource readme docs --- README.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 86c9440a78..54a3abea21 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,13 @@ const room = new Room({ }, }); +// get your url from livekit's dashboard, or point it at a self hosted livekit deployment +const url = "ws://localhost:7800"; + +// generate a token by making a request to a endpoint using the livekit server sdk or +// using a prebuilt TokenSource (documented below) +const token = "..."; + // pre-warm connection, this can be called as early as your page is loaded room.prepareConnection(url, token); @@ -107,7 +114,7 @@ room .on(RoomEvent.LocalTrackUnpublished, handleLocalTrackUnpublished); // connect to room -await room.connect('ws://localhost:7800', token); +await room.connect(url, token); console.log('connected to room', room.name); // publish local camera and mic tracks @@ -304,6 +311,99 @@ setLogExtension((level: LogLevel, msg: string, context: object) => { }); ``` +### Generating a url/token with `TokenSource` + +A pre-implemented set of credentials fetching utilities. Once one is constructed, call `fetch` on +to generate a new set of credentials. + +There are two types of `TokenSource`'s - fixed and configurable. Configurable token sources can be +passed options as part of the generation process, allowing your to customize the token that they +generate. Fixed token sources generate their credentials fully indepentantly and don't allow for +output customization. + +```ts +// Fixed token sources don't take any parameters as part of `fetch`: +const fixed: TokenSourceFixed = /* ... */; +const fixedResponse = await fixed.fetch(); +room.connect(fixedResponse.serverUrl, fixedResponse.participantToken); + +// Configurable token sources can optionally take parameters to change what is encoded into the token: +const configurable: TokenSourceConfigurable = /* ... */; +const configurableResponse = await configurable.fetch({ agentName: "agent to dispatch" } /* <-- here */); +room.connect(configurableResponse.serverUrl, configurableResponse.participantToken); +``` + +| | via pre-generated credentials | via a request to a url | via custom logic | +|fixed | TokenSource.literal | N/A | TokenSource.literal(async () => { /* ... */ }) | +|configurable | — | TokenSource.endpoint or TokenSource.sandboxTokenServer | TokenSource.custom | + +#### TokenSource.Literal +A fixed token source which returns a static set of credentials or a computed set of credentials +with no external input on each call. + +Example: +```ts +const literal1 = TokenSource.literal({ serverUrl: "ws://localhost:7800", participantToken: "..." }); +await literal1.fetch() // { serverUrl: "ws://localhost:7800", participantToken: "..." } + +const literal2 = TokenSource.literal(async () => ({ serverUrl: "ws://localhost:7800", participantToken: "..." })); +await literal2.fetch() // { serverUrl: "ws://localhost:7800", participantToken: "..." } +``` + +#### TokenSource.Endpoint +A configurable token source which makes a request to an endpoint to generate credentials. By +default, a `POST` request with a `Content-Type: application/json` header is made, and the request +body is expected to follow the [standard token format](FIXME: add docs link here!). If +credentials generation is successful, the endpoints returns a 2xx status code with a body following +the [standard token response format](FIXME: add docs link here!). + +Example: +```ts +const endpoint1 = TokenSource.endpoint("http://example.com/credentials-endpoint"); +await endpoint1.fetch({ agentName: "agent to dispatch" }) // { serverUrl: "...", participantToken: "... token encoding agentName ..." } + +const endpoint2 = TokenSource.endpoint("http://example.com/credentials-endpoint", { + // For all supported options below, see https://developer.mozilla.org/en-US/docs/Web/API/RequestInit + method: "PUT", + headers: { + "X-Custom-Header": "custom header value", + }, +}); +await endpoint2.fetch({ agentName: "agent to dispatch" }) // { serverUrl: "...", participantToken: "... token encoding agentName ..." } +``` + +#### TokenSource.SandboxTokenServer +A configurable token source which makes a request to a +[sandbox token server endpoint](https://cloud.livekit.io/projects/p_/sandbox/templates/token-server), +a LiveKit-hosted token generation mechanism. This is an inherently insecure token generation +mechanism and should only be used for prototyping / NOT used in production. + +One parameter is required - the sandbox id from the dashboard. This is the `token-server-xxxxxx` +value in `https://token-server-xxxxxx.sandbox.livekit.io`. + +Example: +```ts +const sandbox = TokenSource.sandboxTokenServer("token-server-xxxxxx"); +await sandbox.fetch({ agentName: "agent to dispatch" }); // { serverUrl: "...", participantToken: "... token encoding agentName ..." } +``` + +#### TokenSource.Custom +A fully custom configurable token source that allows one to consume any end application-specific +token generation mechanism. + +Note that it is expected that all options passed into `fetch` will always be encoded into the +output token. If you'd rather implement a fixed version of this TokenSource, see +`TokenSource.literal(async () => { /* ... */ })`. + +Example: +```ts +const sandbox = TokenSource.custom(async (options) => { + // generate token info via custom means here + return { serverUrl: "...", participantToken: "... options encoded in here ..." }; +}); +await sandbox.fetch({ agentName: "agent to dispatch" }); +``` + ### RPC Perform your own predefined method calls from one participant to another. From cbd7ccdbc055ee84e58d52473b3805c242bbd8d7 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Wed, 8 Oct 2025 15:24:02 -0400 Subject: [PATCH 2/8] docs: add in better tokensource markdown table --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 54a3abea21..a3c788197c 100644 --- a/README.md +++ b/README.md @@ -333,9 +333,10 @@ const configurableResponse = await configurable.fetch({ agentName: "agent to dis room.connect(configurableResponse.serverUrl, configurableResponse.participantToken); ``` -| | via pre-generated credentials | via a request to a url | via custom logic | -|fixed | TokenSource.literal | N/A | TokenSource.literal(async () => { /* ... */ }) | -|configurable | — | TokenSource.endpoint or TokenSource.sandboxTokenServer | TokenSource.custom | +|Mechanism: | using pre-generated credentials | via a http request to a url | via fully custom logic | +|-------------|--|--|--| +|Fixed | [`TokenSource.literal`](#tokensourceliteral) | — | [`TokenSource.literal(async () => { /* ... */ })`](#tokensourceliteral) | +|Configurable | — | [`TokenSource.endpoint`](#tokensourceendpoint) or [`TokenSource.sandboxTokenServer`](#tokensourceendpoint) | [`TokenSource.custom`](#tokensourcecustom) | #### TokenSource.Literal A fixed token source which returns a static set of credentials or a computed set of credentials From 9f4e2f422395357e76e1bb19ccc8f3bd7b887151 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Thu, 9 Oct 2025 13:18:49 -0400 Subject: [PATCH 3/8] refactor: made updates based on shijing comments --- README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a3c788197c..f31c71a85d 100644 --- a/README.md +++ b/README.md @@ -313,13 +313,13 @@ setLogExtension((level: LogLevel, msg: string, context: object) => { ### Generating a url/token with `TokenSource` -A pre-implemented set of credentials fetching utilities. Once one is constructed, call `fetch` on -to generate a new set of credentials. +A pre-implemented set of credentials fetching utilities. Once a `TokenSource` is constructed, call +`fetch` to generate a new set of credentials. There are two types of `TokenSource`'s - fixed and configurable. Configurable token sources can be -passed options as part of the generation process, allowing your to customize the token that they -generate. Fixed token sources generate their credentials fully indepentantly and don't allow for -output customization. +passed options as part of the generation process, allowing you to customize the token that they +generate. Fixed token sources generate static credentials and don't accept parameters that can +effect the generated token. ```ts // Fixed token sources don't take any parameters as part of `fetch`: @@ -340,7 +340,7 @@ room.connect(configurableResponse.serverUrl, configurableResponse.participantTok #### TokenSource.Literal A fixed token source which returns a static set of credentials or a computed set of credentials -with no external input on each call. +with no external input required on each call. Example: ```ts @@ -355,7 +355,7 @@ await literal2.fetch() // { serverUrl: "ws://localhost:7800", participantToken: A configurable token source which makes a request to an endpoint to generate credentials. By default, a `POST` request with a `Content-Type: application/json` header is made, and the request body is expected to follow the [standard token format](FIXME: add docs link here!). If -credentials generation is successful, the endpoints returns a 2xx status code with a body following +credentials generation is successful, the endpoint returns a 2xx status code with a body following the [standard token response format](FIXME: add docs link here!). Example: @@ -376,8 +376,10 @@ await endpoint2.fetch({ agentName: "agent to dispatch" }) // { serverUrl: "...", #### TokenSource.SandboxTokenServer A configurable token source which makes a request to a [sandbox token server endpoint](https://cloud.livekit.io/projects/p_/sandbox/templates/token-server), -a LiveKit-hosted token generation mechanism. This is an inherently insecure token generation -mechanism and should only be used for prototyping / NOT used in production. +a LiveKit-hosted token generation mechanism. + +This token generation mechanism is inherently insecure and should only be used for +prototyping; do NOT use in production. One parameter is required - the sandbox id from the dashboard. This is the `token-server-xxxxxx` value in `https://token-server-xxxxxx.sandbox.livekit.io`. @@ -389,7 +391,7 @@ await sandbox.fetch({ agentName: "agent to dispatch" }); // { serverUrl: "...", ``` #### TokenSource.Custom -A fully custom configurable token source that allows one to consume any end application-specific +A fully custom configurable token source that allows you to consume any end application-specific token generation mechanism. Note that it is expected that all options passed into `fetch` will always be encoded into the From 48b0f3466809e48e6cffe55b627e4414188d0223 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Mon, 20 Oct 2025 10:52:17 -0400 Subject: [PATCH 4/8] fix: add custom pure function note --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f31c71a85d..da4339ade8 100644 --- a/README.md +++ b/README.md @@ -392,7 +392,8 @@ await sandbox.fetch({ agentName: "agent to dispatch" }); // { serverUrl: "...", #### TokenSource.Custom A fully custom configurable token source that allows you to consume any end application-specific -token generation mechanism. +token generation mechanism. Tokens that are generated are cached and used until they expire or the +options passed into `fetch` change. Note that it is expected that all options passed into `fetch` will always be encoded into the output token. If you'd rather implement a fixed version of this TokenSource, see From 137435d5501832bdc2a25973c00e170263ec3936 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Mon, 1 Dec 2025 11:52:09 -0500 Subject: [PATCH 5/8] fix: swap in docs links for pull request temporarily In the future, this really needs to point to a real docs page. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index da4339ade8..93ff7aface 100644 --- a/README.md +++ b/README.md @@ -354,9 +354,9 @@ await literal2.fetch() // { serverUrl: "ws://localhost:7800", participantToken: #### TokenSource.Endpoint A configurable token source which makes a request to an endpoint to generate credentials. By default, a `POST` request with a `Content-Type: application/json` header is made, and the request -body is expected to follow the [standard token format](FIXME: add docs link here!). If +body is expected to follow the [standard token format](https://github.com/livekit-examples/token-server-status/pull/33). If credentials generation is successful, the endpoint returns a 2xx status code with a body following -the [standard token response format](FIXME: add docs link here!). +the [standard token response format](https://github.com/livekit-examples/token-server-status/pull/33). Example: ```ts From 1a19dc0766342bfc7b8112c8fb00b1e17f770706 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Mon, 1 Dec 2025 11:53:59 -0500 Subject: [PATCH 6/8] refactor: adjust first line of token source docs to be a overall summary --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93ff7aface..755a2dbc96 100644 --- a/README.md +++ b/README.md @@ -313,7 +313,7 @@ setLogExtension((level: LogLevel, msg: string, context: object) => { ### Generating a url/token with `TokenSource` -A pre-implemented set of credentials fetching utilities. Once a `TokenSource` is constructed, call +A TokenSource is a pre-implemented way of fetching credentials. Once a `TokenSource` is constructed, call `fetch` to generate a new set of credentials. There are two types of `TokenSource`'s - fixed and configurable. Configurable token sources can be From fb8823716eb43db17825e60f5cc32ac790de7774 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Mon, 1 Dec 2025 12:07:11 -0500 Subject: [PATCH 7/8] fix: swap out standard token format links to a better source --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 755a2dbc96..8c56108112 100644 --- a/README.md +++ b/README.md @@ -354,9 +354,9 @@ await literal2.fetch() // { serverUrl: "ws://localhost:7800", participantToken: #### TokenSource.Endpoint A configurable token source which makes a request to an endpoint to generate credentials. By default, a `POST` request with a `Content-Type: application/json` header is made, and the request -body is expected to follow the [standard token format](https://github.com/livekit-examples/token-server-status/pull/33). If +body is expected to follow the [standard token format](https://github.com/livekit-examples/token-server-node/blob/main/TEMPLATE.md#sandbox). If credentials generation is successful, the endpoint returns a 2xx status code with a body following -the [standard token response format](https://github.com/livekit-examples/token-server-status/pull/33). +the [standard token response format](https://github.com/livekit-examples/token-server-node/blob/main/TEMPLATE.md#sandbox). Example: ```ts From e688b79ebcec13ec8e34e1ecf594e13d72771d14 Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Mon, 1 Dec 2025 12:11:58 -0500 Subject: [PATCH 8/8] fix: update placeholder links one more time - actually link to the rendered version of the template file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8c56108112..f137f14733 100644 --- a/README.md +++ b/README.md @@ -354,9 +354,9 @@ await literal2.fetch() // { serverUrl: "ws://localhost:7800", participantToken: #### TokenSource.Endpoint A configurable token source which makes a request to an endpoint to generate credentials. By default, a `POST` request with a `Content-Type: application/json` header is made, and the request -body is expected to follow the [standard token format](https://github.com/livekit-examples/token-server-node/blob/main/TEMPLATE.md#sandbox). If +body is expected to follow the [standard token format](https://cloud.livekit.io/projects/p_/sandbox/templates/token-server). If credentials generation is successful, the endpoint returns a 2xx status code with a body following -the [standard token response format](https://github.com/livekit-examples/token-server-node/blob/main/TEMPLATE.md#sandbox). +the [standard token response format](https://cloud.livekit.io/projects/p_/sandbox/templates/token-server). Example: ```ts