An API key is a password your software uses to be someone. Payment provider, email service, database, AI model — each one holds a key, and each key can spend money or read data on your behalf.
The question worth answering this afternoon is not whether you have keys. It is which of them a stranger can read.
The mistake, in one sentence
Anything the browser downloads, the visitor can read.
That is the whole thing. There is no obscure exception. Code that runs in your customer's browser was sent to their machine, and it can be opened and searched. A key placed there is published.
It happens because it works. During development the fastest way to make a call succeed is to put the key where the calling code is. The feature works, the demo passes, and the key ships.
Why AI-generated code lands here so often
Ask a model for a front end that calls a service and it will produce one that calls the service. That requires a key, so the generated code has a place for a key, and the developer fills it in.
Nothing in the request said "and keep this secret from the users of the page", so nothing in the answer accounts for it. This is the same shape as the finding that around 45% of AI-generated code carries an OWASP Top 10 flaw — the code is correct with respect to the question asked, and the question omitted the security requirement.
The five-minute self-check
You can do this yourself, on your own site, without any tools beyond a browser.
Open your application. Right-click and choose View Source, or open developer tools and look at the Sources panel. Use the browser's search across those files for the strings key, secret, token, password, and for the prefixes your providers use — sk_ and pk_ for Stripe, AKIA for AWS, sk- for OpenAI.
A public or publishable key appearing is fine — those are designed to be seen. A secret key is an incident. If you are unsure which you are looking at, the provider's documentation says so plainly, and the word "publishable" or "public" in the name is usually the answer.
Also check the network tab while using the app. Watch the requests going out. If a request to a third-party service is going directly from the browser with a credential attached, that credential is public.
What to do if you find one
In this order, and the order matters.
Rotate it first. Issue a new key, update the server, revoke the old one. Do this before anything else, because the exposed key is live until it is revoked and no amount of code fixing changes that.
Then check what it did. Most providers give you a usage log. Look for calls you cannot account for — unfamiliar times, volumes, or destinations. This tells you whether you have a fix or an incident.
Then move the call. The pattern is always the same: the browser calls your server, your server holds the key and calls the provider. Slightly more code, and it is the only arrangement that works.
Then stop it recurring. A secret scanner in the pipeline that fails the build. They are free, take an hour to set up, and catch this permanently.
The honest framing
This is not an advanced failure and finding one does not mean your team is careless. It is the single most common issue in fast-built software, precisely because putting the key where the code is makes the feature work.
The five-minute check above costs nothing and answers a question you would otherwise find out about from your provider's fraud team. If it turns up something and you would rather have the whole surface looked at properly, that is what a Reality Check does — a week, a fixed fee, and a written list.
This is the part we do — the crossing from a demo to a system that survives production.