Skip to content

Security and governanceGuide

AI API keys in frontend and mobile apps: what to do instead

Shipping an OpenAI or Gemini key inside a React bundle or an Android app hands it to every user who looks. Obfuscation does not change that. Here are the four patterns that keep the key on a server, with what OpenAI, Google and Firebase document for each.

By INFRO Editorial

Published

8 min read

An amber key inside a glowing glass hexagon on a dark ground, ringed by dashed orbits and small glass nodes

In short

An API key in a browser bundle or a mobile binary can be read by anyone who has the app, so treat it as public. Keep provider keys on a server: route requests through your own backend that authenticates each user and caps what they can spend; for realtime voice, mint short-lived client secrets on the server (OpenAI Realtime client secrets, Gemini Live ephemeral tokens); for Gemini in mobile apps, Firebase AI Logic keeps the key server-side and App Check attests the app. Then cap spend per end user.

Key takeaways

  • Any key that ships to a browser or a phone is public: it can be read from the bundle, the binary or the network traffic, and obfuscation only slows that down.
  • The OpenAI and Anthropic TypeScript SDKs refuse to run in a browser unless you set dangerouslyAllowBrowser, because it exposes the key.
  • Put provider keys behind your own backend that authenticates each user, fixes the model and limits, and caps spend per user.
  • For realtime voice, mint short-lived credentials on the server: OpenAI Realtime client secrets expire in 10 seconds to 2 hours, Gemini Live ephemeral tokens in 30 minutes by default.
  • For Gemini in mobile apps, Firebase AI Logic keeps the key on Google's side and App Check attests the calling app; App Check enforcement becomes required on 2026-11-02.

Can you put an AI API key in a frontend or mobile app? No. A key in a browser bundle or a mobile binary is public: anyone with the app can read it from the code, the binary or the network traffic, and use it on your provider account until you revoke it. Keep provider keys on a server. Have the app call your backend with the user's own session, mint short-lived credentials on the server where the client must talk to the provider directly (realtime voice), use attestation such as Firebase App Check where the platform offers it, and cap what each user can spend.

This guide explains why hiding techniques fail, then walks through the four patterns that work, with what OpenAI, Google and Firebase document for each.

Why a shipped key is a public key

A browser or a phone has to send the key with each request, so the key exists in plaintext on the device at that moment. Environment variables in a React, Vue or Next.js client build are inlined into the bundle at build time; the network tab shows the Authorization header; an Android package can be unpacked and searched for strings. Obfuscation moves the key around but cannot remove it.

The SDK authors agree. The OpenAI and Anthropic TypeScript SDKs disable browser use by default "to avoid exposing your secret API credentials", and only run there if you set dangerouslyAllowBrowser to true12. OpenAI's README says enabling it "exposes your secret API credentials in the client-side code"1. Google's Gemini key page says never to expose keys client-side in production or hardcode them in web or mobile apps, because they can be extracted, and to call the API through a backend3. OWASP's Mobile Top 10 lists hardcoded credentials in app code or configuration files as "a clear indicator of vulnerability" under M1, Improper Credential Usage, and recommends revocable access tokens instead4.

This is not a hypothetical. In April 2026 CloudSEK scanned the top 10,000 Android apps and found 32 live Google API keys across 22 apps with a combined install base above 500 million that worked against the Gemini API; for one language-learning app, the key listed files in Gemini's Files API that included users' speech recordings5. The keys had been embedded for Maps or Firebase, where Google's documentation once said that was fine, and gained Gemini access when the Generative Language API was enabled in the same project5. Google API keys and Gemini exposure covers that case in depth.

A key on a device exposes three things: spend (anyone can run inference on your account), data (stored files, responses or fine-tuning data the key can read), and your standing with the provider (abuse on your key is abuse by your account; see why providers suspend accounts).

Four patterns that keep the key off the device

PatternKey on device?Best forWhat you still build
Your backend as the proxyNoChat, completions, images, anything request/responseUser auth, per-user limits, fixed model and parameters
Short-lived client secretsA credential that expires in minutesRealtime voice and video over WebRTC or WebSocketsA server endpoint that authenticates the user, then mints
Platform proxy plus attestationNo provider key; an attestation tokenGemini in mobile and web apps via FirebaseApp Check setup, per-user rate limits
Per-user capsNot applicableEvery pattern aboveA user id on every request and a cap per user

1. Your backend is the proxy

The app authenticates the user with your normal session (cookie, OAuth token, Firebase Auth), calls your endpoint, and your server calls the provider with a key that never leaves the server. This is the default for anything that is not realtime.

A backend that forwards whatever the client sends is only a slower way of publishing the key. Decide on the server:

  • Which model and parameters. Fix the model, max_tokens, tools and system prompt server-side; never accept a model name or a raw message list from the client without checking it.
  • Who may call. Refuse unauthenticated requests; rate-limit by user, not only by IP.
  • How much each user may spend. A per-user daily ceiling turns one abusive account into a bounded cost. Stopping your AI feature becoming a free LLM proxy covers the abuse patterns.
  • What reaches logs. Prompts from users are user data; apply your prompt logging policy.

