How to Pass User Identity Safely to a Conversational Interview Avatar Without Exposing API Keys

Learn how to pass user identity to a conversational avatar via server-issued sessions, without exposing API keys or secrets.
Introduction
When you add a conversational avatar to a product, one of the first design questions is: how do you carry the user’s identity into the avatar session without leaking credentials? The common mistake is to let the browser talk directly to the avatar API with a long-lived key, then try to “just attach” a user ID on top. That works until someone inspects network traffic, copies your key, or reuses it from another origin.
The safe pattern is simpler: keep API keys on your server, mint a short-lived session on behalf of the signed-in user, and pass only non-secret identity data to the avatar layer. By the end of this post, you should be able to design that flow cleanly, decide what belongs in the browser versus the backend, and avoid the most common identity and authorization mistakes when integrating a realtime interview avatar.
Separate authentication, authorization, and avatar identity
These are related but not the same thing:
Authentication proves who the user is to your app. Usually this is your normal session cookie, OAuth token, or JWT.
Authorization decides what that user can do. For an interview avatar, that might be “can start a session,” “can join only their own interview,” or “can access this candidate-specific prompt.”
Avatar identity is the label or metadata you want the conversational system to know about the participant. This can be a user ID, candidate ID, interview ID, locale, or role.
The key principle is that the avatar service should receive identity data, not secret credentials. The avatar does not need your user’s login token. It needs enough context to personalize the conversation and tie the session to your backend records.
A good mental model is: the browser asks your backend for permission; your backend asks Protoface for a session; Protoface returns a session artifact; the browser only uses that session artifact. The browser should never see your API key.
Use your backend as the trust boundary
For a realtime avatar, the browser is inherently untrusted. Even if you use WebRTC for media and a websocket or SDK for control, the client can be inspected, replayed, or manipulated. So the server should own three things:
User verification — confirm the logged-in user is allowed to start this interview.
Session creation — call the avatar API with your secret key.
Identity binding — attach the user’s application identity to the session in a server-controlled way.
That last step is where people often overexpose data. The browser can send a candidate ID or display name to your backend, but your backend should validate it against the authenticated user and then decide what to forward. Do not accept arbitrary identity fields from the browser and blindly inject them into an upstream session request.
A practical approach is to issue a short-lived, scoped session token from your backend. The token can include:
your internal user or candidate ID
an interview or conversation ID
an expiration timestamp
optional claims like locale, plan tier, or allowed avatar template
Keep it small. Anything the avatar does not strictly need should stay in your database, not in the session payload. If the avatar needs to say “Hi, Maya,” send the display name. If it needs to know the candidate’s email, probably don’t.
Recommended flow for a safe avatar session
Here is the pattern I recommend for a browser-based interview avatar:
The user signs in to your app.
Your frontend calls your backend: “start interview session.”
Your backend verifies the user and creates a conversation/session with Protoface using its API key.
Your backend stores the mapping between your internal interview record and the Protoface session ID.
Your backend returns only the minimal session data the browser needs to connect.
If your architecture uses a LiveKit voice agent, the same pattern applies: your agent server acquires the identity context from your backend or job metadata, then starts the agent with the avatar attached. The avatar is part of the agent runtime, not a credential source.
Example: backend creates a session and returns a safe client payload
This example is intentionally generic. Exact request fields depend on the API surface you use, but the shape is what matters: the backend talks to the API; the browser never sees the bearer token.
Two important caveats:
Do not copy this payload shape into production without checking the docs; field names and returned tokens depend on the API.
Do not put your API key in frontend code, even if the UI is “internal” or behind authentication. Browser isolation is not a secret store.
Identity data: what to send, what to avoid
For an interview avatar, the useful fields are usually:
Stable internal ID — the key that joins session logs to your own database.
Display name — for personalization and greetings.
Role or persona — e.g. candidate, interviewer, observer.
Conversation context ID — interview session, support ticket, sales opportunity, etc.
Fields to avoid unless you have a clear reason:
email addresses
phone numbers
full profile objects
access tokens from your app
anything that would be sensitive if logged or stored in vendor metadata
Remember that session metadata often appears in dashboards, logs, analytics, and debugging tools. Assume it may be visible to operators and retained longer than you expect. Treat it like application-level context, not a private user record dump.
WebRTC and realtime gotchas
People sometimes assume WebRTC media transport itself solves identity. It doesn’t. WebRTC gives you low-latency media paths for audio/video, but it does not authenticate your business logic. Your control plane still needs signed, server-issued session creation and a clear mapping between your app user and the avatar session.
That distinction matters in two places:
Session establishment — only your backend should be able to mint a valid avatar session for a given user.
Mid-session control — if you need to update instructions, transfer the interview, or end the session, those actions should also be authorized server-side.
A related trap is reusing one generic session token across multiple users. Don’t do that. Sessions should be short-lived and scoped to one conversation. If the user refreshes the page or retries, create a new session or explicitly rotate the token.
Also be careful with client-visible state. If you pass the candidate’s real name into the browser to render a greeting, that is often fine. If you pass internal scoring notes or hidden interview instructions, that is not. Split what the avatar needs to speak from what only your backend or evaluation pipeline should see.
Where Protoface fits
This is exactly the kind of integration Protoface is built for: your server owns the API key, creates the avatar session, and passes only the necessary identity context into the session lifecycle. If you are wiring this into a voice agent, the LiveKit plugin and quickstarts are useful reference points for the control flow and session attachment patterns; the same trust boundary applies whether you use the REST API directly or the Python SDK. The docs at docs.protoface.com cover the concrete request/response fields and the supported session options.
If you prefer to work in Python, the SDK keeps the same model: call it from trusted server code, not from the browser.
And if your app is built around a LiveKit voice agent, the relevant pattern is the same: the agent process receives the user context from your backend, then attaches the avatar as part of the realtime session setup. The avatar becomes the face of the agent, not a separate trust domain.
Practical checklist before shipping
Keep all Protoface API keys on the server.
Create sessions only after your app has authenticated the user.
Pass minimal identity metadata, not full profile records.
Bind each session to a single interview or conversation ID.
Use short-lived sessions and rotate on retry or reconnect.
Log session IDs in your backend so you can debug without exposing secrets.
Review what lands in dashboards and analytics before adding new metadata fields.
Conclusion
Safely passing user identity to a conversational avatar is mostly about respecting boundaries: browser for presentation, backend for trust, avatar service for realtime media and session state. If you keep API keys off the client and only forward minimal, server-validated identity data, you can personalize the experience without creating a credential leak or an authorization bug.
For implementation details, session fields, and current examples, start with the docs. If you want to see the broader developer surface and quickstarts, the GitHub examples are a good next stop, especially if you are wiring an avatar into a voice agent or a realtime web flow.
