Security Tip: Yes, Your .Env Is Secure Enough!
[Tip #109] I get asked this all the time, so it's time to set the record straight: there is nothing insecure about storing your credentials in a .env, as long as you keep your .env protected!

I was asked a question over on Twitter recently:
Stephen I would like your opinion on the security of plain text creds on an the .env file. Even when you use a key vault to store credentials instead of the .env when the configuration gets cached those credentials will be stored on /boostrap/cache/config.php, [which] defeats the purpose of not storing creds in plain text anyway.
This is a fairly common question, especially from folks coming from outside the PHP community where app credentials are often handled differently, and there is a lot of rhetoric in the "security community" about not storing credentials in plain text files (i.e. Laravel's .env
). It's actually something we've touched on a few times.
But let's set the record straight...
There is nothing insecure about storing plain-text credentials in your .env file!
Under the following conditions:
- Your
.env
is kept outside your web root. - You don't commit your
.env
file (or store keys directly in code). - You don't store or use production keys outside production (except in a password manager).
If you follow all three of these conditions, your production keys should only be found on your server, and only accessible by someone who has access to all of the files on your server - which should only be you/your sysadmin.
"What if someone gets access to the file?"
This is the most common reason given for not storing plain-text credentials in a .env
. However, it's a flawed argument, because to do so they'd need file access to the server. If someone can access your server, they can read all of the files on the server, giving them access to a lot more than one .env
file. By that point, it's already game-over.
If you're still not convinced, it's worth considering that PHP is a stateless language, which handles each individual request as a separate process - without remembering anything between the requests. This means every single web request needs to boot up the app, read the creds, and then do the work. If you're storing the creds off in some third-party encrypted store - PHP still needs some way to unlock the store and retrieve the creds on each request. Sounds like some form of credential still needs to be present? Unless it's unlocked for the server or maybe process environment variables - but if someone can access the files on the server, they can probably find where this is configured/stored too... I could go on, but the levels of needless complexity becomes overwhelming beyond this point.
Save yourself the effort of trying to invent a more secure system, store your credentials in .env
, and just secure your server.
If you feel differently, please head to the comments and we can continue the discussion. I'd love to dive deep into it, if you think I'm overlooking or simplifying this topic.
If you found this security tip useful, subscribe to get weekly Security Tips straight to your inbox. Upgrade to a premium subscription for exclusive monthly In Depth articles, or drop a coin in the tip jar to show your support.
When was the last time you had a penetration test? Book a Laravel Security Audit and Penetration Test, or a budget-friendly Security Review!
You can also connect with me on Bluesky, or other socials, and check out Practical Laravel Security, my interactive course designed to boost your Laravel security skills.