2. Short-lived client secrets for realtime

Realtime voice wants the client to connect to the provider directly, because relaying audio through your server adds latency. Both OpenAI and Google document the same shape: the server authenticates the user, mints a short-lived credential with its own key, and hands only that to the client.

OpenAI Realtime. The browser asks your server for a token; your server calls POST https://api.openai.com/v1/realtime/client_secrets with its standard API key and returns the result; the browser uses it to open a WebRTC session6. The returned value looks like ek_… and carries an expires_at; expires_after.seconds accepts 10 to 7,200 seconds and defaults to 6007. OpenAI recommends setting the OpenAI-Safety-Identifier header on the server request that creates the secret, so the identifier is bound to the token and the browser does not need to send it6. An alternative keeps the key and token entirely server-side: the browser sends its SDP offer to your server, which posts it to /v1/realtime/calls with the standard key6.

Mint a Realtime client secret on your server
curl -X POST https://api.openai.com/v1/realtime/client_secrets \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Safety-Identifier: $HASHED_USER_ID" \
  -H "Content-Type: application/json" \
  -d '{"expires_after": {"anchor": "created_at", "seconds": 60}}'

Gemini Live. Ephemeral tokens are in preview, work only with the Live API on v1beta, and by default allow one minute to start a session and 30 minutes to use it; uses: 1 limits a token to one session, and liveConnectConstraints locks the model and configuration so the client cannot change the system instructions8. Google is direct about the limit: ephemeral tokens "can be extracted from client-side applications", and their value is that they expire quickly and can be restricted8.

A short-lived credential is only as good as the check before it is minted. If your mint endpoint hands a token to anyone who asks, an attacker calls the endpoint instead of stealing the key.

3. A platform proxy with app attestation

For Gemini in mobile and web apps, Firebase AI Logic puts Google's proxy between the app and the Gemini API so that, in Firebase's words, "your Gemini API key stays on the server and is not embedded in your apps' codebase"9. It applies per-user rate limits by default, and they are configurable9.

The proxy alone would still serve any client that copies the app's configuration. App Check closes that: with enforcement on, the proxy accepts only requests "verified to be from your actual app and/or an untampered device"10. Attestation comes from Play Integrity on Android, DeviceCheck or App Attest on Apple platforms, and reCAPTCHA Enterprise on the web; limited-use tokens with a fixed five-minute lifetime can be used once each for replay protection10. Two dates matter: since early July 2026 the console enforces App Check automatically for new setups, and from 2026-11-02 App Check enforcement is required to use Firebase AI Logic10.

Attestation raises the cost of abuse; it does not identify your users. Pair it with signed-in users and per-user limits.

4. Cap spend per end user

Every pattern above still lets a legitimate-looking user spend. The control that bounds that is a cap per end user, checked before the provider is called, so one account, one script or one compromised session cannot run up the whole month. Pass a stable, opaque user id with every request (never an email address), and refuse requests over the user's cap with a clear error your app can show.

A pre-release checklist

  • Search the built bundle and the compiled app for provider key prefixes (sk-, sk-proj-, sk-ant-, AIza) before every release.
  • No dangerouslyAllowBrowser: true in production code.
  • Every Google API key embedded in an app (Maps, Firebase) is restricted, and the Generative Language API is not enabled in that project unless intended.
  • The backend fixes model, parameters and tools; the client cannot choose them freely.
  • Every AI endpoint requires a signed-in user and has a per-user rate limit and spend cap.
  • Ephemeral credential endpoints authenticate before minting and use the shortest lifetime that works.
  • A provider-side spend limit exists on the project or workspace the server key belongs to.
  • You know how to revoke the server key in minutes; see secure LLM API keys.

How INFRO handles client-facing AI features

INFRO sits behind your backend, not in the client. An INFRO gateway key (sk_infro_) is a secret like any provider key and belongs on your server, never in a bundle or an app. With your backend calling INFRO:

  • End-customer caps limit spend per end user, from the Team plan. Your server sends your opaque user id in metadata.user_id (or X-INFRO-User-Id), a default rule caps every user, overrides change it for one, and a request over its cap is refused with 402 before your provider is called.
  • Model allowlists stop a request for a model the feature should not use, with 403 model_not_allowed.
  • Gateway key controls limit the key to the providers and environment the feature needs, and an IP allowlist set to your backend's egress addresses refuses a copied key used elsewhere with 403 ip_not_allowed.
  • Budgets on the key and project give the feature a hard ceiling, and guardrails on the Business plan can redact emails, card numbers and API keys users paste into prompts.

One limit to state plainly: INFRO governs requests that go through INFRO. If a provider key is ever shipped to a device or stolen from anywhere, it can be used directly against the provider and none of these controls see it. Keep a spend limit and usage monitoring at the provider as well, and revoke there first.

Summary

There is no safe way to ship a provider key in a frontend or mobile app. Keep keys on a server; authenticate users and fix model and limits there; for realtime, mint short-lived client secrets after checking the user; for Gemini on mobile, use Firebase AI Logic with App Check enforced; and cap spend per user so a single account cannot become your largest customer.

