A 2023 GitGuardian audit of 200 open-source projects found exposed secrets in 1 in 10 projects. API keys hardcoded in source files, committed .env files, tokens leaking in CI/CD logs — the mistakes are almost always the same. Here are the 8 most common errors developers make when securing API keys in production, with the fix for each one.
Mistake #1 — Hardcoding the API Key in Front-End Code
The classic mistake. The key is visible in your HTML or in a JavaScript file downloaded by the browser. Anyone can extract it with DevTools in 30 seconds.
// ❌ NEVER do this
const apiKey = "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const map = new google.maps.Map(document.getElementById('map'), {
zoom: 8,
key: apiKey
});
The fix: For front-end APIs like Google Maps, use HTTP referrer restrictions in Google Cloud Console (APIs & Services → Credentials → Edit API Key → HTTP referrers). The key will be visible, but unusable from another domain. For APIs that don’t need to be client-side, create a backend proxy.
Mistake #2 — Committing a .env File to Git
Your .env file contains local secrets. If you commit it by accident — even once, even to a private repo — the secrets are in Git history forever. Bots scan GitHub continuously and find these keys within minutes.
# Check if .env is in your .gitignore
cat .gitignore | grep .env
# If .env was already committed, remove it from history
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch .env" \
--prune-empty --tag-name-filter cat -- --all
# Force push (coordinate with your team)
git push origin --force --all
The fix: Add .env and .env.local to your .gitignore from day one. Only commit a .env.example file with dummy values. Use a secrets manager (AWS Secrets Manager, Google Secret Manager, HashiCorp Vault, Doppler) for shared environments.
Mistake #3 — One Key for Everything
A single key managing production, staging, development, and CI/CD. If it leaks, everything is compromised. And auditing who uses what becomes impossible.
The fix: Create one key per environment and per use case. Production, staging, and development each get their own key. CI/CD gets its own key with minimal permissions (read-only if possible). Configure each key with restrictions appropriate to its context.
Mistake #4 — Keys Without API Scope Restrictions
A Google Cloud key without API scope restrictions can call any API enabled on your project. If your Maps key is stolen, it can potentially access Cloud Storage, Cloud Functions, or Cloud Run if they’re enabled on the same project.
The fix: In APIs & Services → Credentials → Edit API Key → API restrictions, select “Restrict key” and add only the APIs that key actually needs. Principle of least privilege applied to keys.
Mistake #5 — No Key Rotation
A key that’s never rotated may have been exposed without your knowledge — in a log, an error stacktrace, a debug email. The longer a key lives, the higher the risk of silent exploitation.
# Create a new version of a secret in Google Secret Manager
echo -n "NEW_API_KEY" | gcloud secrets versions add my-secret \
--data-file=- \
--project=YOUR_PROJECT_ID
# Disable the old version
gcloud secrets versions disable 1 \
--secret=my-secret \
--project=YOUR_PROJECT_ID
Mistake #6 — No API Call Monitoring
Without monitoring, a compromised key can be used for weeks without you knowing. You discover the problem on next month’s bill.
The fix: Set up Cloud Monitoring alerts on API call counts. In Monitoring → Alerting → Create Policy, create an alert when call volume exceeds your normal baseline × 2.
Mistake #7 — Exposing Keys in CI/CD Logs
GitHub Actions, CircleCI, or GitLab CI build logs are sometimes public. If your workflow prints environment variables — even accidentally via an echo or a stacktrace — the keys are exposed.
# ❌ NEVER do this in CI/CD workflows
run: echo "API Key: $API_KEY"
# ✅ Use GitHub Actions secrets
# In Settings → Secrets → Actions → New repository secret
# Then in your workflow:
jobs:
deploy:
steps:
- name: Deploy
env:
API_KEY: ${{ secrets.GOOGLE_API_KEY }}
run: ./deploy.sh # Secret never appears in logs
Mistake #8 — No Documented Incident Runbook
When a key leaks at 11 PM on a Friday, nobody knows what to do. Every minute of panic costs money. The absence of a runbook is an operational error as much as a technical one.
The fix: Document an incident procedure that answers: Where are all the project’s API keys listed? Who has permissions to revoke them? What’s the Google support contact? How do we re-enable billing after a kill switch? This procedure should fit on one page and be accessible to the whole team at any hour.
Summary Checklist
- ☑ Front-end keys restricted by HTTP referrer
- ☑ .env in .gitignore, secrets in a dedicated manager
- ☑ One key per environment and per use case
- ☑ API scope restrictions on all keys
- ☑ Monthly or quarterly rotation
- ☑ API call monitoring with anomaly alerts
- ☑ CI/CD secrets via native vaults (GitHub Secrets, etc.)
- ☑ Incident runbook documented and accessible
🔐 Not sure your API keys and cloud configuration are secure?
Klack offers a complete security audit: exposed key detection, billing limit setup, automatic alerts, and kill switch implementation. Response within 24-48 hours.

