What to Do When Your API Keys End Up in a Repo
You pushed code to GitHub and realized seconds later that your API key went with it. Maybe GitHub sent you an alert. Maybe GitGuardian emailed you. Either way, you’re now dealing with exposed secrets in frontend apps—and the clock is ticking.
Here’s the critical thing most developers get wrong: removing the key from your latest commit doesn’t fix the problem. Git history preserves everything. Forks may already exist. Automated bots scan public repositories within seconds of a push.
This article covers exactly what to do when API keys are leaked on GitHub, how to distinguish between truly sensitive secrets and public client keys, and how to prevent this from happening again.
Key Takeaways
- Revoke and rotate exposed secrets immediately—cleaning up Git history is secondary since the key is already compromised.
- Distinguish between public client keys (designed for browser use) and true secrets (privileged credentials that require urgent action).
- Git history preserves everything, so deleting a commit doesn’t remove the secret from forks, caches, or existing clones.
- Enable GitHub’s push protection to block commits containing secrets before they reach your repository.
- Never store privileged keys in frontend code—use server-side API routes or backend proxies instead.
First, Understand What You Actually Exposed
Not all keys carry the same risk. Before you panic, identify what type of credential leaked.
Public client keys are designed to be visible. Google Maps API keys restricted to specific domains, analytics tokens, or keys explicitly prefixed for client-side use (like NEXT_PUBLIC_ in Next.js or VITE_ in Vite) are meant to ship in browser bundles. These should still have usage restrictions, but exposure isn’t catastrophic.
True secrets grant privileged access: Stripe secret keys, AWS credentials, database connection strings, or any key that can read/write sensitive data or incur charges. These require immediate action.
The distinction matters because your response should match the severity.
Immediate Response: Revoke and Rotate First
When you’ve leaked a true secret, history cleanup is secondary. Your first priority is rotating compromised API keys.
Step 1: Revoke the exposed key immediately. Log into your API provider’s dashboard and delete or disable the compromised credential. Don’t wait until you’ve cleaned up Git history—the key is already compromised.
Step 2: Generate a new key with minimal scope. Apply the principle of least privilege. Restrict by IP, domain, or specific API endpoints where possible.
Step 3: Update your application. Deploy the new key to your environments before your app breaks.
Some cloud providers automatically disable credentials they detect in public repositories. For example, Google Cloud can automatically disable exposed service account keys by default. Others, including AWS, typically notify you but do not consistently revoke keys automatically. All of these providers participate in GitHub’s secret scanning partner program. Don’t rely on automation—act immediately anyway.
Why Deleting the Commit Isn’t Enough
Git never forgets. Even if you remove the secret from your current branch, it lives in:
- Previous commits accessible via
git log - Forks created before your fix
- Existing clones pulled by other users or bots
- Any mirrors made before removal
This is why revocation comes first. History cleanup is containment, not remediation.
If you need to scrub history, tools like git filter-repo or BFG Repo-Cleaner can help. But understand that if your repo was public for any length of time, assume the secret was captured.
Discover how at OpenReplay.com.
GitHub Secret Scanning and Push Protection
GitHub offers first-class protection against this exact problem. Secret scanning and push protection are available for all public repositories and for private repositories via GitHub Secret Protection (also bundled in GitHub Advanced Security).
Secret scanning detects known credential patterns in your repository and alerts you and/or the provider automatically.
Push protection goes further—it blocks commits containing detected secrets before they reach the repository. This is the single most effective prevention mechanism available.
Enable both in your repository settings under Settings → Code security and analysis, or see the official documentation on GitHub Secret Protection.
The Frontend Environment Variable Trap
Here’s a mistake that catches many React, Vue, and Next.js developers: environment variables prefixed for client use are not secrets.
Variables like REACT_APP_*, NEXT_PUBLIC_*, or VITE_* get bundled directly into your JavaScript. Anyone can open DevTools and find them. These are not hidden—they’re just organized.
If a key grants privileged access, it cannot live in frontend code. Period.
Prevention Strategies for Frontend Teams
Keep privileged keys server-side. Use API routes, serverless functions, or a backend proxy. Your frontend authenticates users; your backend holds the secrets.
Enable push protection. This catches mistakes before they become incidents.
Use pre-commit hooks. Tools like gitleaks or detect-secrets scan staged changes locally.
Add CI scanning. Run secret detection in your pipeline as a safety net.
Restrict keys aggressively. Even public client keys should be limited by domain, IP, or API scope.
Conclusion
When API keys leak, speed matters more than perfection. Revoke first, rotate immediately, then clean up history as a secondary step. Don’t confuse public client keys with true secrets, and never trust environment variables to hide anything in frontend builds.
Enable GitHub’s push protection today. It’s the easiest way to ensure this problem never happens again.
FAQs
Revoke or disable the exposed key immediately through your API provider's dashboard. Do not wait to clean up your Git history first. The key is already compromised the moment it was pushed to a public repository, and automated bots can capture it within seconds. After revocation, generate a new key and update your application.
No. Git preserves all history, so the secret remains accessible in previous commits, forks, existing clones, and any copies made before your fix. Deleting or amending the commit only removes it from the current branch tip. You must revoke the key regardless of any history cleanup you perform afterward.
No. These prefixed environment variables are bundled directly into your frontend JavaScript and are visible to anyone who opens browser DevTools. They are meant for public configuration values, not secrets. Any key that grants privileged access must be stored server-side and accessed through API routes or backend proxies.
Enable GitHub push protection to block commits containing detected secrets before they reach your repository. Use pre-commit hooks with tools like gitleaks or detect-secrets to scan changes locally. Add secret detection to your CI pipeline as an additional safety net. These layers work together to catch mistakes early.
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.