Skip to content

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

LiveKit Platform Service Architecture

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

Bayer LiveKit SDK Architecture

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

End-to-end flow — agent registration, session start, and real-time communication

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:

LiveKit webhook session lifecycle

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.


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