Skip to main content
GullySystem
A practical guide

What to do when an API key or password is found in your code

Ganesh HSStrategy and Technology, GullySystem
Practical advice · 5 min read

In this guide 6 sections
The short answer

Treat any key found in code as already stolen. First revoke it and issue a new one. Then read the provider’s logs for misuse. Strip the secret from history and old builds, then move every secret into a managed store, with scanning that blocks the next commit from carrying one.

Revoke and rotate before anything else

Do not start by deleting the line. Once a key has sat in a repository, copies live in clones, forks, build caches, backup drives and the laptops of every developer who ever pulled the code. Removing the file changes nothing about who already holds it. Speed matters more than tidiness.

Open the provider’s console and disable the old key. Create a replacement and deploy it. For a database password, change it on the server. Update the application settings in the same window. Warn the team first. Mobile users on the old build will see errors until they update, and webhook senders will start failing. Nobody should waste an hour debugging a failed login.

Expect a short outage. A planned ten minute break beats a quiet leak that runs for months while invoices and customer records sit open to anyone holding the key.

  • Cloud access keys and service account files
  • Payment, SMS and email provider tokens
  • Database connection strings with passwords
  • Signing keys for mobile apps and webhooks
  • Third party API keys inside a mobile build

Check whether anyone used it

Rotation closes the door. It does not tell you who walked through. Ask the provider for the usage history of the old key, starting from the day it first appeared in code.

Look for calls from unfamiliar addresses, odd hours, regions you do not serve and actions your app never performs, such as creating new users or listing storage buckets. Check the bill for sudden spikes too. Cloud providers keep such trails. AWS CloudTrail and Google Cloud audit logs are the usual places to look.

Write down what you find, even when it is nothing. Save screenshots of the log filters you used, with dates, in a folder the security owner controls. That record matters if a customer or regulator asks later.

Clean the history and the old builds

A secret removed in a later commit stays readable in the earlier one. Tools such as git filter-repo or BFG Repo-Cleaner rewrite history to strip it. Every contributor must then re-clone and force the old branches out of their local copies. Give notice first.

Do not forget what sits outside the repository. Search old Docker images, CI logs, Postman collections and wiki pages for the same string. Check the APK or IPA files already published too. A mobile build carries its strings in plain view. Unpacking takes a minute. Stale copies hide there. Terraform state files and exported Kubernetes manifests are favourite hiding places.

The key is revoked already, so this is housekeeping. Do it anyway. Never let it replace the revoke step.

  • Full git history on every branch and tag
  • Container images and CI job logs
  • Mobile app builds on stores and test channels
  • Chat messages and tickets where keys were pasted

Move secrets out of the code for good

Secrets belong in a managed store such as a cloud secrets manager or a vault, read at start time through environment settings. The code holds the name of the secret. It never holds the value. A .env file kept out of version control is a start, not an end.

Give each environment its own keys, so a developer’s test key has no power over production data, customer files or the live payment account. Limit every key to the single action it needs. Set an expiry where the provider allows one.

For a mobile app, assume the build is public. Route sensitive calls through your own server, which holds the real key and checks who is asking before it forwards anything to the provider.

Stop it happening again

Add secret scanning to the repository and to the pre-commit hook; a push that contains a key pattern should fail with a message naming the file. Gitleaks and the scanning built into major code hosts do this job; the scan should also run in the build pipeline, as a second net.

Add one line to code review: references only, no values in the diff; run a scan across the full history every quarter to catch what slipped through. Short. Strict. Boring.

Today, list every key your applications use. Note where each lives. Rotate the oldest.

Exposed secret response sheet

A single page runbook. One numbered row per step. Columns give the step, the owner, the time started, the time finished and the evidence kept. Rows cover revoke, replace, provider log review, history rewrite, build and image sweep, store migration and scanner switch on, so nothing in the sequence gets skipped under pressure. A box at the foot records the first date the secret appeared.

Open a blank worksheet to print

Questions owners ask

Is it safe if the repository is private?

Narrower, not safe. Former staff, contractors, stolen laptops and a later change of repository visibility can all expose it. Treat private as a delay, nothing more. Rotate anyway.

Do I have to tell customers?

That depends on whether the key reached their data. Your log review answers the first part. Ask a legal adviser about your own duties.

Will deleting the commit be enough?

No. Clones and forks keep their copies. Hosts may cache old commits. Revocation is the only step that makes the secret useless.

Where should the new key be kept?

In a secrets manager or the platform’s protected settings, injected at run time. Never in the source tree, a shared document or a chat message.

Browse all guidesBack to top ↑
Next step

Have a specific situation to work through?

This article covers the general case. Tell us what you’re actually dealing with and we’ll respond directly.

Share Your Requirements