Bayer LiveKit Platform Architecture¶
LiveKit ⧉ is an open-source platform for real-time voice, video, and data applications. It provides a media server, client SDKs, and an agent framework — everything needed to build AI agents that talk, listen, and see.
But LiveKit was designed for single-team deployments. It ships with one set of static API credentials that grant unrestricted administrative access — any holder can join any room, dispatch any agent, record any conversation, and delete any session. There is no way to scope a key to a specific team, room, or operation.
At Bayer, dozens of teams build AI agents and client applications on shared LiveKit infrastructure. Static credentials break down at this scale — they can't be scoped, can't be audited, and can't be revoked without affecting everyone.
The Bayer LiveKit Platform solves this. It adds an enterprise identity and security layer on top of standard LiveKit, replacing static credentials with identity-based, scoped, time-limited tokens — so every team gets LiveKit's full real-time capabilities with none of the credential risk.
How the Platform Extends LiveKit¶
| Capability | Standard LiveKit | Bayer LiveKit Platform |
|---|---|---|
| Authentication | Static API key + secret shared by all teams | Microsoft Entra ID — every connection tied to a verified identity |
| Credential scoping | One key grants full admin access to all rooms | Per-session tokens bound to a single room and identity |
| Revocation | Rotating the shared key disrupts all teams | Disable one Entra app — zero impact on others |
| Audit trail | No record of who performed an action | Every registration and session logged with full identity context |
| Credential exposure | Developers need API keys to build and test agents | Developers never see LiveKit credentials — the platform handles authentication transparently |
| Compliance | Cannot demonstrate least-privilege or access controls | Identity-based access with full traceability — Entra ID, Ocelot, and LKPS enforce each boundary independently |
Design Principles¶
These principles guided every design decision — from how tokens are issued to how the SDK wraps the standard LiveKit agent framework.
- Zero-trust security
- All access is authenticated and authorized via Microsoft Entra ID. No developer or application ever holds static LiveKit credentials. Every boundary — edge proxy, orchestration service, media server — validates tokens independently.
- Audit and accountability
- Every agent registration and session start is logged with full identity context: who requested it, when, from which application, and with what permissions.
- Leverage LiveKit native patterns
- The platform does not reinvent LiveKit. It uses LiveKit's agent dispatch, standard room management, and native WebRTC transport. Agent code is standard LiveKit — only the authentication layer changes.
- Simplicity
- Minimal abstraction layers. The SDK is a thin wrapper, not a framework. The service has four endpoints. If LiveKit already handles something, the platform stays out of the way.
System Overview¶
flowchart TB
subgraph auth["Authentication — HTTPS"]
Client["Client Application<br/><i>Web · Mobile · Desktop · CLI</i>"]
Agent["AI Agent<br/><i>Bayer LiveKit SDK</i>"]
Ocelot["Ocelot<br/><i>Reverse Proxy</i>"]
LKPS["LiveKit Platform Service<br/><i>Orchestration · Tokens · Audit</i>"]
EntraID["Microsoft Entra ID<br/><i>Identity Provider</i>"]
Client -. "① Acquire token" .-> EntraID
Agent -. "② Acquire token" .-> EntraID
Client -- "③ Entra JWT" --> Ocelot
Agent -- "④ Entra JWT" --> Ocelot
Ocelot -- "⑤ Validated headers" --> LKPS
LKPS -- "⑥ Scoped LiveKit JWT" --> Client
LKPS -- "⑦ Scoped LiveKit JWT" --> Agent
end
subgraph realtime["Real-time Communication — WebRTC"]
SFU["LiveKit Server<br/><i>SFU — Selective Forwarding Unit</i>"]
end
Client == "⑧ Voice · Video · Data" ==> SFU
Agent == "⑨ Voice · Video · Data" ==> SFU
SFU -. "⑩ Webhooks" .-> LKPS
style auth fill:transparent,stroke:#5c6bc0
style realtime fill:transparent,stroke:#26a69a
| Step | Action |
|---|---|
| ① ② | Client and agent authenticate with Microsoft Entra ID |
| ③ ④ | Both send requests to Ocelot with the Entra JWT as a Bearer token |
| ⑤ | Ocelot validates the JWT and injects identity headers |
| ⑥ ⑦ | LKPS issues a scoped, short-lived LiveKit JWT |
| ⑧ ⑨ | Client and agent connect to the LiveKit Server over WebRTC |
| ⑩ | LiveKit Server sends webhook events to LKPS for session lifecycle tracking |
Zero-trust by default
No component trusts another implicitly. Every boundary requires a valid, scoped token — issued by LKPS and verified by the receiver.
Core Components¶
The platform is built from four components, each handling a distinct layer of the stack.
| Component | Role | Technology |
|---|---|---|
| Ocelot | Edge authentication and routing | Bayer reverse proxy |
| LKPS | Token orchestration, audit, and session management | Node.js / Express |
| LiveKit Server | Real-time media routing (SFU) | Open-source LiveKit |
| Bayer LiveKit SDK | Agent-side auth wrapper with credential isolation | Python |
Ocelot — Reverse Proxy¶
Bayer's in-house reverse HTTP proxy, deployed across EU and US regions. Ocelot sits in front of LKPS and handles JWT validation, identity header injection, client access lists, and TLS termination. LKPS never validates raw JWTs itself — it trusts Ocelot's injected headers for caller identity.
Each region and environment has a separate Ocelot route with a distinct hostname. The client or agent selects the region by calling the appropriate URL:
| Environment | EU | US |
|---|---|---|
| Non-Prod | eu-livekit-platform-service-np.int.bayer.com |
us-livekit-platform-service-np.int.bayer.com |
| Production | eu-livekit-platform-service.int.bayer.com |
us-livekit-platform-service.int.bayer.com |
Learn More
Ocelot Documentation ⧉ — concepts, configuration, and network architecture.
LiveKit Platform Service (LKPS)¶
The orchestration layer — a Node.js / Express service that connects identity, authorization, and LiveKit infrastructure.
What LKPS does:
- Validates caller identity from Ocelot-injected headers
- Issues scoped LiveKit JWTs for agents and clients — using server-side credentials that are never exposed
- Creates rooms with automatic agent dispatch via
RoomAgentDispatch - Persists every registration and session to PostgreSQL for audit
- Processes LiveKit webhook events to track session lifecycle
What LKPS does not do:
- Manage agent worker processes (LiveKit handles this)
- Implement custom dispatch logic or job queues (LiveKit handles this)
- Load-balance agents (LiveKit handles this)
- Control room behavior beyond token issuance
| Endpoint | Method | Purpose |
|---|---|---|
/api/agent/register |
POST |
Registers an agent and returns a scoped LiveKit JWT + server URL |
/api/session/start |
POST |
Creates a room, issues a participant token, dispatches the agent |
/api/health |
GET |
Health check (includes LiveKit connectivity status) |
/livekit/webhook |
POST |
Receives LiveKit webhook events for session lifecycle tracking |
Learn More
LiveKit Platform Service — full API reference, request/response schemas, error codes, and authentication details.
Bayer LiveKit Server¶
An open-source Selective Forwarding Unit (SFU) that handles real-time media. The LiveKit Server forwards voice, video, and data streams between participants, manages rooms, dispatches agents via RoomAgentDispatch, and sends webhook events to LKPS.
Deployed in EU and US — each region is a fully isolated instance. Developers never interact with the LiveKit Server directly. All access is mediated through LKPS-issued tokens.
Learn More
Bayer LiveKit Infra — regions, URLs, network topology, and infrastructure details.
Bayer LiveKit SDK¶
A Python package that wraps the open-source livekit-agents framework with Bayer's identity and security layer. The SDK handles Entra ID authentication, LKPS registration, token renewal, and credential isolation — so agent developers write standard LiveKit agent code without managing any infrastructure.
How the SDK replaces credential access:
| Standard LiveKit SDK | Bayer LiveKit SDK |
|---|---|
Developer sets LIVEKIT_API_KEY and LIVEKIT_API_SECRET environment variables |
Developer authenticates via Entra ID — no LiveKit credentials needed |
| Worker creates JWTs directly using admin credentials | Service creates JWTs server-side — developer receives a scoped token |
ctx.api provides full admin access to all rooms |
ctx.api is blocked — agents cannot make administrative API calls |
| Credential rotation requires coordinated update across all teams | Token auto-renews every hour — no manual rotation |
The SDK exposes 60+ plugin extras from the LiveKit ecosystem — STT, TTS, LLM, and avatar providers — installable via pip extras.
Learn More
Bayer LiveKit SDK — authentication modes, token lifecycle, migration guide, and full plugin list.
Data Flows¶
End-to-End Flow¶
The platform operates in three phases:
Phase 1 — Agent Registration (one-time, auto-renewed)
| Step | Action |
|---|---|
| 1 | Agent authenticates with Entra ID using client credentials |
| 2 | Agent receives an Entra JWT |
| 3 | Agent calls POST /api/agent/register through Ocelot with Bearer token |
| 4 | Ocelot validates the JWT and forwards with injected identity headers |
| 5 | LKPS issues a scoped LiveKit token and returns the server URL |
| 6 | Agent connects to LiveKit Server via WebSocket |
Phase 2 — Session Start (per conversation)
| Step | Action |
|---|---|
| 7 | Client authenticates with Entra ID |
| 8 | Client receives an Entra JWT |
| 9 | Client calls POST /api/session/start through Ocelot with Bearer token |
| 10 | Ocelot validates the JWT and forwards with injected identity headers |
| 11 | LKPS verifies client authorization (if enforced by the agent) |
| 12 | LKPS returns a participant token, room name, and LiveKit Server URL |
Phase 3 — Real-time Communication (WebRTC)
| Step | Action |
|---|---|
| 13 | Client joins the room using the participant token |
| 14 | LiveKit Server dispatches the agent to the room |
| 15 | Client and agent interact in real time over WebRTC (voice, video, data) |
Session Lifecycle¶
After the initial connection, LKPS tracks session state through LiveKit webhook events:
All state transitions are persisted in PostgreSQL for audit and observability.
Learn More
LKPS Webhook Reference — detailed event handling.
Security Model¶
Every component boundary enforces its own security layer. No single point of compromise grants access to the full system.
Security Boundaries¶
| Boundary | Protection | Enforcement |
|---|---|---|
| Client ↔ Ocelot | Entra ID JWT | Signature, expiry, tenant, and audience validated by Ocelot |
| Ocelot ↔ LKPS | Injected identity headers | user-id, client-id, x-bayer-user + Client Access Lists |
| LKPS ↔ LiveKit | Server-side credentials | livekit-server-sdk — credentials never leave the service |
| Client ↔ LiveKit | Scoped participant token | Bound to a single room and identity, 1-hour TTL |
| Agent ↔ LiveKit | Scoped agent token | Auto-renewed by SDK, 1-hour TTL |
| Agent ↔ LiveKit API | Blocked | SDK prevents direct ctx.api calls by design |
Token Scoping¶
| Token Type | Grants | TTL | Renewal | Scope |
|---|---|---|---|---|
| Agent token | agent, canPublish, canSubscribe, canPublishData |
1 hour | Auto-renewed by SDK (5 min before expiry) | All rooms — agent receives dispatch events |
| Participant token | roomJoin, canPublish, canSubscribe, canPublishData |
1 hour | Not renewed (single session) | Single room — bound to room name + participant identity |
Threat Mitigation¶
| Threat | Standard LiveKit Risk | Platform Mitigation |
|---|---|---|
| Credential leak | Full admin access to entire tenant | Tokens scoped to single agent/session, 1-hour expiry |
| Unauthorized room access | Any key holder can join any room | Participant tokens bound to specific room and identity |
| Agent impersonation | No identity verification for agents | Entra service principal validation at registration |
| Audit evasion | Direct API calls bypass logging | ctx.api blocked; all access mediated through LKPS |
| Credential rotation | Shared key rotation disrupts all teams | Per-identity tokens — disable one Entra app, zero impact on others |
Deployment¶
The platform is deployed across two regions. Each region is fully isolated — there is no cross-region communication.
| Region | LKPS | LiveKit Server |
|---|---|---|
| EU | eu-livekit-platform-service[-np].int.bayer.com |
eu.livekit[-np].int.bayer.com |
| US | us-livekit-platform-service[-np].int.bayer.com |
us.livekit[-np].int.bayer.com |
Pick one region and use it consistently
An agent registered with the EU LKPS instance is only available in EU. Sessions started in EU use the EU LiveKit Server. Mixing regions will fail silently.
Infrastructure Stack¶
| Layer | Technology | Notes |
|---|---|---|
| Runtime | Docker on Kubernetes | Containerized deployments with auto-scaling |
| Database | PostgreSQL (Sequelize ORM) | Agent registry, session audit, webhook state |
| Logging | Pino (structured JSON) | Correlated via x-request-id across all components |
| Secrets | Runtime injection | Developers never see production LiveKit credentials |
| Monitoring | /api/health endpoint |
Includes LiveKit Server connectivity check |
Learn More
Environments & URLs — full list of non-production and production endpoints.
Related Documentation¶
| Resource | Description |
|---|---|
| Getting Started Guide | Step-by-step setup for agent and client app developers |
| Agent Developer Guide | Build and deploy an AI agent |
| Client Developer Guide | Integrate a client application |
| Environments & URLs | Non-production and production endpoints |
| LiveKit Platform Service | Full API reference and authentication details |
| Bayer LiveKit SDK | SDK architecture, plugins, and migration guide |
| Bayer LiveKit Infra | Regions, network topology, and infrastructure |