Header Logo

OAuth vs API Keys for Realtime AI Avatars in Customer Support Widgets

OAuth vs API Keys for Realtime AI Avatars in Customer Support Widgets

OAuth vs API keys for realtime AI avatar widgets: backend-minted short-lived grants, browser auth trade-offs, and secure session design.

Introduction


If you are embedding a realtime AI avatar into a customer support widget, the first security decision is usually not “which model?” but “how do we authenticate the browser?” API keys are simple, but they are also a terrible fit for untrusted clients. OAuth is better at delegating user-specific access, but it adds flow complexity and is not always what you want for a widget that should just render a session and stream media.


This post explains when API keys are appropriate, when OAuth is the better choice, and how to reason about auth in a WebRTC-style avatar system where the browser is exchanging short-lived session state, audio, and video with your backend. By the end, you should be able to choose an auth model for your support widget, understand the security trade-offs, and know where a managed embed can remove the browser-auth problem entirely.


What the browser is actually doing


A realtime avatar widget is not a normal REST client. The browser usually needs to:


  • open or join a live session,

  • send microphone audio,

  • receive synchronized video and audio back,

  • possibly exchange small control messages such as persona, language, or tool events.


In practice, that means you are dealing with ephemeral realtime sessions over streaming transport, not a single request/response call. The security model should reflect that. A long-lived credential in the browser can be abused to create sessions, burn usage, or impersonate other users. A short-lived session token or a server-mediated flow is much safer.


That is the main reason API keys and OAuth behave differently here:


  • API keys identify your application or backend.

  • OAuth access tokens identify a user and an authorization grant.


For a support widget, you usually do not want the browser to hold either one unless the token is narrow, short-lived, and disposable.


API keys: good for servers, bad for browsers


API keys are the simplest way to authenticate machine-to-machine calls. They are ideal when your backend creates avatars, provisions sessions, or queries usage from a trusted environment.


For example, a backend can create an avatar or start a session using a bearer key against a REST API:


curl https://api.protoface.com/v1/sessions \
}'
curl https://api.protoface.com/v1/sessions \
}'
curl https://api.protoface.com/v1/sessions \
}'


That pattern is fine because the secret stays server-side. The browser never sees the key. If you use the Python SDK, the same rule applies: instantiate it in your backend service, not in client code.


from protoface import Client

)
from protoface import Client

)
from protoface import Client

)


The upside of API keys is operational simplicity. The downside is also simplicity: if a key leaks, it usually grants broad access until you rotate it. That is manageable for backend services, but unacceptable in frontend JavaScript. In a customer support widget, placing an API key in the browser means anyone can inspect it, replay it, and potentially create sessions on your behalf.


So the rule is straightforward: use API keys only on trusted infrastructure. If a credential crosses the browser boundary, treat it as public.


OAuth: better identity, but usually more than you need


OAuth is useful when the widget should act on behalf of a logged-in end user, or when you need fine-grained access to a user’s data or organization context. It gives you a way to delegate permissions without exposing a master credential. That matters if your avatar session needs to read account-specific history, tickets, or entitlements.


But OAuth is not a free win for realtime avatars. You still need to decide what the access token can do. A user access token may prove identity, but you generally do not want to let that token directly create arbitrary realtime sessions, especially if session creation has billing implications or resource limits. In other words: OAuth can authenticate the user, but you still need authorization logic on your backend to decide what that user may start.


For a support widget, the common pattern is:


  1. User logs into your app with your normal auth system.

  2. Your backend validates the user and their tenant/org.

  3. Your backend creates a narrow, short-lived session grant for the widget.

  4. The browser uses that grant only to connect to the live avatar session.


This keeps OAuth where it belongs: user identity and delegated app access. The avatar session itself remains a separate, tightly scoped capability.


The practical pattern: backend-minted session grants


The cleanest architecture for customer support is usually neither “browser API key” nor “browser OAuth token directly talking to the avatar API.” It is a backend-mediated exchange.


Flow:


  1. The page loads a lightweight widget.

  2. The browser authenticates to your app, not to the avatar service.

  3. Your backend checks tenant, plan, rate limits, and whatever business rules matter.

  4. Your backend creates a realtime session using its server-side API key.

  5. Your backend returns only the minimal session information the browser needs.


