Guide · Security
How to Secure API Keys in JavaScript Frontend
API keys in frontend code are never secure. Here's how to architect your app so keys stay server-side and your frontend stays safe.
Browser-exposed keys fail Secrets Management—proxy through a backend and keep credentials server-side. Primary control: Secrets Management
Browser JS is a hostile environment for secrets
Anything shipped to the client can be read—DevTools, source maps, bundle scraping. Putting OpenAI, Stripe, or cloud keys in frontend code (including `NEXT_PUBLIC_` env) is publishing them. One React app called OpenAI from the client with a `NEXT_PUBLIC_` key; scrapers found it and ran ~$12k before anyone noticed.
The only safe pattern: your API owns the key
Expose `/api/chat` (or similar) from your server. The browser sends a session/user token; the server holds `OPENAI_API_KEY` (never `NEXT_PUBLIC_`). Enforce per-user auth and quotas on that route. If a key ever lived in a client bundle, rotate it immediately and scrub git history / old deploys.
Secrets custody is an APRF gate
APRF Secrets Management and Authentication assume credentials never ship to the browser. "It worked in the tutorial" is not a control.
Next: Secrets Management
Open the related pillar specification for mandatory checks, artifacts, and pass conditions. Self-attest is optional.
Related
Frequently asked questions
- Can I use API keys in React or Next.js frontend?
- No. Any key in client-side JavaScript can be extracted. Use a backend API route or serverless function to hold the key and proxy requests from your frontend.
- What is the safest way to call OpenAI from a frontend?
- Create a backend endpoint that receives the user's prompt, calls OpenAI with your server-held key, and returns the response. The frontend never touches the key.
- How do I secure API keys in Next.js?
- Never use NEXT_PUBLIC_ for secrets. Use env vars without that prefix—they're only available server-side. Put API calls in API routes or server components.