The most useful rule about frontend secrets is blunt: if the browser needs a value to run, the user can read it. Minification, environment-variable names and an obscure bundle path do not change that.

The difficult part begins after somebody finds a suspicious key. Some browser keys are designed to identify a public project. Others grant privileged access. A good response classifies the credential before either dismissing it or declaring a breach.

First, understand what the value can do

Look up the provider's intended usage. A publishable Stripe key and a Supabase anonymous key are expected in client code, though the systems behind them still need secure server or database rules. A Stripe secret key, Supabase service-role key, private GitHub token or webhook signing secret does not belong there.

Check restrictions as well as the key type. A public map key limited to one domain and one API has a different risk from an unrestricted project credential with billing enabled.

Rotate before cleaning the repository

Once a privileged credential is public, assume it has been copied. Removing it from the current file does not invalidate screenshots, browser caches, deployment artefacts, package registries or Git history.

Rotate or revoke the credential first. Then deploy the replacement only to the trusted server environment that needs it. If the application cannot tolerate immediate rotation, make that an incident decision with a short, explicit deadline rather than leaving the key active by accident.

Investigate the exposure window

Establish when the value first appeared and which environments it reached. Search built assets, old deployments, source maps, Git commits and CI artefacts. Provider audit logs may show where and when the credential was used.

The investigation should answer:

  1. What data or actions did the key permit?
  2. Was it used from an unexpected location?
  3. Could it create new credentials or persistence?
  4. Do affected records or customers require notification?

Do not paste the full secret into tickets, analytics or chat while investigating. Use a short fingerprint or the provider's credential ID.

Fix the architecture that put it there

Generated applications sometimes reference process.env or an equivalent name and create the impression that the value remains private. Frontend build tools substitute many of those variables into the shipped JavaScript.

Move privileged provider calls behind a server endpoint. The browser authenticates to your application; the server authorises the action and uses the private credential. Keep the server response narrow so it does not become a generic proxy for the same privileged API.

Where a public client key is intentional, enforce the real boundary elsewhere. Supabase RLS, Firebase rules, API authorisation and provider-side restrictions matter more than the fact that the identifier is visible.

Prevent the repeat

Add secret scanning to commits and CI, but do not rely on pattern matching alone. Review which environment variables are intentionally exposed by the frontend build system. Separate public configuration from private secrets in naming and documentation.

Finally, test the deployed bundle rather than only the source tree. The build step is where a private-looking variable can become public.

Document which client keys are public by design and restrict them on that assumption. Treat every privileged credential found in a browser as an incident until its permissions and usage history prove otherwise.