API Keys in Your Code: How Secrets Leak and What to Do When One Does

Updated 5 min read

An API key is a password one piece of software uses to talk to another: your site to Stripe, your app to its database, your shop to your email service. When a secret key ends up in code that anyone can read, a stranger can use it as if they were you, on your data and on your bill.

In short

  • Some keys are made to be public, like Stripe’s publishable key. Secret keys never belong in a web page, an app or a code repository.
  • More than 39 million secrets leaked across GitHub in 2024, GitHub says.
  • If a key leaked, replace it first. Deleting the file or the commit doesn’t make the old key safe.

Where keys leak

  • In the website’s own code. Everything a browser downloads, anyone can read: open a page, right-click and choose View page source, or open the browser’s developer tools. A key placed in front-end JavaScript is public, whatever the file is called.
  • In a public repository. In October 2022, Toyota said a contractor building its T-Connect website had uploaded part of the site’s source code to a public GitHub account by mistake in December 2017. The code contained an access key to a data server, and it stayed public until 15 September 2022. Up to 296,019 customer email addresses and customer numbers could have been reached. Toyota changed the key two days later and said it had found no further damage.
  • In a private repository. Private isn’t the same as safe. In 2016, intruders used an access key that an Uber engineer had posted to a private GitHub repository, and downloaded data on US riders and drivers: 25.6 million names and email addresses, 22.1 million names and mobile phone numbers, and 607,000 names and driving licence numbers, according to the FTC. Uber hadn’t required its engineers to use multi-factor login for GitHub.
  • In old commits. Deleting a key from the code leaves it in the repository’s history. GitHub warns that even after the history is rewritten, copies can survive in clones, forks, cached views and pull requests.
  • In apps and settings files. An app on someone’s phone can be taken apart, and a settings file left on the web can be downloaded: see exposed .env files.

Which keys are safe to show

Not every key is a secret. Some are designed to sit in a web page or an app:

Service Safe in a web page or app Keep on the server only
Stripe Publishable key (pk_...): identifies your account and can create payment tokens, but can’t take charges or read account data Secret keys (sk_...) and restricted keys (rk_...)
Supabase Publishable key: reaches only what your Row Level Security rules allow Secret or service_role key: bypasses Row Level Security, with full access to your data

That Supabase detail matters for apps built quickly, including with AI tools. The publishable key is only as safe as the Row Level Security rules behind it. If nobody set them up, check before launch.

A rule of thumb: if a service calls a key “secret”, “private”, “service role” or “admin”, it doesn’t belong anywhere a visitor can see.

If a key leaked: what to do, in this order

1. Replace the key

Go to the service and revoke or rotate the key, which makes the old one useless. GitHub’s guidance puts this first, before any cleanup of the code. In Stripe, open API keys, click the menu (⋯) next to the key, choose Rotate key and set the old one to expire Now.

2. Put the new key somewhere safe

Stripe recommends a secrets vault from your hosting platform, or environment variables if you don’t have one, and never keys in source code or in files checked into version control.

3. Check what the old key was used for

Many services keep a log of requests made with each key. Stripe shows them from the same menu. Look for activity you don’t recognise.

4. Then clean up the code

Remove the key from the code and, if you like, from the repository’s history. Once the key has been replaced, this is tidying up, not the fix.

5. Stop it happening again

  • On GitHub, push protection blocks pushes that contain known kinds of secrets. GitHub began switching it on for all pushes to public repositories in February 2024, after detecting more than a million leaked secrets on public repositories in the first eight weeks of that year.
  • Give each part of your site a key with only the permissions it needs. Stripe recommends restricted keys over full secret keys for this reason, and lets you limit a key to your own servers.

What Teyna checks

On the Pro plan, Teyna reads your code repositories, history included, for passwords and keys written into the code, keys still hiding in old commits, and settings files that shouldn’t be there, and it tells you whether a key it finds still works. Its access is read-only: it never writes to your repository. The free check looks from outside for settings files and backups your site hands out to anyone.

Is your website safe? Find out in a minute.

The free check reads only what anyone on the internet can already see: the padlock, email protection, open backups and signs of a hack. No sign-up and no card. We only ask for your email to send you the link to your report.

Scan my site for free

Questions

Is a Stripe publishable key safe in front-end code?

Yes. Stripe says you can include it in front-end code and in apps you distribute: it identifies your account but can’t take charges or read account data. Your secret and restricted keys must stay on the server.

Is deleting the file from GitHub enough?

No. The key is still in the repository’s history, and copies may exist in clones and forks. Revoke or rotate the key first. After that, cleaning up the history is tidying.

Are private repositories safe for keys?

Safer, not safe. Anyone who gets into the repository gets the keys, which is how Uber’s 2016 breach happened. Laravel’s documentation makes the same point about settings files in source control.

My app was built with an AI tool. What should I check?

Ask where each key lives. Keys that are meant to be public, like Stripe’s publishable key or Supabase’s publishable key, can be in the app, but the Supabase one is only safe if Row Level Security is set up. Secret keys, like Stripe’s secret key or Supabase’s service_role key, must only be on the server.

How would I know if one of my keys has leaked?

On GitHub, secret scanning can alert you when it spots a known kind of key in a repository. Check each service’s request logs for use you don’t recognise, and watch your bills: a key to a paid service lets whoever has it run up charges on your account.

sources