fixes / launch-ready

How I Would Fix exposed API keys and missing auth in a React Native and Expo AI chatbot product Using Launch Ready.

If I open an Expo chatbot app and find API keys exposed plus no real auth, I treat it as a production incident, not a code cleanup. The symptom is usually...

How I Would Fix exposed API keys and missing auth in a React Native and Expo AI chatbot product Using Launch Ready

If I open an Expo chatbot app and find API keys exposed plus no real auth, I treat it as a production incident, not a code cleanup. The symptom is usually simple: the app works, but anyone can inspect the bundle, copy a key, and hit your AI or backend endpoints from anywhere.

The most likely root cause is that the product was built to prove the idea fast, then shipped without a server boundary. The first thing I would inspect is where the model calls happen: inside the React Native app, inside Expo config, or through an unprotected API route with no session checks.

Triage in the First Hour

1. Check the live app behavior on iOS and Android.

  • Confirm whether chat requests are made directly from the client.
  • Look for hardcoded base URLs, tokens, or provider keys in screens, hooks, or config files.

2. Inspect build artifacts and environment usage.

  • Review `app.config.js`, `app.json`, `.env`, EAS secrets, and any `EXPO_PUBLIC_` variables.
  • Verify whether sensitive values were bundled into the client.

3. Check backend or serverless logs.

  • Look for unusual request volume, repeated prompts, or calls from unknown IP ranges.
  • Confirm whether requests have user identity attached or are anonymous.

4. Review auth flows in the app.

  • Test signup, login, logout, token refresh, and session persistence.
  • Confirm whether protected screens actually block unauthenticated users.

5. Inspect cloud dashboards and provider consoles.

  • Check OpenAI or other LLM usage spikes.
  • Review rate limits, quota burn rate, and error rates.

6. Audit secrets exposure paths.

  • Search Git history for keys.
  • Check CI logs, preview builds, crash reports, analytics events, and shared screenshots.

7. Freeze risky changes.

  • Stop new deploys until you know which key is exposed and where it is used.
  • Rotate anything that could be abused today.

A quick diagnostic command I would run locally:

grep -R "sk-" . --exclude-dir=node_modules --exclude-dir=.git

That does not fix anything by itself. It just tells me how bad the exposure is and whether secrets are sitting in plain text in source files.

Root Causes

| Likely cause | How I confirm it | Why it matters | | --- | --- | --- | | API key is stored in Expo client code | Search bundle output, `EXPO_PUBLIC_` vars, and screen files | Anyone can extract it from the app | | Chatbot calls third-party AI directly from device | Inspect network requests in dev tools | No server-side control over auth or abuse | | Missing user authentication layer | Try opening protected routes while logged out | Anonymous users can consume paid resources | | Backend accepts requests without session validation | Review API middleware and request headers | Attackers can replay requests at scale | | Secrets leaked into git or CI logs | Check commit history and pipeline output | Rotating one key may not be enough | | No rate limiting or quotas | Test repeated requests from one account/IP | One bad actor can burn through spend fast |

The biggest business risk here is not just theft of a key. It is uncontrolled usage cost, customer data exposure, support load from broken accounts, and loss of trust if users see unauthorized chat history or broken sign-in behavior.

The Fix Plan

My rule is simple: move trust out of the client and into a controlled backend boundary. The React Native app should never hold privileged AI keys or admin credentials.

1. Rotate every exposed secret first.

  • Revoke old API keys immediately.
  • Replace them with new keys stored only in server-side secret managers or deployment env vars.
  • Assume anything committed to git is public forever.

2. Put all AI calls behind your own API.

  • The app should call your backend endpoint.
  • The backend validates the user session before forwarding any request to the model provider.
  • This gives you logging, quotas, moderation hooks, and cost control.

3. Add real authentication before any paid action.

  • Use email magic links, OTPs, OAuth, or a proper session-based flow.
  • Protect chat creation, message history access, profile data, billing pages, and admin routes.
  • If there are guest users allowed, make that explicit and heavily limited.

4. Enforce authorization on every sensitive endpoint.

  • Do not rely on hidden buttons or client-side route guards alone.
  • Check user ownership on message threads, workspace records, billing state, and exported data.

5. Add rate limits and abuse controls.

  • Limit requests per user and per IP.
  • Cap prompt size and response length where possible.
  • Add timeouts so runaway requests do not pile up costs.

6. Remove secrets from mobile builds.

  • Keep only non-sensitive public settings in Expo public env vars.
  • If a value can be abused outside your app context, it does not belong in the client bundle.

7. Tighten CORS and network boundaries where relevant.

  • If you have web endpoints alongside mobile endpoints, allow only known origins for browser traffic.
  • Mobile apps are not protected by CORS anyway; auth still has to be enforced server-side.

