Skip to main content

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:

bash
install -m 600 /dev/null /etc/myapp/env
# then edit /etc/myapp/env and reference it from the systemd unit

In 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

  1. Revoke it first — do not investigate before cutting off access.

  2. Create a replacement and update the consumers.

  3. Review usage logs for what the leaked key did.

  4. Find the leak (git history, a public gist, a client bundle) and fix the process.

  5. 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