Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment encryption for non local environments fails since values are overloaded with env values from remote environment #44789

Closed
tomvo opened this issue Oct 31, 2022 · 5 comments
Assignees

Comments

@tomvo
Copy link

tomvo commented Oct 31, 2022

  • Laravel Version: 9.37.0
  • PHP Version :8.1.9
  • Database Driver & Version: -

Description:

When following the steps in the docs regarding .env encryption for non local environments here: https://laravel.com/docs/9.x/configuration#encrypting-environment-files the encryption fails since the ENV variables from the "to encrypt environment" are used.

In other words, i'm locally trying to encrypt the .env file that corresponds to our remote staging environment .env.staging using artisan env:encrypt --env=staging. It obviously contains values for servers I cannot access locally like Redis, DB, etc. When trying to encrypt it fails on a timeout trying to connect to our staging Redis server because CACHE_DRIVER=redis. When changing this value in .env.staging to CACHE_DRIVER=array the encryption works fine but it creates an encrypted .env.staging file with the wrong value for CACHE_DRIVER.

Steps To Reproduce:

  1. Create a .env.staging file with values from a remote server with unreachable Redis instance
  2. Try to encrypt the file using artisan env:encrypt --env=staging
  3. Fail
@joedixon
Copy link
Contributor

Hey @tomvo A fix for this is due to be released tomorrow: #44758

@tomvo
Copy link
Author

tomvo commented Nov 2, 2022

hey @joedixon thanks for the fix and the release. I just upgraded and it doesn't seem to fix the problem.

            "name": "laravel/framework",
            "version": "v9.38.0",

I made a simple test by dumping the config value dd(config('cache.default')); in my AppServiceProvider@register().
cache.default is set to 'default' => env('CACHE_DRIVER', 'file'),

I have the following .env files locally with it's corresponding values:

.env -> CACHE_DRIVER = array
.env.production -> CACHE_DRIVER = redis
.env.staging -> CACHE_DRIVER = redis
.env.test -> CACHE_DRIVER = redis

Results:

$ artisan  env:encrypt --env=staging
"redis" // app/Providers/AppServiceProvider.php:26

$ artisan  env:encrypt --env=test
"redis" // app/Providers/AppServiceProvider.php:26

$ art  env:encrypt --env=production
"redis" // app/Providers/AppServiceProvider.php:26

$ artisan 
"array" // app/Providers/AppServiceProvider.php:26

@tomvo
Copy link
Author

tomvo commented Nov 2, 2022

Ah! After some more tinkering I found out the problem was that we're checking for an existence of some keys in the Cache in the registering of a singleton in one of our service providers. So we are using the Cache facade in the register. It was only in one location so I moved it to a later point in the booting.

However, i'm not sure if this should be documented or not?

@joedixon
Copy link
Contributor

joedixon commented Nov 2, 2022

Hey @tomvo are you able to show me what that service provider looks like?

@tomvo
Copy link
Author

tomvo commented Nov 2, 2022

hey @joedixon i can't really post the whole thing here but it basically boils down to this:

namespace \App\Support\Remote;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;

class ServiceProvider extends BaseServiceProvider
{
    public function register()
    {
      //Register API clients as singletons
        $this->app->singleton(\App\Support\Remote\Api::class, function () {
            return new App\Support\Remote\Api;
        });
    }
}
class Api implements ApiInterface
{
    protected $guzzle = null;

    public function __construct()
    {
        $this->guzzle = new GuzzleClient([
            //...
            'auth' => [Cache::get('remote.api.access_token')],
            //...       
        ]);
    }
}

But as mentioned i've created a new createClient() method in our API classes that is called when a request is done in runtime and it solves the problem. It's a solution that is not really related at all to get the encryption working but hey.

I'm not that familiar with Laravel core but wouldn't it be possible to just encrypt any file without messing with environments at all. Something like artisan encrypt [my-file]. It would come in handy too for other things that won't go in repo's like push notification certs etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants