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 a React Native and Expo AI chatbot product and find exposed API keys plus missing auth, I assume two things immediately: the app is already in...

Opening

If I open a React Native and Expo AI chatbot product and find exposed API keys plus missing auth, I assume two things immediately: the app is already in production risk, and the blast radius is bigger than the founder thinks. The likely root cause is that secrets were shipped into the client bundle or checked into a repo, while the backend trusts requests from anyone who can hit the endpoint.

The first thing I would inspect is where the chatbot actually talks to the AI provider. In most cases, I am looking for hardcoded keys in Expo env files, direct calls from the mobile app to OpenAI or another model API, and any backend route that lacks token validation, rate limiting, or user/session checks.

Triage in the First Hour

1. Check the repo for secrets.

  • Search `app.config.js`, `.env`, `.env.local`, `eas.json`, and any committed config files.
  • Look for `sk-`, `Bearer`, service account JSON, Firebase admin keys, Supabase service role keys, or webhook secrets.

2. Inspect the built app path.

  • Confirm whether the key is present in JS bundles or embedded in config passed to Expo.
  • Check whether the app can call AI endpoints directly without a server hop.

3. Review authentication flow.

  • Verify if login exists at all.
  • If it exists, confirm whether API routes actually validate a token instead of trusting a client flag like `isLoggedIn: true`.

4. Check logs and dashboards.

  • Look at API gateway logs, server logs, Cloudflare logs if present, and provider usage dashboards.
  • Watch for unusual spikes in requests, token usage, failed logins, or traffic from unexpected regions.

5. Audit environment variables.

  • Confirm what is set in local dev versus EAS preview versus production.
  • Identify any variables that should never be client-side.

6. Review deployment settings.

  • Check build profiles, release channels, and whether preview builds are pointing at production APIs.
  • Confirm if old builds are still live in TestFlight or Play internal testing with stale secrets.

7. Inspect user screens and flows.

  • Verify whether unauthenticated users can reach chat input, send messages, or access prior conversations.
  • Check empty states and error states for information leakage.

8. Freeze risky changes.

  • Pause new releases until secrets are rotated and auth is enforced.
  • Disable any public endpoint that is clearly accepting unauthenticated traffic.

A fast diagnostic command I would run locally:

grep -RInE "sk-|Bearer |service_role|private_key|api[_-]?key|secret" .

If that returns anything inside source files or committed config, I treat it as a credential incident first and a code issue second.

Root Causes

1. Secrets were embedded in the Expo client.

  • Confirmation: key appears in source, build output, or JS bundle inspection.
  • Why it happens: founders want to move fast and call the model directly from mobile code.

2. The app calls third-party AI APIs from the device instead of a backend proxy.

  • Confirmation: network trace shows requests going straight from app to AI provider domains.
  • Why it matters: any user can extract requests and reuse credentials.

3. Auth exists only in UI state, not on protected routes.

  • Confirmation: unauthenticated requests still return chat responses or conversation history.
  • Why it happens: login screens look real but backend never checks tokens.

4. Environment separation is broken.

  • Confirmation: preview builds use production keys or production endpoints by default.
  • Why it matters: one leaked test build can expose live data and burn paid tokens.

5. Secrets were committed to git history or shared via CI logs.

  • Confirmation: secret scanners or git history show past exposure even after file cleanup.
  • Why it matters: rotating current values alone may not be enough if old values remain valid elsewhere.

6. Missing rate limits and abuse controls.

  • Confirmation: one account or no-account traffic can generate large volumes of chat requests quickly.
  • Why it matters: even after fixing auth, you can still get bill shock and downtime from automated abuse.

The Fix Plan

My goal is to stop exposure first, then restore safe functionality without breaking onboarding or chat UX.

1. Rotate every exposed secret immediately.

  • Replace all leaked API keys, webhook secrets, cloud credentials, and service role credentials.
  • Assume anything shipped to clients is compromised forever.

2. Move all privileged AI calls behind a backend layer.

  • The Expo app should talk only to your own API.
  • The backend stores vendor keys in server-side environment variables only.

3. Enforce authentication on every protected route.

  • Require a valid session token or JWT before creating chats, reading threads, exporting data, or accessing billing actions.
  • Validate token signature, expiry, issuer, audience if relevant.

