Lesson 10 / 31
How Secrets Leak
Identify the common ways API keys and passwords leak and explain why deleting a committed secret is not enough.
By Rahul Agarwal · 15 years in web development
Secrets travel further than you think
A secret is any value that grants access: API keys, database passwords, cloud access keys, private keys, OAuth client secrets, webhook signing keys. They leak in predictable ways: hard-coded in source, committed in a .env file, printed in CI logs, baked into a container image layer, pasted into a ticket or chat, or stored in a frontend bundle that every visitor downloads. The most misunderstood case is Git. When you delete a secret in a new commit, it still exists in history, and every clone and fork already has a copy. Automated bots scan public repositories continuously, so a leaked cloud key can be abused within minutes. The correct response to a leaked secret is therefore always the same order: revoke and rotate it first, check access logs for misuse, then clean history if needed. Rewriting history alone does not make a leaked key safe.
The life of a secret
A safe secret lifecycle runs from creation in a secret store, to injection at runtime, to regular rotation, to revocation when it is no longer needed or has leaked.
Proving the secret is still in history
Deleting the line does not delete the past. git log -p shows the old diff.
git init -q demo && cd demo
git config user.email dev@example.com && git config user.name dev
echo 'API_KEY=demo-not-a-real-key-123' > .env
git add .env && git commit -qm "add config"
git rm -q .env && git commit -qm "remove secret"
test -e .env || echo ".env is gone from the working tree"
git log -p --all | grep 'API_KEY'
Output:
.env is gone from the working tree -API_KEY=demo-not-a-real-key-123 +API_KEY=demo-not-a-real-key-123
Docker layers remember too
COPY .env . followed by RUN rm .env still leaves the file in an earlier image layer. Use build secrets (RUN --mount=type=secret) and a .dockerignore instead.
Quick check: You notice a cloud access key was pushed to a public repository an hour ago. What should you do first?
- Rewrite Git history to remove it
- Revoke and rotate the key, then review its usage logs
- Make the repository private and continue
- Add the file to .gitignore
Answer
Revoke and rotate the key, then review its usage logs — Once public, assume it is compromised. Revoking stops abuse; history cleanup and prevention come after.