Guides / Prompting and shipping

How to Keep API Keys Safe in Your App

Keep API keys out of your code, browser and chat: store them as secrets, use them only on the server, restrict them, and rotate any key that leaks.

Mythex Team · 2026-09-29 · 6 min read

To keep API keys safe, store them as secrets or environment variables on your host, use them only in server-side code, and never paste them into chat, code files, screenshots or a Git repository. Give each key the least permission it needs, set spending limits at the provider, and if a key ever leaks, rotate it — create a new one and delete the old — rather than just hiding where it appeared.

An API key is a password for a service. Your OpenAI key lets someone spend your money on AI; your Stripe secret key lets someone issue refunds; your email provider key lets someone send mail as you. AI app builders are good at wiring these in and not always careful about where they end up, so this guide covers how to keep them safe and how to check.

Public keys vs secret keys

Not every key is secret. Knowing the difference stops you from panicking about the wrong one and ignoring the right one.

TypeExamplesCan it be in the browser?
Publishable / public keysStripe pk_… key, a maps key restricted to your domain, some analytics IDsYes — designed for it
Secret keysStripe sk_…, OpenAI and Anthropic keys, email provider keys, database passwordsNever
Service/admin keysKeys that bypass access rules on a hosted databaseNever — treat as the most sensitive

If you're not sure which kind a key is, check the provider's documentation. When in doubt, treat it as secret.

Step 1: Store keys as secrets, not in code

Keys belong in your host's environment variables or secrets settings. Your code reads them by name at runtime (for example process.env.OPENAI_API_KEY), so the value never appears in your files. For the background, see what environment variables and secrets are.

Move every API key out of the code into environment variables. List each key you found, which file it was in, and the variable name you used. Don't show me the values.

Then check nothing is left:

Search the whole project, including config files and any .env files, for anything that looks like an API key or password. Report the file and line, not the value.

Step 2: Use secret keys only on the server

This is the rule that matters most. Anything the browser receives, a visitor can read — the page source and JavaScript files are all visible in developer tools.

So if the app needs to call OpenAI, the browser should call your server, and your server calls OpenAI with the key. The key never leaves the server.

The chat feature calls OpenAI directly from the browser. Move that call to a server API route that reads OPENAI_API_KEY from the environment. The browser should only call our route. Require login for the route.

Watch for one common trap in frontend frameworks: variables with a public prefix — VITE_ in Vite, NEXT_PUBLIC_ in Next.js — are built into the browser code on purpose. A secret key with one of those prefixes is exposed, even though it's "in an environment variable".

Step 3: Test that nothing leaks

Don't trust that it worked — check the live site:

  1. Open the published app in a browser.
  2. Open developer tools, then the Sources or Network tab.
  3. Search across files for the first characters of each secret key (for example sk_ or sk-).
  4. Check the network requests the app makes. A request going straight from the browser to a paid AI provider is a red flag.

If you find a secret key, move it to the server (step 2) and rotate it (step 6), because it was already public.

Step 4: Restrict what each key can do

Many providers let you limit a key:

  • Scoped or restricted keys that can only do what your app needs. Stripe, for example, supports restricted keys with specific permissions.
  • Domain or IP restrictions for keys that must be public, such as maps keys.
  • Separate keys per app and per environment, so one leak doesn't expose everything, and revoking one doesn't break the others.
  • Test keys while building, and live keys only in the published app.

Step 5: Put a ceiling on damage

Even a well-protected key can be misused through your own app — someone scripting your AI feature thousands of times, for example.

  • Set spending limits or alerts at every paid provider.
  • Require login for any feature that costs money per call.
  • Add a per-user rate limit. See what rate limiting is.

Add a limit of 30 AI requests per user per hour to /api/chat. Return a clear message when the limit is hit. Reject requests from users who aren't logged in.

Step 6: Rotate keys that leak

If a secret key appears somewhere it shouldn't — a chat message, a commit, a screenshot, a support ticket, browser code — assume it's compromised.

  1. Create a new key at the provider.
  2. Update the secret in your app's settings.
  3. Redeploy or publish again so the live app uses the new key.
  4. Delete the old key at the provider.
  5. Check the provider's usage logs for activity you don't recognise.

