aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Tools & DevOps

.env File Management: Keeping Secrets Safe in Projects

An env file is the most common way to store the secrets your project needs to run but that should never enter the code repository: API keys, database passwords, tokens. The idea is simple: you separate configuration from code. The same codebase runs with different values on your development machine, in a test environment and on the live server; the only thing that changes is the .env file in that environment. In this article I cover the practical rules for managing .env files safely, the mistakes people make most often, and what to do when a secret leaks.

Why use a .env file?

Writing secrets straight into your source code (hardcoding) is one of the most common security flaws. The moment you embed an API key in config.php and push it to Git, that key is baked into the entire history of the repository; even after you delete it, it still sits in the commit log. A .env file solves this by keeping secret data completely outside version control.

  • Separation: the code can be public, the secrets cannot.
  • Per-environment values: local, staging and production connect to different databases and keys.
  • Easy rotation: changing a key means updating a single line, with no code deployment required.

The structure of a .env file

The format is a plain KEY=value list; each line is one variable. Most libraries support comment lines that start with #.

# Application
APP_ENV=production
APP_DEBUG=false

# Database
DB_HOST=127.0.0.1
DB_DATABASE=portfolio
DB_USERNAME=app_user
DB_PASSWORD=a-very-secret-password

# Third-party services
STRIPE_SECRET=sk_live_xxx
MAIL_PASSWORD="a value with spaces needs quotes"

A few practical points: if a value contains spaces or special characters, wrap it in double quotes; don't put unnecessary spaces around the equals sign; and values are always read as a string. That means APP_DEBUG=false is really the text "false", not your language's false boolean. Converting it to the right type is your job; for example Laravel's env() helper automatically casts values like true/false/null, while a bare getenv() does not.

The most important rule: .env never enters Git

Accidentally committing a .env file is the number one cause of secret leaks. The way to prevent it is to add a line to a .gitignore at the project root:

# .gitignore
.env
.env.*
!.env.example

The !.env.example line exempts the example file (which I'll explain shortly) from the blacklist. If you have already committed the file by mistake, adding it to .gitignore is not enough — Git is already tracking it. To stop tracking it:

git rm --cached .env
git commit -m "stop tracking .env"

Keep in mind: this command does not erase the file from history, it only stops tracking it in future commits. If the secret really entered a public history, see the leak section below.

Keeping the team in sync with .env.example

Since the real .env is not in the repo, how will a new developer who clones the project know which variables are needed? The answer is the .env.example file (sometimes .env.sample): it contains the same keys but the values are empty or fake. This file does go into the repo and acts as a form of documentation.

# .env.example
APP_ENV=local
APP_DEBUG=true
DB_HOST=127.0.0.1
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
STRIPE_SECRET=

The setup step is usually simple: copy the file with cp .env.example .env and then fill in the real values. Make it a habit to update the example file whenever you add a new variable; otherwise a teammate's setup breaks on a missing key they'll spend hours hunting down, wondering "why doesn't it work?".

Safe use on servers and in CI/CD

On live servers, restrict the file permissions of .env so only the user running the application can read it:

chmod 600 .env

On shared hosting or a VPS, make sure the file sits outside the web root (for example public/); otherwise a misconfigured server could serve it as plain text. In CI/CD pipelines (GitHub Actions, GitLab CI), instead of putting a .env file in the repo, use the platform's secrets / environment variables feature. These secrets are stored encrypted, masked in logs, and injected as environment variables only while the pipeline runs. In larger setups, dedicated secret managers like HashiCorp Vault, AWS Secrets Manager or Doppler come into play.

  • Never echo secrets into pipeline logs.
  • Don't distribute production secrets to developers' local machines; use separate, less privileged keys.
  • Rotate keys at regular intervals.

What to do if a secret leaks

Say an API key accidentally ends up in a public commit. The first and most important step is not cleaning the file from history — it's to revoke the key immediately and generate a new one. A leaked secret can survive in clones and caches that others copied even after you remove it from history; the only safe assumption is that it must now be treated as invalid.

Once you have rotated the key, you can clean the history with git filter-repo (Git's recommended modern tool) or the BFG Repo-Cleaner. After that a force-push is required and the whole team has to re-clone the repository. To prevent such accidents in the future, you can add tools like git-secrets or gitleaks as a pre-commit hook; they catch secret patterns at commit time and warn you.

Frequently Asked Questions

Should I encrypt my .env file?

For local development it usually isn't necessary; file permissions and .gitignore are enough. But if you need to share secrets in the repo, Laravel's built-in php artisan env:encrypt command, or tools like git-crypt and sops, let you store an encrypted .env. The decryption key must still live somewhere safe.

What's the difference between .env and real environment variables?

The .env file is a convenience: it mimics the operating system's environment variables from a file. In production many platforms prefer to define variables directly at the system level (server panel, container environment, a secrets service); in that case you don't need a .env file at all, which lowers the leak risk even further.

Can I keep separate files for multiple environments?

Yes, it's a common pattern: .env.local, .env.staging, .env.production and so on. The framework or a tool (such as Vite, Next.js or Laravel) picks which one to load based on the environment. Just remember to add all variants that contain real values to your .gitignore.

Are your secrets safe? If you need help with configuration management, deployment or the secure setup of a project, get in touch with me — let's build a solid foundation together.

Bu kategorideki tüm yazılar →

Devamı için