Best practice and common sense (if there is a difference between the two) dictate that storing secret information like API keys in your repository is bad.
Keeping .env.production
encrypted is an effective way to prevent malicious actors and developer mistakes from impacting the stability of your application.
To keep the env file secure, we must have a secure password which will be stored and distributed outside of the repository.
strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 32 | tr -d '\n'; echo
Save the generated password to the base of your laravel project in a file named .envkey
.
Only the most trusted developers and production machines should get the key.
When everything is complete, your env files will look something like this.
\ # base_path()
| .env # your local config
| .envkey # secret key file
| .env.production # plaintext production env file (.gitignored)
| .env.production.enc # encrypted production env file (source controlled)
Add app/Console/Commands/EnvEncrypt.php
.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class EnvEncrypt extends Command
{
protected $signature = 'env:encrypt';
protected $description = 'Encrypt production environment variable file';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$crypt = \Illuminate\Encryption\Encrypter(Decrypt::getKeyFileContents());
$path = \base_path('.env.production');
$text = \file_get_contents($path);
$enc = $crypt->encrypt($text);
\file_put_contents($path . '.enc', $enc);
$this->info("Encypted environment file");
}
}
Add app/Console/Commands/EnvDecrypt.php
.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class EnvDecrypt extends Command
{
protected $signature = 'env:decrypt';
protected $description = 'Decrypt production environment variable file';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$crypt = \Illuminate\Encryption\Encrypter(self::getKeyFileContents());
$path = \base_path('.env.production');
$enc = \file_get_contents($path . '.enc');
$dec = $crypt->decrypt($enc);
\file_put_contents($path, $dec);
$this->info("Decrypted environment file");
}
public static function getKeyFileContents(): string
{
return trim(\file_get_contents(\base_path('.envkey')));
}
}
Encryption and decryption functions can be accessed via artisan commands.
Always be sure to freshly run env:decrypt
before making changes so that any other developer changes in .env.production.enc
are not reversed.
php artisan env:encrypt # .env.production -> (encrypt) -> .env.production.enc
php artisan env:decrypt # .env.production <- (decrypt) <- .env.production.enc
Add this to any relevant sections of your Envoy.blade.php
to decrypt and overwrite the contents of .env
with .env.production
.
php artisan env:decrypt ; cp -fv .env.production .env
Now that you are following best practices, its time to atone for past mistakes.
.env.production
from source control.env.production
to .gitignore
or whatever you have to do to exclude this file from source control