Skip to main content
Security

Env files and secrets management: `.env` is configuration, not a vault

Keep local configuration convenient without turning Git history, CI logs, and container images into a long-lived archive of production credentials.

Thien Nguyen
By Thien Nguyen
Updated July 1, 2026 · 2 min read

.env files are useful because they make local setup boring. They become dangerous when a production secret survives in a commit, a Docker layer, a support archive, or a copied sample file for years.

Short answer: keep a committed .env.example with names and safe placeholders, keep real .env files ignored, inject production secrets from the deployment platform or a secret manager, and rotate anything that was committed—even if the repository is private.

Give every value a home

ValueGood homeWhy
LOG_LEVEL=debugVersioned config or .env.exampleNot sensitive; reviewable
Local database passwordIgnored local .envConvenient for a developer machine
Production API keySecret manager / platform secretAudited access and rotation
Browser-exposed public identifierBuild-time public configIt is not a secret—name it honestly
# .env.example — commit this
DATABASE_URL=postgres://app:password@localhost:5432/app
STRIPE_SECRET_KEY=replace-me

The example must be usable documentation, not a museum of variables no code reads. Validate startup configuration and fail with the variable name—not its value—when something is missing.

Base64 is not secret storage. Neither are encrypted files if the decryption key lives beside them in the same CI environment.

The incident response nobody enjoys

If a credential reaches Git, deleting the line is not remediation: clones, forks, caches, and prior commits may retain it. Revoke or rotate first, then remove it from current config, audit its use, and consider history cleanup as damage reduction rather than the fix.

For local hygiene, run a secret scanner in pre-commit and CI. For production, prefer short-lived workload identities over static keys when the platform supports them. The important property is not where a string is stored; it is who can retrieve it, how long it works, and how quickly you can revoke it.

Cover photo by Nathan Thomas on Pexels.

References

Primary documentation and specifications checked when this article was last updated.

SecurityConfigurationDevOps

Related articles

All articles