Never send your real API key to the browser. Your server holds the key and mints a short-lived ephemeral token per session; the game’s client-side JavaScript uses only that token, which expires quickly and limits damage if it leaks.
At a glance
| Fact | Value | Source |
|---|---|---|
| OpenAI Realtime uses ephemeral client secrets | minted server-side | developers.openai.com |
| Browser gets SDP offer exchanged via server | server holds project key | platform.openai.com |
| GitHub scans repos for committed secrets | full git history, all branches | docs.github.com |
Ephemeral tokens work by never letting the browser see your real API key. Your own server (or a serverless function) holds the long-lived key and calls the AI provider’s API to mint a short-lived credential scoped to one session. Your game’s JavaScript receives only that credential and uses it to talk to the AI service directly – for OpenAI’s Realtime API, the application server creates an ephemeral client secret for the Realtime session, and the browser connects over WebRTC using that secret, never the underlying project key. Because the token expires quickly, a player who inspects network traffic or browser memory only ever finds a credential with a short life, not one that keeps working indefinitely.
If you are developing your browser game with an AI coding agent like Claude Code or Cursor, the Playgama MCP server connects your agent directly to the developer cabinet to upload builds and publish a test sandbox.
This matters for browser games specifically because your entire client is downloadable source: anyone can open devtools, view the page source, or unzip an itch.io/CrazyGames/playgama.com build and read every string in it. API credentials in client-side code are vulnerable to extraction attacks, and obfuscation does not fix this – the fix is architectural: the real key never ships to the client at all.
How do you implement ephemeral client tokens?
- A thin backend endpoint that holds the real key as a server secret (e.g. a Cloudflare Worker secret, not a hardcoded value) and returns an ephemeral token per request.
- Client code (in a .jslib for Unity, or JavaScriptBridge for Godot) that calls only your backend and the ephemeral endpoint, never the provider directly with the real key.
- Short session lifetimes, and a header on the server-side minting request to associate an identifier with the session, so you can track and revoke abuse per player.
Sources
- Getting started with the Realtime API | OpenAI
- WebRTC | OpenAI API
- Best practices for securely using API keys – API Console Help
- The Comprehensive Guide to Sharing and Storing API Keys Securely
- Secrets – Cloudflare Workers docs
- About secret scanning – GitHub Docs
- Playgama Bridge SDK – getting started
Related questions
Can I just obfuscate the API key in my browser game instead?
No. Obfuscation does not stop extraction attacks; client-side code, including obfuscated code, can be read and the key extracted by anyone inspecting the build.
Where should the real, long-lived API key live?
On a server you control – an environment variable, a Cloudflare Worker secret, or similar – outside the application’s source tree, never in files shipped to the browser.
Does an ephemeral token remove the need for a backend server?
No. A server (or serverless function) must still mint the ephemeral token per session; the browser never calls the provider with the long-lived key directly.
Last updated: 30 September 2026