Deleting the chat message or Git commit is not enough. Git history keeps old versions, and anything public may already have been copied.

Common mistakes

  • Pasting a key into the prompt. It's now in the chat history. Use a secrets form instead.
  • A public prefix on a secret variable. VITE_OPENAI_API_KEY ships the key to every visitor.
  • Committing a .env file. Make sure it's in .gitignore before the first push.
  • One key everywhere. Use separate keys for test and live, and for each app.
  • No spending limit. A leaked or abused key with no cap can run up a large bill before you notice.
  • Hiding instead of rotating. Once a key has been exposed, only a new key fixes it.
  • Keys in screenshots. Crop or blur settings pages before sharing them for help.

Checklist

  • Every key is stored as a secret or environment variable, not in code.
  • No .env file or key is committed to Git.
  • Secret keys are used only in server-side code.
  • No secret variable uses a public prefix like VITE_ or NEXT_PUBLIC_.
  • I searched the live site's JavaScript for each key's prefix and found nothing.
  • Keys are scoped or restricted where the provider allows it.
  • Test and live keys are separate.
  • Paid features require login and have per-user limits.
  • Every paid provider has a spending cap or alert.
  • I know how to rotate each key, and any key that was ever exposed has been rotated.

Keeping keys safe on Mythex

Mythex keeps keys out of your code and chat in two ways:

  • Secrets request card. When the agent needs a key, it shows a card in chat where you enter the value in form fields, not the message box, and it's stored as a project secret. See Secrets in chat.
  • Project settings → Secrets, or /secrets in chat, to add or change keys yourself. See Environment variables and secrets.

After changing a secret for a published app, publish again so the live app picks it up. Exported projects leave secrets out, so re-add them wherever you run the code next. If a key ever appears in chat, rotate it at the provider.

For the rest of the pre-launch security pass, work through the security checklist for AI-built apps. If you're adding AI features, how to use LLM APIs covers keys and costs in more depth.

Questions

Is it safe to put an API key in frontend code?

Only if the provider designed that key to be public, such as Stripe's publishable key or a maps key restricted to your domain. Any key that can spend money or read private data must stay on the server, because anything sent to the browser can be read by anyone.

What should I do if I pasted an API key into a chat or a public repo?

Rotate it: create a new key at the provider, update your app's secrets, publish again, then delete the old key. Deleting the message or commit is not enough, because copies may already exist.

Where should API keys be stored?

In your host's environment variables or secrets settings, read by server-side code at runtime. They should not be written into source files, committed to Git, or included in screenshots.

How can I tell if my API key is exposed in my website?

Open your live site, view the page source and the JavaScript files in the browser's developer tools, and search for the start of the key. If it appears, it's exposed and should be moved to the server and rotated.

Keep reading

  • How to Add a Blog to Your Website: Options, SEO and Setup — How to add a blog to your website: Markdown files vs a built-in editor vs a CMS, subfolder vs subdomain, SEO basics, and prompts to build it with AI.
  • How to Add a Contact Form to Your Website (That Actually Reaches You) — How to add a contact form that works: save messages, get email alerts, stop spam, and avoid the mistakes that silently lose enquiries. Prompts included.
  • How to Add a Database to Your App (Without Losing Data Later) — How to add a database to an app you built: when you need one, Postgres vs hosted options, designing tables, prompts to use, and mistakes that lose data.
  • How to Add AI Features to Your App — Add summaries, chat, data extraction and classification to your app with an LLM API — keeping keys safe, costs under control and output trustworthy.
  • How to Add Analytics to Your App: GA4, Privacy-First Tools and Product Analytics — How to add analytics to your website or app: Google Analytics 4 vs privacy-first vs product analytics, what to track, cookie consent, and prompts to use.
  • How to Add Cookie Consent to Your Website — Add a cookie banner that actually blocks scripts until people agree: what needs consent, CMP vs custom, Google consent mode and a checklist. Not legal advice.

Start building free · Templates · Docs