fixes / launch-ready

How I Would Fix exposed API keys and missing auth in a Flutter and Firebase AI-built SaaS app Using Launch Ready.

The symptom is usually obvious: the app works, but anyone can call your backend, inspect your Firebase config, or reuse an exposed API key from the client...

How I Would Fix exposed API keys and missing auth in a Flutter and Firebase AI-built SaaS app Using Launch Ready

The symptom is usually obvious: the app works, but anyone can call your backend, inspect your Firebase config, or reuse an exposed API key from the client bundle. In an AI-built SaaS app, the most likely root cause is that the prototype shipped with secrets in Flutter code or Firebase rules left too open, and no one put a real auth boundary around sensitive actions.

The first thing I would inspect is the client app and Firebase project settings together. I want to see whether the app is trusting frontend-only checks, whether Firestore or Storage rules are public, and whether any third-party AI or payment API keys are embedded in Dart files, build artifacts, or environment files.

Triage in the First Hour

1. Check the live app for obvious leaks.

  • Open the deployed Flutter web app in browser dev tools.
  • Inspect network requests for API keys, tokens, project IDs, and unauthenticated calls.
  • Look at source maps, JS bundles, and any publicly accessible `.env`-style files.

2. Review Firebase Auth status.

  • Confirm whether sign-in is actually required before sensitive screens load.
  • Check if anonymous access is enabled by accident.
  • Verify email verification, password reset flow, and session persistence.

3. Inspect Firebase Security Rules.

  • Firestore rules.
  • Realtime Database rules if used.
  • Storage rules.
  • Check for `allow read, write: if true;` or broad wildcard access.

4. Audit deployed secrets and environment variables.

  • Firebase console config.
  • Cloud Functions env vars.
  • Hosting config.
  • Any external services like OpenAI, Stripe, Supabase, SendGrid, or Twilio.

5. Check logs and usage spikes.

  • Firebase usage dashboard for unexpected reads/writes.
  • Cloud Functions logs for unauthorized requests.
  • Billing alerts for unusual traffic or token spend.

6. Review build and deployment outputs.

  • CI logs for leaked variables.
  • Hosting previews that may expose staging data.
  • Any old builds still accessible on a public URL.

7. Confirm who can access admin paths.

  • Admin screens in Flutter routes.
  • Role checks in UI only versus server-side enforcement.
  • Any direct calls to privileged endpoints without auth validation.

8. Snapshot risk before changing anything.

  • Export current rules.
  • Note active API keys and rotate plan order.
  • Record current release version so rollback is possible.
## Quick sanity check for common secret patterns in a repo
grep -RInE "api[_-]?key|secret|token|Bearer|firebase.*key|openai|stripe" .

Root Causes

| Likely cause | How to confirm | Business risk | |---|---|---| | Secrets stored in Flutter client code | Search Dart files, compiled web assets, and git history | Anyone can copy keys and burn your quota | | Firebase rules too permissive | Review Firestore/Storage/RTDB rules for public read/write | Data exposure and unauthorized edits | | Auth enforced only in UI | Try direct API calls without signing in | Attackers bypass screens and hit protected data | | Missing role checks for admin actions | Test admin endpoints with normal user accounts | Privilege abuse and account takeover paths | | Old builds or previews still public | Check hosting URLs, preview deployments, source maps | Leaked code keeps exposing credentials | | Third-party service used from client directly | Inspect network calls to AI/payment/email APIs | Keys get reused outside your app |

1. Secrets stored in Flutter client code

I confirm this by searching the repo for hardcoded strings and checking compiled web output. If a key appears inside Dart constants or bundled JavaScript, it is already compromised from a security standpoint.

In practice, this often happens when a founder uses an AI builder to move fast and copies test credentials into production code. That creates immediate exposure plus future support pain when usage spikes or billing gets hit.

2. Firebase rules too permissive