This pattern gives you a few important properties:


  • Secret isolation: only your backend sees the API key.

  • Least privilege: the browser gets one short-lived capability, not a master secret.

  • Auditable authorization: you can attach tenant IDs, user IDs, plan state, and session metadata server-side.

  • Operational control: you can revoke, throttle, or refuse sessions without changing frontend code.


For widgets specifically, short-lived session grants are the difference between “somebody copied my JS bundle” and “somebody temporarily joined one session.” That is the level of blast-radius reduction you want.


Why realtime media changes the threat model


Realtime AI avatars are stateful and billable. A leaked credential is not just a data-access problem; it is a usage and abuse problem. An attacker with a key or a token may be able to:


  • spin up sessions repeatedly,

  • consume compute and media bandwidth,

  • attach arbitrary instructions or personas,

  • probe tenant boundaries,

  • inflate usage in a way that is hard to spot immediately.


That is why auth for realtime systems should be judged by two questions:


  1. Can this credential be limited to one narrow action?

  2. Can it be made short-lived enough that browser exposure is tolerable?


API keys usually fail the first test in the browser. OAuth often fails the second unless you introduce a backend exchange step. The backend exchange step is usually the right answer.


Where Protoface fits naturally


Protoface is useful here because it cleanly separates server-authenticated control-plane operations from browser-facing session delivery. The REST API and Python SDK are the parts you use from trusted backend code to create avatars and realtime sessions. Your application keeps the API key, and the browser gets only the minimum state required to join the session.


That makes the architecture for a support widget straightforward: create the session server-side, then hand the frontend a short-lived session reference or embed URL. If you want to avoid exposing any backend credential in the browser at all, the customer-managed iframe embed is the other practical path. In that setup, you do not ship an API key to the client; instead, the embed enforces origin allowlists and supports per-embed voice, custom instructions, and rate limits.


If you are implementing the server side yourself, the docs are the right place to confirm the exact session fields and request shape: docs.protoface.com. For a Python backend, the SDK is the fastest way to wire this up without hand-rolling HTTP calls: github.com/protoface-ai/protoface-sdk-python.


How to choose: OAuth vs API keys


Here is the pragmatic decision tree I would use for a customer support widget:


  • Use an API key on the backend when your service creates sessions, manages avatars, or reads usage for your own tenants.

  • Use OAuth for end-user login when the avatar needs user-specific data or must honor user identity inside your app.

  • Do not put API keys in the browser unless they are not actually secrets and have extremely tight scope and lifetime.

  • Do not rely on OAuth alone if the browser can directly create expensive or privileged realtime sessions.

  • Prefer backend-minted short-lived grants for the browser-facing part of the flow.


If you already have an OAuth system, it is common to combine it with a server-side session minting step. OAuth authenticates the user; your backend authorizes the action; the avatar service receives a narrowly scoped, ephemeral session.


Common gotchas


A few mistakes show up repeatedly in realtime avatar integrations:


  • Shipping a service key to the frontend. Minified JavaScript is not protection.

  • Confusing user auth with service auth. A user being logged in does not mean they should be able to create unlimited live sessions.

  • Making tokens too long-lived. Realtime widgets benefit from minutes, not days.

  • Skipping rate limits. Even a valid credential can be abused.

  • Ignoring origin controls for embeds. If the browser is allowed to host the widget, make sure only approved sites can use it.


Also remember that a realtime avatar is part media pipeline, part application logic. Auth protects not just an API endpoint but an active session with ongoing compute cost. That is why authorization should happen before session creation, not after the fact.


Conclusion


For realtime AI avatars in customer support widgets, the right answer is usually not “OAuth or API keys” so much as “OAuth for user identity, API keys for trusted backend control, and short-lived browser grants for the live session.” API keys belong on servers. OAuth belongs at the user boundary. The browser should receive the smallest possible capability.


If you are building this yourself, start with backend session creation and keep the frontend credential-free. If you want the managed path, read the implementation details in the docs and follow the quickstarts linked from the project README on GitHub. The important part is not the exact library; it is preserving the trust boundary between your backend and the browser.


For reference material, start with docs.protoface.com and the relevant SDK or integration repo on GitHub.

Add a face to your AI.

No credit card needed.

Add a face to your AI.

No credit card needed.

Add a face to your AI.

No credit card needed.