What a secret is
A secret is data that proves identity or grants access: a database password, an API key, a cloud access key, a GitHub token, a TLS or SSH private key, a connection string. Whoever holds a secret has its rights, with no need to know who you are.
How secrets leak
- Hard-coded in source:
DB_PASSWORD = "changeme-example". - Committing a
.env,terraform.tfstate,kubeconfigor private key by mistake. - Printing them into CI logs, error messages or screenshots.
- Sending them over chat, email or tickets.
- Baking them into Docker images (a
COPY .envor anENVholding a secret).
Bots scan public GitHub constantly; a cloud access key pushed to a public repo can be used for crypto mining within minutes. Deleting the file in a later commit is not enough: the secret still lives in Git history.
git log --all -p -S "DB_PASSWORD" # find commits that ever contained the string
The secret lifecycle
flowchart LR C["Create"] --> S["Store in a vault<br/>encrypted, access-controlled"] S --> D["Deliver to the app<br/>at runtime"] D --> R["Rotate"] R --> S D --> X["Revoke when leaked<br/>or unused"]
General rules:
- Never keep secrets in code, images or Git; apps read them at runtime from environment variables, mounted files or a secret manager API.
- Store them centrally in a secret manager with encryption, access control and audit logs.
- Rotate regularly and immediately on suspicion; prefer short-lived secrets that expire on their own.
- Give each app and environment its own secret so revoking one does not break others.
When a secret has leaked
The right order: revoke or rotate first at the system that issued it, check logs for misuse, then clean Git history (git filter-repo) and report. Rewriting history without rotating leaves the secret valid in every clone and fork.
| Job | Example tools |
|---|---|
| Detect | gitleaks, GitHub secret scanning, trufflehog |
| Store and issue | HashiCorp Vault, AWS Secrets Manager, Azure Key Vault |
| In the cluster | Kubernetes Secret, External Secrets Operator |
| In pipelines | GitHub Actions secrets, OIDC |
A local .env file is still handy on a dev machine, but it must be in .gitignore, have mode 600 and hold only dev values.