Header Logo

Designing a Zero-Trust Architecture for Interactive AI Avatars on Public Kiosks and Displays

Designing a Zero-Trust Architecture for Interactive AI Avatars on Public Kiosks and Displays

Zero-trust architecture for AI avatars on public kiosks: ephemeral sessions, origin allowlists, server-side policy, and no browser keys.

Introduction


Public kiosks and displays are a hostile environment by default. The browser is visible to everyone, the device may be physically accessible, the network is untrusted, and the application often needs to talk to a realtime AI backend that can stream audio, video, and text. If you put an interactive avatar on a kiosk without a strong trust boundary, you eventually leak credentials, allow prompt abuse, or give the local user a path to pivot into your backend.


This post is about designing that boundary correctly. By the end, you should be able to reason about which parts of an avatar system can run in the browser, which parts must stay server-side, and how to build a zero-trust kiosk deployment that supports realtime voice interaction without exposing long-lived secrets.


Start with the threat model, not the UI


For public displays, assume the following are true:


  • The browser is not trusted. Anyone can inspect DOM, network traffic, and local storage.

  • The device may be rebooted, tampered with, or used by many users in sequence.

  • The kiosk network may be monitored or proxied.

  • The avatar backend must tolerate untrusted inputs and adversarial prompts.


That means the main goal is not “hide the frontend.” It is to ensure the frontend never receives credentials or privileges that outlive a single interaction.


In practice, zero trust for an avatar kiosk means three things:


  1. Use short-lived, scoped session credentials.

  2. Keep privileged API access off the browser entirely.

  3. Constrain what the kiosk can connect to, speak as, and do per session.


If you get those right, the public display becomes a thin rendering surface, not a control plane.


Separate control plane from data plane


The cleanest mental model is to split the system into a control plane and a data plane.


Control plane responsibilities:


  • Create or authorize sessions.

  • Choose the avatar, voice, and instructions allowed for that session.

  • Enforce origin, IP, and duration limits.

  • Track usage and revoke access.


Data plane responsibilities:


  • Stream audio/video in realtime.

  • Carry user utterances to the agent and responses back to the display.

  • Render the avatar in the browser or in the agent pipeline.


For kiosks, the control plane should be server-side only. The browser should receive at most an ephemeral embed/session token that cannot be used to call your management APIs. Never ship a long-lived API key to a public device, even “temporarily.” If the browser can reach the management API, assume the key is compromised.


Session design for hostile browsers


There are a few practical rules that make kiosk deployments much safer:


  • Per-session credentials only. Session tokens should be mintable server-side and valid only for the intended interaction window.

  • Origin allowlists. If the avatar is embedded in a page, restrict which parent origins are allowed to mount it.

  • Bounded lifetime. Enforce session expiration even if the kiosk page never closes.

  • Rate limits. Apply per-IP and per-embed limits so one device cannot consume infinite usage.

  • Strict content boundaries. Treat user text as input to the agent, not as instructions for the kiosk runtime.


A subtle but important point: the kiosk browser is usually less trusted than the human standing in front of it. That means the browser should not decide which avatar to load, which voice to use, or how much access it has. Those choices belong in your backend policy layer.


Also avoid putting secrets in localStorage or query strings. If you must hand a token to the browser, use the narrowest possible scope and expiration, and assume it will be observed.


Realtime transport: what actually needs to stay authenticated


Interactive avatars usually involve two streams moving in parallel: a realtime media stream and a control channel. The media path carries audio and synthesized or generated video frames; the control path negotiates session state, selected avatar, and policy. In WebRTC-style setups, media is peer-to-peer or relayed through a server, but the session establishment still depends on authenticated signaling.


The important security distinction is that media packets are not the same as management actions. A kiosk may be allowed to receive a media stream for a single session while being forbidden from creating new avatars, rotating keys, or reading usage history. If you collapse those two planes into one API, you lose the ability to apply least privilege.


A good operational pattern is:


  1. Your backend authenticates the human user or device.

  2. Your backend asks the avatar service to create a short-lived session.

  3. The browser receives only the session artifact needed to join that interaction.

  4. When the session ends, the token expires and cannot be replayed.


If you are integrating with a voice agent, this also means your agent runtime should own the avatar attachment, not the kiosk page itself. The browser should not be deciding how to synthesize speech or when to escalate to another model; it should just render the outcome of an already-authorized session.


Policy enforcement for public kiosks


Zero trust is mostly policy enforcement in code. For public kiosks and displays, the policy should be boring and explicit:


  • Allowed origins: only your kiosk domain(s) or embed hosts.

  • Allowed IP ranges: if the kiosk fleet is known, constrain by network where feasible.

  • Session duration: hard cap on how long a session can remain active.

  • Avatar scope: a kiosk session should only access the avatar it was issued.

  • Instruction scope: per-embed or per-session instructions should be immutable from the client.


That last one matters more than it seems. If the client can alter the system prompt or session instructions, a public kiosk becomes a prompt-injection amplifier. The kiosk can still accept user questions, but the policy that defines the assistant’s behavior must remain server-controlled.


You also want observability. At minimum, log session creation, origin, IP, session duration, and termination reason. For kiosk incidents, you need to know whether misuse was due to a stolen token, a bad origin policy, or an overly permissive session scope.


Where Protoface fits: managed embeds without exposing API keys


For browser-first kiosk experiences, the safest pattern is to keep the browser on a short leash and let the server mint whatever the browser needs. The customer-managed iframe embed model is designed for that: you can add an interactive avatar to a website with an iframe, keep the backend out of the browser, and never expose an API key client-side. The iframe can enforce parent-origin allowlists, per-embed voice and custom instructions, and per-IP or duration limits, which maps well to public displays.


If you are building from the server side instead of an embed, use the management API to create sessions and keep the key on your backend. A minimal request looks like this:


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


The exact fields depend on the endpoint version, so use the documentation for the authoritative schema. The key point is that the browser should receive only the session artifact, never the management credential. See the docs at docs.protoface.com for the current API and embed details.


If you are integrating a voice agent rather than a pure web embed, the LiveKit plugin path is often the right architecture: your agent runtime owns the realtime session and the avatar is attached as part of the agent pipeline. That keeps the kiosk page dumb and pushes authentication, policy, and media handling into controlled server components. The relevant plugin and examples live in the GitHub org, and the Python SDK is useful when you want to provision sessions programmatically from your backend.


A practical deployment checklist


If you are shipping this to real kiosks, use a checklist like this before rollout:


  • Store API keys only on backend hosts or secret managers.

  • Issue short-lived session tokens with tight scope.

  • Pin allowed parent origins for any embed surface.

  • Set a hard session TTL and revoke on disconnect or inactivity.

  • Restrict per-IP usage for public devices and shared networks.

  • Log session creation and termination for auditability.

  • Test prompt injection and malformed input against the agent, not just the UI.

  • Assume the kiosk browser can be inspected and replayed.


The design principle is simple: the public device renders a session; it does not own identity, policy, or credentials.


Conclusion


Designing a zero-trust architecture for interactive AI avatars on public kiosks comes down to one rule: treat the browser as untrusted infrastructure. Keep management APIs server-side, issue only ephemeral session credentials, constrain origin and network access, and make policy immutable from the client. Do that, and you can safely add realtime avatars to kiosks without turning them into a privilege-escalation problem.


If you want to implement this pattern, start with the docs at docs.protoface.com, then choose the integration surface that fits your architecture: embed for browser-first deployments, REST for backend-driven session control, or the agent/plugin path if the avatar belongs inside your voice stack.

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.