Keep Credentials Out of the Repository Entirely

Using environment variables for secrets.

I still remember the 3:00 AM page from my old hosting days that nearly made me quit the industry altogether. I was staring at a terminal, watching a client’s entire database get wiped because they had pushed a configuration file containing their root credentials directly to a public GitHub repo. It wasn’t some sophisticated zero-day exploit or a nation-state actor; it was just a human error born from laziness. People act like securing a stack requires a massive, expensive vault system, but most of the time, you just need to stop hardcoding your credentials and start using environment variables for secrets.

I’m not here to sell you on a complex enterprise security suite that costs more than your monthly hosting bill. My goal is to show you how to do this the right way using the tools you already have. I’ll walk you through the practical, boring, and highly effective methods for managing your keys so you don’t end up as a cautionary tale in my notebook. We are going to focus on implementing simple workflows that actually work in production, because a secure system is a system that stays online.

The Fatal Flaw of Dotenv File Security Risks

The Fatal Flaw of Dotenv File Security Risks

Look, I get it. Using a `.env` file feels easy. You drop it in your root directory, list your keys, and suddenly everything works. It’s the path of least resistance, which is exactly why it’s dangerous. The biggest issue I see isn’t the file itself, but the human error surrounding it. Someone forgets to update the `.gitignore` file, or a junior dev accidentally commits that `.env` to a public GitHub repo, and suddenly your entire infrastructure is wide open. Once those credentials hit a public repository, you aren’t just dealing with a minor bug; you are dealing with a total compromise of your production environment.

Even if you manage to keep the file out of version control, you’re still playing a risky game with local file storage. If a malicious actor finds a way to exploit a directory traversal vulnerability on your server, that `.env` file is sitting there like a gift-wrapped invitation to your database. Relying on a flat file for protecting API keys in production is a lazy habit that ignores the reality of modern server security. It’s a single point of failure that most people don’t realize they’ve created until the logs show unauthorized access from a country they don’t even do business with.

Protecting Api Keys in Production Before They Leak

Protecting Api Keys in Production Before They Leak

Once you realize that a `.env` file sitting in your web root is basically a ticking time bomb, you need a real plan for protecting API keys in production. Moving away from local files isn’t just about being “extra secure”; it’s about ensuring that a simple misconfigured directory listing doesn’t hand your database credentials to a bot in seconds. In a production environment, your secrets should exist only in the system’s memory, injected at the moment the process starts.

The most reliable way to handle this is by leveraging cloud provider secret managers like AWS Secrets Manager or HashiCorp Vault. These tools are designed specifically for secure secret management best practices, allowing you to rotate keys automatically without manually updating a dozen config files. If you are running containers, use the orchestration layer to inject these values directly into the runtime. It might feel like overkill when you’re just trying to get a site live, but trust me: preventing credential leakage is a lot easier than explaining to a client why their entire server cluster was hijacked because of a stray text file.

Five ways to stop treating your secrets like public knowledge

  • Stop committing your .env files to Git. I’ve seen enough repos leaked on GitHub to know that “I forgot to add it to .gitignore” is the most expensive mistake you can make.
  • Use your hosting provider’s native dashboard. Whether it’s Heroku, Vercel, or a VPS, use their built-in environment variable settings instead of trying to manage local files in production.
  • Implement a “Least Privilege” approach. Your staging environment doesn’t need your production Stripe keys. If the staging site gets compromised, you shouldn’t be losing real money.
  • Automate your secret rotation. If a key stays the same for three years, it’s not a secret; it’s a liability. Set a schedule to cycle your credentials so a leak doesn’t become a permanent catastrophe.
  • Audit your logs for accidental leaks. Check your application logs to ensure you aren’t inadvertently printing your entire environment object to a text file when an error occurs. That’s just handing the keys to the intruder.

The Bottom Line

Stop relying on .env files in production; they are a convenience for local dev, but in a live environment, they are just one misconfigured permission or accidental git push away from a disaster.

Use your hosting provider’s native environment variable settings or a dedicated secret manager to inject credentials directly into the process memory where they belong.

Treat every API key and database password like a physical key to your office—if it’s just lying around in a plain text file on the disk, you haven’t actually secured anything.

Stop Playing Russian Roulette with Your Credentials

Stop Playing Russian Roulette with Your Credentials.

At the end of the day, managing secrets isn’t about being fancy or following some complex security framework just to look good on a resume. It’s about the basics: stop relying on `.env` files in production, stop committing keys to Git, and start using your environment variables the way they were intended. We’ve talked about why hardcoding is a death sentence and why your deployment pipeline needs to be the gatekeeper, not your source code. If you take nothing else from this, remember that security is a series of small, boring habits that prevent massive, expensive disasters. It is much easier to set up a proper secret management workflow now than it is to rebuild your entire infrastructure after a leaked key has been scraped by a botnet.

I’ve spent enough nights being paged at 3:00 AM to know that most “security breaches” aren’t the result of genius hackers; they are the result of simple, preventable laziness. Moving your secrets into the environment might feel like an extra step in your workflow, but that extra step is exactly what keeps your site online and your clients’ data safe. Don’t wait for an outage or a leaked credential to force your hand. Do the boring work today so you don’t have to deal with the unnecessary chaos tomorrow. Get your secrets out of your code, get them into your environment, and then get back to building things that actually work.

Frequently Asked Questions

If I'm not using a .env file, where exactly am I supposed to input these variables so the application can actually see them?

You don’t type them into a file; you inject them directly into the environment where the process lives. If you’re on a VPS, you’d set them in your systemd service unit or your shell profile. If you’ve moved up to Docker, you pass them via the `–env` flag or the `environment` key in your Compose file. Most modern platforms, like Heroku or AWS, have a specific “Config Vars” or “Secrets Manager” UI for this. It’s cleaner, and more importantly, it’s actually secure.

Is it actually safe to store these variables in my CI/CD pipeline, or am I just trading one security headache for another?

It’s a trade-off, but a much smarter one. Moving secrets to your CI/CD pipeline—like GitHub Actions or GitLab CI—is significantly safer than committing a `.env` file to a repository. You’re moving from “publicly visible” to “controlled access.” However, it’s not a magic bullet. If your pipeline logs are too verbose or your team permissions are a mess, those secrets can still leak. Treat your CI/CD secrets with the same paranoia you’d give a root password.

At what point does my setup become too complex, and should I stop using basic environment variables and start paying for a proper secret manager?

Look, there isn’t a magic number of keys that triggers this, but there is a “complexity threshold.” If you’re managing more than five or six services and you’re starting to lose track of which `.env` file belongs to which staging environment, you’re asking for a midnight page. Once you move from a single site to a distributed architecture where multiple servers need the same credentials, stop playing around. Pay for a secret manager. It’s cheaper than a breach.

About Otieno Mbatha

Most hosting problems are not exotic. They are an expired certificate, a full disk, or a backup nobody tested. I write about the boring things because the boring things are what break.