Cette page est affichée en anglais. Une traduction française est en cours.
ScriptsMay 11, 2026·4 min de lecture

LiveKit Token Server — Sign JWTs for Room Access

Server-side token signing for LiveKit rooms. Python/Node SDKs. Per-user permissions, room scoping, TTL. Required for production.

LiveKit
LiveKit · Community
Prêt pour agents

Cet actif peut être lu et installé directement par les agents

TokRepo expose une commande CLI universelle, un contrat d'installation, le metadata JSON, un plan selon l'adaptateur et le contenu raw pour aider les agents à juger l'adaptation, le risque et les prochaines actions.

Stage only · 17/100Stage only
Surface agent
Tout agent MCP/CLI
Type
Skill
Installation
Stage only
Confiance
Confiance : New
Point d'entrée
Asset
Commande CLI universelle
npx tokrepo install 793c4a17-cd72-40f3-aba5-9cb0f5957f1d
Introduction

LiveKit rooms require signed JWT access tokens — your backend signs a token with API key + secret, granting a specific identity permission to join a specific room with specific capabilities (publish, subscribe, record, data). Never sign in the browser. This is the server-side flow with Python and Node examples. Best for: any production LiveKit deployment, multi-tenant voice apps, per-user permission models. Works with: livekit-server-sdk (Python, Node, Go, Ruby, Java). Setup time: 10 minutes.


Python token endpoint (FastAPI)

from livekit import api
from fastapi import FastAPI, HTTPException, Depends
import os

app = FastAPI()

@app.post("/livekit/token")
async def issue_token(user_id: str, room: str, user = Depends(authenticated_user)):
    if not can_join_room(user, room):
        raise HTTPException(403, "not allowed in this room")

    token = (
        api.AccessToken(os.environ["LIVEKIT_API_KEY"], os.environ["LIVEKIT_API_SECRET"])
        .with_identity(user_id)
        .with_name(user.display_name)
        .with_grants(api.VideoGrants(
            room_join=True,
            room=room,
            can_publish=True,
            can_subscribe=True,
            can_publish_data=True,
        ))
        .with_ttl(timedelta(hours=1))
        .to_jwt()
    )
    return {"token": token, "url": os.environ["LIVEKIT_URL"]}

Node token endpoint (Express)

import { AccessToken } from 'livekit-server-sdk';

app.post('/livekit/token', requireAuth, async (req, res) => {
  const { userId, room } = req.body;
  if (!canJoinRoom(req.user, room)) return res.status(403).send();

  const at = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, {
    identity: userId,
    name: req.user.displayName,
    ttl: '1h',
  });
  at.addGrant({
    roomJoin: true,
    room,
    canPublish: true,
    canSubscribe: true,
    canPublishData: true,
  });

  res.json({ token: await at.toJwt(), url: process.env.LIVEKIT_URL });
});

Grant cheat sheet

Grant Use case
room_join Required for any participant
can_publish Participant can publish audio/video
can_subscribe Participant can hear/see others
can_publish_data Send arbitrary chat / state via DataChannel
room_admin Can mute, remove participants
room_record Can start egress recording
ingress_admin Can manage SIP / RTMP ingress

Production hardening

  • Short TTL — 1 hour max for end-user tokens. Browser refreshes via your endpoint.
  • Per-user identity — never reuse identities. user_id should be your DB primary key.
  • Server-side only — never log secrets, never ship API_SECRET to the browser.
  • Cache the SDK — instantiate once, reuse for many tokens.

FAQ

Q: Can I sign tokens in the browser? A: No — the API_SECRET would be exposed. Always sign in your backend. The browser only ever sees the resulting JWT, which has limited TTL and scoped grants.

Q: How do agents get their own token? A: Agents authenticate the same way — your worker process signs an agent identity token (with agent=True grant) before joining the room. LiveKit Cloud agent dispatchers handle this automatically when you deploy via the LiveKit CLI.