Questions readers ask

Can I hide an OpenAI API key in a React app with environment variables?
No. Build tools inline environment variables into the JavaScript bundle, and the browser sends the key on every request, so anyone can read it in developer tools. Call OpenAI from your own server, and have the browser call your server with the user's session.
Is it safe to put an API key in an Android or iOS app if I obfuscate it?
No. Obfuscation slows extraction down, but the app must present the real key at request time, so it can be recovered from the binary or the network traffic. OWASP lists hardcoded credentials as a clear sign of the top mobile risk. Use a backend, or for Gemini, Firebase AI Logic with App Check.
How does the browser connect to the OpenAI Realtime API without exposing my key?
Your server uses its standard API key to call POST /v1/realtime/client_secrets and returns the short-lived client secret to the browser, which uses it to open the WebRTC session. The secret expires after 10 minutes by default, configurable from 10 seconds to 2 hours.
Are ephemeral tokens safe to expose?
Safer, not safe. Google notes that ephemeral tokens can be extracted from browsers and apps just like keys; they limit the damage because they expire quickly and can be locked to one model and configuration. Your server must still authenticate the user before minting one.

From the team that builds it

Where this shows up in INFRO

INFRO is a control plane in front of the provider accounts you already hold. The capabilities below are the parts of it this article touches, each with the documentation that defines its behaviour.

  • Key limits and rotation

    Available with a plan

    Limit a gateway key to chosen providers or IP ranges, and rotate it with an overlap window so the old key keeps working while you deploy the new one.

    Read the documentation for Key limits and rotation
  • End-customer spend caps

    Available with a plan

    One spend cap for every end customer of your product, per organization or per project, with overrides your backend sets through the management API. A refused request returns a 402 with the time the cap resets, for your app to show its user. Caps from the Team plan; the per-customer cost view on every plan.

    Read the documentation for End-customer spend caps
  • Budgets and spend ceilings

    Available with a plan

    A hard cap per organization, project, member, and key, with alerts at your own thresholds.

    Read the documentation for Budgets and spend ceilings
  • Model allowlists

    Available with a plan

    Approve which models a project may call; anything else returns a policy error instead of a line item.

    Read the documentation for Model allowlists
  • Guardrails

    Available with a plan

    Pattern-based checks on chat completion prompts and responses: block, redact or flag email addresses, phone numbers, card numbers, IBANs, US Social Security numbers, IP addresses, API keys and your own terms, plus optional classifier checks on your own connection to a decision model's provider. Detection can miss things. Included from the Business plan.

    Read the documentation for Guardrails
  • Environments

    Available with a plan

    Production, staging and development to start, and your own beside them. A connection or route serves one, several or every environment; each gateway key belongs to exactly one, and never reaches a connection outside it.

    Read the documentation for Environments

INFRO accounts are self-serve. Provider usage is billed to you by your providers; INFRO charges a software subscription and takes 0% of model spend. See plans.

Sources

Numbered in order of first citation. Each was opened and checked against the claim on the date shown.

  1. 1.openai/openai-node README (opens in a new tab) — GitHub. Accessed Oct 21, 2026.
  2. 2.anthropics/anthropic-sdk-typescript README (opens in a new tab) — GitHub. Accessed Oct 21, 2026.
  3. 3.Using Gemini API keys (opens in a new tab) — Google AI for Developers. Accessed Oct 21, 2026.
  4. 4.M1: Improper Credential Usage (opens in a new tab) — OWASP Mobile Top 10. Accessed Oct 21, 2026.
  5. 5.Hardcoded Google API Keys in Top Android Apps Now Expose Gemini AI (opens in a new tab) — CloudSEK. Accessed Oct 21, 2026.
  6. 6.Realtime API with WebRTC (opens in a new tab) — OpenAI. Accessed Oct 21, 2026.
  7. 7.Create client secret (Realtime) (opens in a new tab) — OpenAI API reference. Accessed Oct 21, 2026.
  8. 8.Ephemeral tokens (opens in a new tab) — Google AI for Developers. Accessed Oct 21, 2026.
  9. 9.Gemini API using Firebase AI Logic (opens in a new tab) — Firebase. Accessed Oct 21, 2026.
  10. 10.Implement Firebase App Check for Firebase AI Logic (opens in a new tab) — Firebase. Accessed Oct 21, 2026.

About this article

On 2026-10-21 we opened OpenAI's Realtime WebRTC guide and client secrets API reference, Google's Gemini API key and ephemeral token documentation, Firebase AI Logic's overview and App Check pages, the OpenAI and Anthropic TypeScript SDK READMEs, OWASP's Mobile Top 10 M1 page and CloudSEK's April 2026 research on keys in Android apps. INFRO behaviour is described from its public documentation. Written by the team that builds INFRO.

Last checked against its sources on . The next review is due by . No separate named reviewer is recorded for this article.

How articles are written, sourced and corrected is set out in the editorial standards.