API keys and secrets: handling them properly
Store, scope, rotate and revoke credentials without leaking them.
Most breaches that are not brute-force are a leaked credential. These habits prevent the common ones.
Never do this
Commit keys to git (even a private repo — history is forever, and repos get made public).
Put keys in client-side code (browser JS, mobile apps) — it is public by definition.
Paste keys into chat, tickets, or screenshots.
Email keys.
Reuse one key across many services or people.
Store them properly
On a server: an environment file with tight permissions, loaded by the service:
install -m 600 /dev/null /etc/myapp/env
# then edit /etc/myapp/env and reference it from the systemd unitIn a repo: a .env.example with placeholders committed, and the real .env git-ignored. Never the reverse.
For teams: a secrets manager (Vault, or a self-hosted Vaultwarden / Passbolt) rather than a shared spreadsheet or chat.
Scope keys to the minimum
One key per consumer — per app, per environment, per person.
Least privilege — read-only keys where write is not needed.
Per-environment keys — staging keys must not touch production data.
Rotate and revoke
Rotate on a schedule (quarterly is a reasonable default) and immediately whenever a key might have leaked.
Revoke unused keys. An unused key is pure risk with no upside.
Rotation should be a routine, not an emergency: practise it so it is not scary.
If a key leaks
Revoke it first — do not investigate before cutting off access.
Create a replacement and update the consumers.
Review usage logs for what the leaked key did.
Find the leak (git history, a public gist, a client bundle) and fix the process.
Rotate anything else that key could reach.
Scan your repos
A pre-commit hook or a secret scanner in CI catches the most common mistake — a key committed by accident — before it reaches the remote.
Related reading