Token broker
Example: examples/token-broker
# put upstream provider keys in the environmentbun run examples/token-broker/server.tsContract
Section titled “Contract”Request:
POST /api/voice/tokenContent-Type: application/jsonAuthorization: Bearer <application-session-token>
{ "provider": "azure_speech", "purpose": "asr", "sessionId": "required"}Response:
{ "token": "short-lived-token", "url": "wss://optional-signed-endpoint", "expiresAt": 1784000000000}Client providers:
const applicationSessionToken = await getApplicationSessionToken();
createAzureTTS({ tokenBrokerUrl: 'https://your.app/api/voice/token', tokenBrokerHeaders: { authorization: `Bearer ${applicationSessionToken}` }, tokenBrokerSessionId: voiceSessionId, region: 'eastasia', voice: 'en-US-AvaMultilingualNeural',});A token broker is appropriate only when the provider can mint a short-lived, least-privilege credential. Scope it to its purpose/route and, where possible, model, conversation, and budget. A broad bearer token is not client-safe merely because it expires sooner.
The Azure STS token in the example only reduces credential exposure time; it
does not lock voice, route, or budget. Treat it as an explicit provider-direct
mode, not the standard production boundary. In standard mode the browser calls
an application API while the Azure provider and voice stay server-side.
For request/response APIs such as OpenRouter, standard integrations should use
createOpenRouterGateway(). The server reconstructs requests and locks prompt,
model, voice, temperature, token ceiling, and reasoning. It must also enforce
user auth, conversation ownership, quotas, rate limits, payload limits,
timeouts, and audit IDs. Do not log raw audio, full transcripts, or upstream
credentials by default. See the security guide.