8. Add monitoring before redeploying widely.

  • Track failed logins, 401/403 counts, request spikes, token refresh failures, LLM spend spikes, and latency p95.
  • Set alerts for unusual usage so you catch abuse early instead of after the invoice lands.

For Launch Ready work specifically, I would use this sprint to get domain/email/Cloudflare/SSL/deployment/secrets/monitoring sorted together so you do not patch security in one place while leaving production weak everywhere else. That package matters because security fixes fail when DNS is messy or deploys are manual.

Regression Tests Before Redeploy

I would not ship this fix until these checks pass:

1. Auth gating

  • Unauthenticated users cannot access chat creation or message history.
  • Logged-out users are redirected to login within 1 second on protected screens.

2. Authorization checks

  • User A cannot read User B's threads by changing IDs in requests.
  • Admin-only actions fail with 403 for non-admin accounts.

3. Secret safety

  • No private API keys appear in source files or bundled client code.
  • New builds do not contain provider credentials when scanned locally.

4. Abuse controls

  • Repeated rapid requests trigger rate limits gracefully.
  • The app shows a clear error state instead of hanging or retrying forever.

5. Functional chat flow

  • Login -> create thread -> send message -> receive reply -> reload -> history persists correctly.
  • Logout clears access to private data immediately.

6. Error handling

  • Expired sessions prompt re-authentication cleanly.
  • Provider outages return a friendly failure state with no leaked stack traces.

7. Security acceptance criteria

  • 100 percent of sensitive endpoints require authentication middleware.

This means no public route can create cost-bearing AI traffic without a valid user context. For a small product like this I want at least 90 percent test coverage on auth middleware paths before release.

8. Release readiness

  • EAS build succeeds for both platforms.
  • Smoke test passes on one iPhone device class and one Android device class before full rollout.

If I were running QA on this sprint end-to-end I would also check that onboarding still works after auth changes. A common failure mode is fixing security but accidentally breaking first-run conversion by forcing too much friction too early.

Prevention

The best prevention is architectural discipline plus basic operational guardrails.

  • Keep secrets off-device by default.

Any value that can charge your account or expose customer data belongs server-side only.

  • Require code review for auth changes.

I would review every change touching sessions, tokens, storage helpers, route guards, webhook handlers, and AI proxy endpoints before merge.

  • Add secret scanning to CI/CD.

Block merges if patterns like provider keys appear in commits or environment files committed by mistake.

  • Use least privilege everywhere possible.

Separate dev/staging/prod credentials so one mistake does not take down all environments at once.

  • Monitor spend as a security signal.

A sudden jump in token usage often means abuse long before customers complain.

  • Design safer UX around login states.

Show clear locked states for premium chat features instead of letting users discover failures after typing a long prompt.

  • Keep performance sane while adding security layers.

Proxying chat through your backend should still keep p95 response times under about 800 ms before model latency, with caching for static assets through Cloudflare so auth work does not slow down unrelated screens.

Here is the decision path I use:

When to Use Launch Ready

Use Launch Ready when you need this fixed fast without turning it into a six-week rebuild. I handle domain setup, email deliverability, Cloudflare, SSL, deployment, secrets, and monitoring together so your product lands safely instead of half-fixed across multiple tools.

This sprint fits best if you already have:

  • A working React Native + Expo chatbot prototype
  • Access to your repo
  • Access to hosting/deployment accounts
  • Access to DNS registrar
  • Access to AI provider dashboards
  • Access to email sending accounts if onboarding emails exist

What I need from you before kickoff:

  • Current repo link
  • List of environments: dev/staging/prod
  • All third-party services used by the app
  • Any known leaked key locations
  • Desired auth method if you already chose one
  • App Store / Play Store status if mobile release depends on this fix

If you are unsure whether this is just an Expo config problem or a deeper security issue, I would still start with Launch Ready because the first job is containment: rotate secrets, close anonymous access, stabilize deployment, then decide whether more architecture work follows next week.

References

  • https://roadmap.sh/cyber-security
  • https://roadmap.sh/api-security-best-practices
  • https://roadmap.sh/code-review-best-practices
  • https://docs.expo.dev/
  • https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html

---

Take the next step

If this is a problem in your product right now, here is what to do next:

  • [Use the free Cyprian tools](/tools) - estimate cost, score app risk, check launch readiness, or pick the right service sprint.
  • [Book a discovery call](/contact) - I will tell you honestly whether you need a sprint or if you can DIY the next step.

*Written by Cyprian Tinashe Aarons - senior full-stack and AI engineer helping founders rescue, launch, automate, and scale AI-built products.*

Next steps
About the author

Cyprian Tinashe AaronsSenior Full Stack & AI Engineer

Cyprian helps founders rescue, secure, deploy, and automate AI-built apps with production-grade engineering, launch systems, and AI integration.