Small teams rarely lose secrets through sophisticated attacks. They lose them by pasting a key into a group chat, committing an environment file, or sharing a screenshot with a token visible. Once a secret has been in any of those places, treat it as public.

Where secrets should live

Every serious hosting platform has an encrypted secret store with a command-line interface. Use it. Secrets set this way are never written to your repository, never appear in a build log, and are prompted for rather than typed into a shell that records history.

Git history is permanent

Deleting a secret in a later commit does not remove it. It remains in the history, and in every clone and fork. If a key was ever committed, rotate it — rewriting history is disruptive and unreliable, and rotation is both faster and more complete.

Scope and separation

  • Use the narrowest permission the integration needs. A key that only sends email should not be able to read or delete.
  • One key per integration, so any single revocation has a contained blast radius.
  • Separate keys for development and production. Test data belongs in test accounts.
  • Record what each key is for and who created it — unlabelled keys never get rotated because nobody knows what they will break.

Rotation in practice

Rotate on a schedule, and immediately whenever someone leaves, a laptop is lost, or a key appears anywhere it should not. Add a secret scanner to your pre-commit hooks or pipeline so the common mistake is caught before it reaches a remote. And make rotating a key a routine, boring operation — if it is frightening, it will not happen when it matters.