Guides
What to Do If You Committed an API Key to GitHub
Committing an API key to GitHub is a common mistake — especially when an AI coding tool generates integration code with real key values. If this happened to you, act now. The key should be considered compromised the moment it reached GitHub, regardless of whether the repo is public or private. This guide gives you the exact steps to contain the damage and prevent it from happening again.
Updated July 2026 · 11 min read
Written for AI makers using tools like Cursor, Bolt, Lovable, Replit, Claude, and ChatGPT.
Quick answer
Rotate or revoke the exposed key immediately — this is the most important step. Then remove the key from your code, add .env to .gitignore, create .env.example with placeholders, set the new key value in your hosting environment, and check provider billing for unexpected usage.
Who this is for
- You pushed to GitHub and realized a
.envfile or hardcoded key was included - GitHub's secret scanning alerted you about an exposed credential
- You are not sure whether a key was already in a commit you pushed weeks ago
What you'll need
- Access to the provider's API dashboard (OpenAI, Stripe, Supabase, etc.)
- Access to your GitHub repository
- Access to your hosting platform dashboard
- Your project open in a code editor
How serious is this?
Treat it as a confirmed breach from the moment you know. Automated bots scan GitHub commit history continuously — not just the latest files, but every commit ever pushed. A key that touched a public repo even briefly can be found within seconds. A private repo is less immediately dangerous but not safe: collaborators have access, the repo can become public, and your own account could be compromised.
The consequences depend on the key. A leaked OpenAI key can run up hundreds of dollars in API charges before you notice. A leaked Stripe secret key can create test charges or access customer data. A leaked database URL gives read and write access to your data. The sooner you rotate, the smaller the damage window.
Do not wait to assess the situation before rotating. Rotate immediately, then investigate. Key rotation is fast and reversible; damage from a misused key may not be.
Step 1: Rotate or revoke the key immediately
Open the provider's dashboard and find the API keys section. Revoke or delete the compromised key, then generate a new one. Different providers use different terminology — look for 'Revoke', 'Delete', 'Roll', or 'Regenerate'. The goal is to make the old key permanently invalid.
Do this for every key in the commit, not just the one you noticed. If your .env file was committed, assume every key in it is compromised.
After generating new keys, update your local .env file with the new values. Do not commit .env. You will add the new production values to your hosting platform in a later step.
- OpenAI: platform.openai.com → API keys → Delete key → Create new
- Stripe: dashboard.stripe.com → Developers → API keys → Roll key
- Supabase: project settings → API → Regenerate service role key
- GitHub personal access tokens: github.com → Settings → Developer settings → Personal access tokens
- Anthropic: console.anthropic.com → API Keys → Delete key → Create new
Why deleting the file is not enough
Git stores every version of every file ever committed. Deleting .env and committing that deletion removes the file from the latest snapshot, but the full key value remains readable in any prior commit.
Anyone can run git log and git show to access the full content of any historical commit. GitHub's web interface also allows browsing commit history. The key value is not gone — it is just not visible in the current file tree.
This is why rotation comes before history cleanup. Rotation makes the compromised key worthless immediately. History cleanup is a secondary step that reduces long-term risk, but it is slower and more complex.
Remove the key from your code and .env
After rotating, search your entire project for the old key value and any hardcoded key patterns. Remove them from source files. Replace string literals with environment variable references: process.env.OPENAI_API_KEY in Node.js and Next.js, os.environ['OPENAI_API_KEY'] in Python.
If the key was in a .env file that was committed, update .env with the new (rotated) key value. The new value has never been committed, so it is safe locally.
Also check README files, documentation, and any notes files. Developers sometimes paste real keys into documentation as examples. Replace any real values with placeholder strings.
Update .gitignore
Open .gitignore in your project root. Add .env on its own line if it is not already there. Save the file.
Then check whether .env is currently tracked by Git. Run git ls-files .env — if it returns the filename, it is tracked and needs to be explicitly untracked. Run git rm --cached .env to stop tracking it without deleting your local copy. Commit this change: git commit -m 'stop tracking .env'.
Verify with git status that .env no longer appears in the list of staged or unstaged changes. From this point forward, Git will ignore .env completely.
Create .env.example
Create .env.example in your project root. List every variable your app reads with descriptive placeholder values: OPENAI_API_KEY=your_openai_api_key_here. This file is safe to commit — it contains no real secrets.
Commit .env.example to GitHub. It serves as documentation for what the project needs and shows reviewers that you have thought carefully about secret management.
If .env.example already exists, review it to confirm all current variables are listed and no real values snuck in.
Optional: clean Git history
Rotation makes the old key useless, but cleaning history reduces the risk of future confusion and removes the key from GitHub's searchable commit history. GitHub provides official guidance on removing sensitive data from repositories.
The standard tools are git filter-branch (older, built-in) or the BFG Repo Cleaner (faster and easier for most cases). Both rewrite history, which changes commit hashes and requires a force push — coordinate with any collaborators before doing this.
For small solo projects where rotation has already happened, history cleanup is good hygiene but not urgent. For team projects or if the key is for a high-value service, prioritize cleaning history promptly.
Update your deployment environment variables
Your hosting platform needs the new (rotated) key value. Log into your hosting dashboard and update the environment variable with the new key. On Vercel: Project → Settings → Environment Variables. On Railway: your service → Variables tab. On Render: your service → Environment.
After updating, trigger a new deployment so the running app picks up the new value. Test the live URL to confirm the API calls still work. If anything breaks, the old key is already revoked — check that the new key value was entered correctly.
Review all environments: if you have staging and production, update both. If you use CI/CD pipelines with stored secrets, update those too.
Check for unauthorized usage
After rotating, check the provider's usage dashboard. Look for requests during the window when the key was exposed — from the time of the first commit containing it until the time you rotated. Unexpected request volumes or requests from unfamiliar IP addresses are signs of misuse.
Most providers show usage by API key. Some provide logs with timestamps and source IPs. Note the total usage and whether it matches what you expected for that period.
If you find evidence of misuse, contact the provider's support team. Many providers have processes for investigating and reversing fraudulent charges when you report promptly. Document the timeline of discovery and rotation.
Step-by-step
- 1
Step 1
Rotate or revoke the exposed key
Open the provider's API dashboard. Revoke or delete the compromised key and generate a new one. Update your local
.envwith the new value. Do this for every key that was committed. - 2
Step 2
Remove the key from source code
Search the project for old key values and hardcoded patterns. Remove them from source files,
README, and documentation. Replace withprocess.env.KEY or os.environ['KEY'] references. - 3
Step 3
Untrack .env and update .gitignore
Add
.envto.gitignore. Run git rm --cached.envif.envis currently tracked. Commit the.gitignorechange. Verify with git status that.envis no longer in the tracked file list. - 4
Step 4
Create .env.example
Create
.env.examplewith every variable name and a placeholder value. Commit it to GitHub. This documents what the project needs without exposing real secrets. - 5
Step 5
Update your hosting environment variables
Add the new (rotated) key value to your hosting platform's environment variables panel. Redeploy. Test the live URL to confirm API calls work with the new key.
- 6
Step 6
Check for unauthorized usage
Review provider usage dashboards and logs for the period when the key was exposed. Contact provider support if you find unexpected usage. Document the incident and timeline.
- 7
Step 7
Optionally clean Git history
Use BFG Repo Cleaner or git filter-branch to remove the old key value from commit history. Force-push the cleaned history. Notify collaborators — their local clones contain the old history until they re-clone or run a hard reset.
Common mistakes
Deleting the
.envfile in a new commit and thinking that fixes itHow to fix it: The key value is still readable in the commit that included it. Rotate the key immediately — deletion alone does not protect you.
Only rotating the key you noticed, not all keys in the commit
How to fix it: Assume every key in the committed file is compromised. Rotate all of them.
Waiting to assess damage before rotating
How to fix it: Rotate first, investigate second. Key rotation takes two minutes and eliminates ongoing risk. Investigating usage logs can happen afterward.
Updating
.gitignorebut not untracking.envwith git rm --cachedHow to fix it: If
.envwas already tracked,.gitignorealone does not remove it from tracking. Run git rm --cached.envto explicitly untrack it.Forgetting to update the hosting platform with the new key
How to fix it: The old key is revoked. If the hosting platform still has the old value, your deployed app will fail. Update the environment variable and redeploy.
Not checking for unauthorized usage after rotating
How to fix it: Review provider dashboards for unusual activity during the exposure window. Promptly-reported misuse is often reversible by the provider.
Copy-ready prompt
Prompt: recover from a committed API key
Paste this into Cursor, Claude, ChatGPT, Bolt, Lovable, or your AI coding tool.
Ready to paste
An API key was accidentally committed to GitHub. Help me recover safely. Tasks: 1. Search the codebase for the committed key value and any other hardcoded secrets or API key patterns. 2. Replace all hardcoded key values in source files with environment variable references (process.env.KEY or equivalent). 3. Verify .env is in .gitignore. Add it if missing. 4. Check whether .env is currently tracked by Git. If so, run git rm --cached .env. 5. Create or update .env.example with placeholder values for every variable in .env. Do not copy real values. 6. List all keys I need to rotate in their provider dashboards. 7. List the hosting platform environment variables I need to update after rotating. 8. Summarize every file you changed.
Paste this into Cursor, Claude, ChatGPT, Bolt, Lovable, or your AI coding tool.
Ready check
Beginner checklist
- Rotated every key that was in the committed file — old keys are revoked
- New key values added to local
.envonly - Old key values removed from all source files,
README, and documentation .envis listed in.gitignore- git rm --cached
.envrun if.envwas previously tracked .env.examplecreated with placeholder values — committed to GitHub- Hosting platform environment variables updated with new key values
- App redeployed and tested on live URL
- Provider usage dashboards checked for unexpected activity
- Git history cleanup completed (optional but recommended for team projects)
Frequently asked questions
- How do I know if my key has already been used by someone else?
- Check the provider's API usage dashboard or logs. Look for requests during the period when the key was exposed — from the time of the commit to when you rotated. Unexpected volumes, unfamiliar endpoints, or activity you did not initiate are warning signs.
- Can I just make the GitHub repo private?
- Making the repo private helps, but the key is still accessible to anyone who cloned it before you switched. It is also not sufficient protection for collaborators or future visibility changes. Always rotate regardless of repository visibility.
- The key was only committed for five minutes before I caught it. Am I safe?
- Automated scanners can find keys within seconds. Five minutes is enough time for a key to be discovered and misused. Rotate it as if it were exposed for days — the rotation cost is trivial and the protection is complete.
- Do I really need to clean Git history, or is rotation enough?
- Rotation is the critical step. History cleanup is good hygiene and reduces long-term risk (future developers stumbling on old keys in history, GitHub's searchability), but it is not urgent once the key is revoked.
- What if I cannot find where to rotate the key in the provider's dashboard?
- Search the provider's documentation for 'rotate API key', 'regenerate key', or 'revoke key'. Most providers have this in their API or developer settings section. If you cannot find it, contact the provider's support immediately and explain that a key was exposed — they can help.