Q: What about webhooks for participant join/leave? A: Configure webhooks at cloud.livekit.io → Webhooks. Events: room_started, participant_joined, participant_left, track_published, egress_started. Verify the X-LiveKit-Signature header server-side.


Quick Use

  1. pip install livekit-api or npm install livekit-server-sdk
  2. Build an authenticated POST /livekit/token endpoint in your backend
  3. Frontend POSTs (user_id, room), gets back {token, url}, joins with the SDK

Intro

LiveKit rooms require signed JWT access tokens — your backend signs a token with API key + secret, granting a specific identity permission to join a specific room with specific capabilities (publish, subscribe, record, data). Never sign in the browser. This is the server-side flow with Python and Node examples. Best for: any production LiveKit deployment, multi-tenant voice apps, per-user permission models. Works with: livekit-server-sdk (Python, Node, Go, Ruby, Java). Setup time: 10 minutes.


Python token endpoint (FastAPI)

from livekit import api
from fastapi import FastAPI, HTTPException, Depends
import os

app = FastAPI()

@app.post("/livekit/token")
async def issue_token(user_id: str, room: str, user = Depends(authenticated_user)):
    if not can_join_room(user, room):
        raise HTTPException(403, "not allowed in this room")

    token = (
        api.AccessToken(os.environ["LIVEKIT_API_KEY"], os.environ["LIVEKIT_API_SECRET"])
        .with_identity(user_id)
        .with_name(user.display_name)
        .with_grants(api.VideoGrants(
            room_join=True,
            room=room,
            can_publish=True,
            can_subscribe=True,
            can_publish_data=True,
        ))
        .with_ttl(timedelta(hours=1))
        .to_jwt()
    )
    return {"token": token, "url": os.environ["LIVEKIT_URL"]}

Node token endpoint (Express)

import { AccessToken } from 'livekit-server-sdk';

app.post('/livekit/token', requireAuth, async (req, res) => {
  const { userId, room } = req.body;
  if (!canJoinRoom(req.user, room)) return res.status(403).send();

  const at = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, {
    identity: userId,
    name: req.user.displayName,
    ttl: '1h',
  });
  at.addGrant({
    roomJoin: true,
    room,
    canPublish: true,
    canSubscribe: true,
    canPublishData: true,
  });

  res.json({ token: await at.toJwt(), url: process.env.LIVEKIT_URL });
});

Grant cheat sheet

Grant Use case
room_join Required for any participant
can_publish Participant can publish audio/video
can_subscribe Participant can hear/see others
can_publish_data Send arbitrary chat / state via DataChannel
room_admin Can mute, remove participants
room_record Can start egress recording
ingress_admin Can manage SIP / RTMP ingress

Production hardening

  • Short TTL — 1 hour max for end-user tokens. Browser refreshes via your endpoint.
  • Per-user identity — never reuse identities. user_id should be your DB primary key.
  • Server-side only — never log secrets, never ship API_SECRET to the browser.
  • Cache the SDK — instantiate once, reuse for many tokens.

FAQ

Q: Can I sign tokens in the browser? A: No — the API_SECRET would be exposed. Always sign in your backend. The browser only ever sees the resulting JWT, which has limited TTL and scoped grants.

Q: How do agents get their own token? A: Agents authenticate the same way — your worker process signs an agent identity token (with agent=True grant) before joining the room. LiveKit Cloud agent dispatchers handle this automatically when you deploy via the LiveKit CLI.

Q: What about webhooks for participant join/leave? A: Configure webhooks at cloud.livekit.io → Webhooks. Events: room_started, participant_joined, participant_left, track_published, egress_started. Verify the X-LiveKit-Signature header server-side.


Source & Thanks

Built by LiveKit. Licensed under Apache-2.0.

livekit/python-sdks, livekit/server-sdk-js

🙏

Source et remerciements

Built by LiveKit. Licensed under Apache-2.0.

livekit/python-sdks, livekit/server-sdk-js

Fil de discussion

Connectez-vous pour rejoindre la discussion.
Aucun commentaire pour l'instant. Soyez le premier à partager votre avis.

Actifs similaires