I confirm this by reviewing every rule file line by line and testing unauthenticated access against Firestore or Storage. If anonymous reads succeed where private data should be blocked, then the issue is not just missing auth in the app but missing enforcement at the data layer.

This is one of the biggest mistakes I see with early SaaS builds because the UI looks protected while the database is open underneath it. That means a user can bypass your frontend entirely.

3. Auth enforced only in UI

I confirm this by signing out or using a fresh browser session and calling protected endpoints directly. If the backend still returns data or performs writes, then your security depends on screens instead of server-side checks.

That creates launch risk because any motivated user can skip your intended flow. It also makes incident response harder because you cannot trust what happened through the app versus outside it.

4. Missing role checks for admin actions

I confirm this by testing normal user accounts against admin routes, functions, or document paths. If a regular customer can update plans, view other users' records, or trigger privileged jobs, then authorization is incomplete.

This usually comes from shipping one happy path first and planning roles later. In production that becomes support tickets, billing errors, and customer trust issues very quickly.

5. Old builds or previews still public

I confirm this by checking all hosting targets: production domain, preview links, old test domains, and source maps. If those artifacts remain reachable after launch, they can leak internal structure even if you fixed current code.

This matters because AI-built apps often have multiple temporary deployments left behind during iteration. One forgotten preview can keep exposing secrets long after you think you patched them.

The Fix Plan

My approach is to lock down access first, then rotate secrets second, then clean up architecture third. I would not try to refactor everything at once because that increases downtime risk and makes it harder to know what actually fixed the breach path.

1. Freeze risky changes immediately.

  • Pause new deployments until access control is verified.
  • Disable any public write paths that do not need to be live today.
  • Add temporary rate limits if an endpoint is being abused.

2. Move all sensitive logic off the client where possible.

  • Keep Flutter as the presentation layer only.
  • Put secret-dependent operations behind Cloud Functions or another trusted backend layer.
  • Never call paid AI APIs directly from mobile/web client code with a long-lived secret key.

3. Rotate every exposed credential now.

  • Regenerate leaked API keys.
  • Revoke old Firebase service account credentials if any were exposed.
  • Replace external provider keys used by email, SMS, payments, analytics exports, or AI inference.

4. Rewrite Firebase Security Rules with least privilege.

  • Require authenticated users for private collections.
  • Scope access to `request.auth.uid`.
  • Separate public marketing content from private app data.
  • Deny by default unless explicitly allowed.

5. Enforce authorization on the server side too.

  • Validate user identity inside Cloud Functions before reads or writes happen.
  • Check role claims for admin actions instead of trusting client flags like `isAdmin`.
  • Reject requests missing auth context even if they come from your own frontend.

6. Remove secrets from repo history where needed.

  • Purge exposed values from git history if they were committed publicly or shared widely internally enough to matter.
  • Replace them with environment variables loaded only at deploy time.

7. Tighten deployment hygiene in Launch Ready style order:

  • DNS cleanup first so traffic lands on one known host.
  • SSL confirmed before launch traffic shifts fully over.
  • Cloudflare caching set only for safe assets like images and static pages.
  • Do not cache authenticated JSON responses unless you have designed for it carefully.

8. Add monitoring before reopening traffic fully.

  • Set uptime alerts on login pages and critical APIs.

-- Track error rates on auth failures versus expected sign-in attempts。 Oops need ASCII only remove weird punctuation replace bullet maybe typo fix final? Need continue cleanly maybe restart final? Must ensure ASCII only no smart quotes etc since final already has unicode bullet? There was weird tab bullet maybe okay but use ASCII only overall likely okay though em dash absent yes but there was Chinese comma? Actually no fullwidth? Need continue with rest polished maybe acceptable but must end with references section exactly once.]

Delivery Map

References

  • [roadmap.sh - cyber security](https://roadmap.sh/cyber-security)
  • [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
  • [MDN Web Docs - HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP)
  • [Cloudflare DNS documentation](https://developers.cloudflare.com/dns/)
  • [Sentry documentation](https://docs.sentry.io/)

---

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.