Most personal [and production-level] project's structure can easily become too complicated as time progresses during development. This leads to over-burdening the .env
file, which should be avoided during large project lifecycles that can last for months.
Nearly all modern IDEs will try to automatically manage .env
settings for you. This is only done both for flexibility and security reasons, and there are still things that need to be considered to properly utilize this important file in your development environment.
This lead me to make a list from both various sources and personal opinions that best describes the top 6 proper use cases for managing an .env file.
1 .env - Permissions:
The standard permissions for an environment variable file used in most web application solutions like: React.js or Laravel or even Node.js should not be accessible outside /public.
Aside from being hidden by default in linux, the read-write access to the environment file is already pre-set in both linux or windows-based deployment setups by the corresponding coding platform that handles it.
This is also-known-as the default that your IDE development environment auto-generates for you on install.
In case that this does not happen a good ruleset to manually secure it would be:
- To have root-only owner access to the file.
- To set the group of that permission on the web server's directory (www-root, www-data for Ubntu/Debian).
- Enable permissions set to 640 on that .env file.
In a production environment, the permissions of the .env file are the corresponding set of the commands below:
chmod 400
or chmod 440
.
Also access must be even further blocked on the webserver side via the .htaccess
file.
2 .env - Source control:
It is not recommended by anyone to add an .env
file to github or any other publicly accessible source control services.
The best thing to do in order to exclude the .env
file from online automatic deployments is to be super-proactive and maybe create your own automation to generate the .gitignore
file with relevant entries before adding anything to source control.
This is for solutions that will based entirely on .env
file and store sensitive data and in cases that .env
files aren't excluded by the default .gitignore
.
An example of .gitignore for .env files..
.env*
.env.*
Or a more generic example below
**/*.env
Or an exclusion example for git..
/*
!.env
A generic .gitignore generator can also be found online -> here.
ALSO:
In the unlikely case that you run an internal custom source control environment and for whatever reason want to add an .env file, you can do so as long as the server is only locally hosted.
Even so, I would recommend to only add an .env.example
instead which is a shallow copy of the values of your completed .env
file that is required by your application.
3 .env - Direct usage in source:
When referencing or using some environment file stored API key or any other setting, try to use a built-in secure library either provided by your own solution's framework or by an external package manager.
Such an example is loading all environment config in Node.js:
require('dotenv').config(); //load all environment variables from main configuration.
process.env.ENV_NAME;
or in laravel by using helper function config() with config.php file that stores environment variables (below):
<?php
config('cfg_name'); # 'cfg_name' stores the variable by env('ENV_NAME'); in the config.php file
4 .env - Comments:
As environment variable files grow larger, the best thing you can do is add multiple urls or api key lists in a structured-format for easily finding and handling multiple values.
This can be easily achieved by using start-end blocks of comments and also inline find by adding specific characters to the start and end of each comment for each setting.
Example Comments here:
-START API section- -END API section- (for storing multiple api values).
<< IMPORTANT >> (for sorting out what should be considered important or not).
[[ TEMPORARY ]] [[ WILL BE REMOVED ]] (for indicating the importance level on parts that will be moved in a different setup of the application).
ALSO:
Avoid using a lot of comments in production files since these will not be changed or tampered with frequently and only add those during testing and debugging cycles on development.
5 .env - Encryption:
In case that you still feel that you cannot get enough security by methods mentioned, you can have the option of completely encrypting the contents of the important .env file of your solution.
In such a case, this needs to be done by the application level and not by the OS level for it to be effective.
A small listing and corresponding sample usages of .env encryption capabilities is found below:
1.Node.js/React.js Applications | npm's secure-env | Default is a decent AES-256 plain-text encryption standard for the file.
Sample Usage below:
Encryption (cmd-line):
$ npx secure-env .env -s mySecretPassword
Decryption (in-code):
require('secure-env')({path:'/custom/path/to/your/env/vars'});
2.Node.js/React.js Applications | npm's dotenvenc | Typescript-based encryption utility for js, produces .env.enc files.
Sample Usage below:
Encryption (cmd-line, .env must be in project root):
./node_modules/.bin/dotenvenc -e
Decryption (in-code):
require('dotenvenc').decrypt();
// From here on your app will have access to the secrets through process.env.DB_SECRET1 and process.env.SECRET_VAR1
3.Node.js/React.js Applications | using node:crypto modules | Manually written code + tutorial for encrypting .env file.
Sample usage on the website.
4.PHP/Laravel Applications | Laravel's official Docs | Built-in encryption standards for laravel web application solution to encrypt .env file using artisan commands.
Sample Usage below:
Encryption (cmd-line, multi environment targets):
php artisan env:encrypt
php artisan env:encrypt --env=staging
Decryption (cmd-line, using laravel encr. key):
php artisan env:decrypt
php artisan env:decrypt --key=EncryptionKeyHere...
Decrypting/Using all the values per file in this case implies the usage on the entire application file per deployment on the server or writing custom artisan command in-code to automate the encryption process.
NOTE THAT:
As always, there is a fair trade-off between security and usability when encrypting code files like above since these might be affected or blocked by filesystem permission sets and the comments might be affected if your encryption library does not properly handle comments in the .env file.
More encryption info HERE-MEDIUM and HERE-OWASP
6 .env - Virtual environments, debugging:
Last but not least, in case that there is no time to do all of the above, a container runner can still be used to deploy the entire application to run in its own protected area with minimal effect on your server's security configuration.
But simply not-using these set of standards still holds an additional security risk.
Containerization services that can always be used to easily build-up and tear-down virtual environments for staging and debugging without having to fully secure the .env in your solution are as below:
- Docker with docker-compose.yaml (some partial exposure to .env might be required).
- Kubernetes
- Red Hat OpenShift
- Microsoft Azure Kubernetes Services (AKS)
- Google Kubernetes Engine (GKE)
- Amazon's Elastic Kubernetes Service (EKS)
- IBM's Istio services (IBM)
As far as I'm concerned if you are using any containerization tool, tightly locking the .env file should be optional and makes more sense to be flexible during debugging and code testing. Sometimes things need to be flexible to make it easy for the developers to build an application in order to make it less error-prone and more secure.
Top comments (0)