4. Add authorization checks per resource.

  • A signed-in user should only access their own conversations and usage data.
  • Do not trust user IDs sent from the client unless they are derived from verified auth claims.

5. Put guardrails on AI usage endpoints.

  • Add rate limits per user and per IP where appropriate.
  • Add request size limits so someone cannot send giant payloads through your chat endpoint.

6. Sanitize what gets logged.

  • Remove prompts containing personal data from application logs unless there is an explicit business need and consent path.
  • Never log full secrets, raw tokens, or provider responses that include sensitive content.

7. Lock down CORS and network access where relevant.

  • If you have web admin panels or companion APIs, allow only known origins and required methods.
  • Keep mobile-specific APIs private behind auth rather than relying on obscurity.

8. Patch release process before shipping again.

  • Separate dev, staging, and production environments clearly in EAS and backend config.
  • Use different keys per environment so one leak does not compromise everything.

9. Add monitoring before re-enabling full traffic.

  • Track auth failures, 401/403 rates, request volume by endpoint, cost per conversation, latency p95, crash-free sessions, and unusual geography spikes.

10. Ship with minimal surface area first if needed.

  • If auth work touches too much code at once,

I would ship a temporary maintenance mode for public users while keeping internal testers active, then restore chat access after verification rather than rushing a half-fixed release.

The architecture change should be simple:

Regression Tests Before Redeploy

I would not redeploy until these checks pass:

  • Authentication tests
  • Unauthenticated users get 401 on protected endpoints
  • Expired tokens are rejected
  • A user cannot read another user's conversation by changing an ID
  • Secret exposure tests
  • No API keys appear in source files
  • No secrets appear in build artifacts
  • No sensitive values appear in logs during normal chat use
  • Chat flow tests
  • Signed-in users can start a new conversation
  • Existing conversations load correctly
  • Error states show a clear message when upstream AI fails
  • Abuse tests
  • Rate limit triggers after expected threshold
  • Large payloads are rejected cleanly
  • Repeated invalid auth attempts do not cause crashes
  • Mobile QA checks

- App launches on iOS and Android test devices - Login persists correctly across restart - Logout clears local session state

Acceptance criteria I would use:

  • Zero exposed secrets in repo scan before merge
  • Zero unauthenticated reads or writes on protected routes
  • p95 API response under 800 ms for non-AI metadata endpoints
  • Crash-free sessions above 99 percent on test build validation
  • No critical security findings left open before public release

Prevention

I would put four guardrails in place so this does not happen again:

1. Security-focused code review gates If a change touches auth middleware, env vars, storage logic, or AI routing, I review it for behavior first: who can call this, what data leaves the device, and what happens when tokens expire?

2. Secret handling policy No long-lived privileged keys in mobile code ever, not even for testing convenience if that build can escape your team.

3. Monitoring with alerts tied to business impact Alert on sudden usage spikes, 401 surges, failed deployments, and abnormal spend so you catch abuse before invoice day surprises you.

4. UX that makes auth obvious Users should know when they are signed out, why chat is unavailable, and what they need to do next instead of seeing vague failures that drive support tickets up.

For performance safety, I also prefer caching non-personal metadata responses at the edge where possible, while keeping chat generation itself authenticated and uncached unless there is a very specific reason not to do so.

When to Use Launch Ready

Launch Ready fits when you already have something working but it is not safe enough to ship publicly yet. I handle domain setup, email, Cloudflare, SSL, deployment, secrets, monitoring, DNS redirects, subdomains, SPF/DKIM/DMARC, production environment variables, and handover so you stop guessing which part of launch is broken.

Use this sprint if:

  • your Expo app works locally but breaks in production
  • secrets are exposed or mismanaged
  • auth needs cleanup before launch day
  • you need deployment discipline more than more features

What I need from you:

  • repo access plus current build links
  • list of third-party services used by the chatbot
  • current domain registrar access if custom domains are involved
  • any existing auth provider details like Clerk Firebase Supabase Auth0 custom JWTs
  • screenshots of broken flows plus notes on what must stay live during the fix

My recommendation is simple: do not keep iterating on features until secret handling and auth are corrected at the platform level first; otherwise you are just adding product surface area onto an unsafe foundation.

References

  • https://roadmap.sh/api-security-best-practices
  • https://roadmap.sh/code-review-best-practices
  • https://roadmap.sh/qa
  • https://docs.expo.dev/guides/environment-variables/
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

---

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.