EXPOSED SECRETS

You pushed an API key to GitHub. What to do in the next hour

A step-by-step plan for a leaked key: revoke it first, check whether it was used, clean the repository and stop it happening again.

It happens to experienced developers. A key ends up in a commit, the commit gets pushed, and now it is on GitHub. Automated bots scan public repositories constantly, so assume a key in a public repository has been seen, even if you noticed within minutes.

The order of the steps below matters. Most people start by deleting the commit. Start by making the key useless instead.

1. Revoke or rotate the key first

Go to the service that issued the key (your payment provider, cloud account, email service or AI platform) and revoke it, or create a new key and delete the old one.

Do this before anything else. Removing the key from GitHub does not remove it from forks, clones or anyone who already copied it. A revoked key is safe wherever it ends up.

2. Check whether it was used

While the key was exposed, was it used by anyone but you? Look at:

  • The provider's usage or billing page, for unexpected spending.
  • Access or audit logs, for requests from addresses you do not recognise.
  • Anything the key could create, such as new users, servers, API keys or email sending.

If you find activity that was not yours, treat it as a security incident: contain it, note what happened and when, and check whether customer data was involved.

3. Put the new key somewhere safe

Store the new key outside the code: in an environment variable, your hosting provider's secret settings or a secret manager. Then deploy and confirm the app works with the new key.

# .env (never committed)
PAYMENT_API_KEY=your-new-key

# .gitignore
.env

4. Clean the repository

Remove the key from the current code, then decide what to do about the history.

If the repository is public, rewrite the history so the key no longer appears in old commits. git filter-repo can replace the text everywhere:

# replacements.txt
literal:the-old-key-value==>REMOVED

git filter-repo --replace-text replacements.txt
git push --force --all

Everyone who has a clone must then re-clone, because their copies still contain the old history. This is exactly why step 1 comes first: you cannot reliably erase something that has been public.

If the repository is private, rotating the key is still the important part. Private repositories are shared with colleagues, contractors, CI systems and tools, and their logs.

5. Stop it happening again

  • Keep .env and other secret files in .gitignore from the first commit.
  • Add a secret scanner such as gitleaks as a pre-commit hook, so a key is caught before it leaves your machine.
  • Turn on GitHub secret scanning and push protection, which block pushes that contain known key formats. GitHub offers these for public repositories, and for private repositories on its paid security plans.
  • Scan your code regularly. Our free scanner checks a ZIP or a repository for exposed keys and other risky patterns, and masks any secret it finds in the report.

The one-minute version

Revoke the key, check the logs, store the new key outside the code, clean the history, then add a scanner so it does not happen twice.

Check your own website or code for these problems.

Run a free security scan Ask us to review it

More from the blog

AI-WRITTEN CODE

Five security mistakes that are common in AI-written code

AI assistants write working code fast, but working is not the same as safe. Five common mistakes, how to spot them in your own code and how to fix each one.

Read the article

WEBSITE SECURITY

Security headers explained: what each one does and how to add it

Six response headers that protect your visitors, what each one does, and copy-ready settings for Nginx, Apache and Node.js.

Read the article

WEBSITE SECURITY

Is your .env file public? How to check in two minutes

How to check whether your .env file, .git folder or backups can be downloaded from your website, how to block them and what to do if they were exposed.

Read the article
Let’s chat