Managing Secrets
Commit one API key and a bot has it before your CI finishes.
What you will learn
- -Keep credentials out of source, config, and build artifacts
- -Choose between env vars and a real secrets manager
- -Detect leaked secrets in git history and respond by rotating
Push an AWS key to a public repo and you can watch it used from a country you have never visited, sometimes within minutes. GitHub's scanning, plus a dozen independent crawlers, watch every public commit as it lands. The scary part is not the exposure. It is that deleting the file does nothing, because the key still sits in every commit, every clone, and every fork.
That single fact drives the whole topic. A secret in git history is compromised the moment it is pushed, and the only real fix is to rotate it. Prevention is cheap. Cleanup is not.
Secrets never live in source
The rule is blunt on purpose: no belongs in code. Not hardcoded in a constant, not in a config file you commit, not baked into a with ENV API_KEY=, and absolutely not in a front-end bundle where every visitor can read it in devtools. If it authenticates you to something, it stays out of the tree.
What counts as a secret is broader than . keys, database connection , signing keys, OAuth secrets, , and webhook signing secrets all qualify. If leaking it lets someone act as you or read data they should not, treat it like a password.
The local pattern is a .env file that is listed in .gitignore, paired with a committed .env.example that has the keys but placeholder values. New developers copy the example, fill in real values, and the real ones never touch the repo.
Env vars are the floor, a manager is better
Environment variables are the minimum viable answer and they follow the twelve-factor approach: config, including secrets, comes from the environment, not the code. Good enough for a small service. The weakness is that env vars are static, visible to the whole process, and often end up in , crash dumps, and docker inspect output.
A secrets manager is the step up. Vault, AWS Secrets Manager, and Google Secret Manager hand out credentials on request, log every access, and can issue short-lived credentials that expire on their own. A database password that lives for one hour is a much smaller problem than one that has been the same since 2021. Reach for a manager once you have more than a couple of secrets or any requirement.
Find leaks before an attacker does
You cannot fix what you cannot see, so scan your history. Tools like gitleaks and trufflehog walk every commit and flag anything that looks like a credential, using both pattern matching and checks for random-looking strings.
$gitleaks detect --source . --verbose$trufflehog git file://. --only-verified$git log -p -S 'AKIA' -- .Running gitleaks and trufflehog on your repositories, or ones you are authorized to , is exactly what they are for. Harvesting leaked keys out of strangers' public repos and using them is unauthorized access to their accounts, which is a crime regardless of how easy the key was to find. Finding a leak in the wild means you report it, you do not use it.
Rotate, do not just delete
When a secret leaks, the first move is to rotate it: generate a new credential and revoke the old one at the provider. Removing the secret from the current file, or even scrubbing history with git filter-repo or BFG, does not help, because you have to assume every clone already captured it. Scrub history to stop future leaks if you like, but rotation is what closes the actual hole. Delete without rotating and you have only hidden the evidence.
You discover an API key was committed to your repo three months ago. What is the correct first action?