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

Add Env::extend to support custom adapters when loading environment variables #54756

Merged
merged 1 commit into from
Feb 23, 2025

Conversation

andrii-androshchuk
Copy link
Contributor

@andrii-androshchuk andrii-androshchuk commented Feb 23, 2025

Summary

This PR introduces a new capability to register one or more additional adapters for reading and loading environment variables during the Kernel's bootstrap process. This allows Laravel applications to retrieve environment variables from external sources such as AWS Secrets Manager, HashiCorp Vault, Infisical, encrypted local files, or any other implementation that conforms to the default interface.

Problem

An application might rely on environment variables ("secrets") that are securely stored in external sources, rather than in a "local" .env file. Additionally, these variables may be dynamically updated (rotated), requiring a reliable way to load them at the right stage of the bootstrapping process.

There are currently a few ways to handle this, but each has limitations:

  • One approach is to use the afterLoadingEnvironment callback to load external secrets. However, if additional environment variables are loaded within this callback, it could lead to the situation where not all environment variables are available yet. As a result, the naming and intended purpose of the callback may become misleading or inaccurate.
  • Another approach is creating a custom Service Provider that retrieves external secrets and updates them via the Configuration Repository with config([$key => $value]). However, service providers load late in the request lifecycle, meaning environment variables (and related configuration settings) are updated too late to be useful during early bootstrapping.

Therefore, both solutions fail to provide external secrets before Laravel compiles the configuration, which is necessary for secure and dynamic environment variable management.

Proposed Solution

The Dotenv library, which Laravel uses to read and load environment variables, supports multiple adapters for reading and writing variables. Currently, Laravel leverages the default RepositoryBuilder, which comes with the following adapters:

  • ServerConstAdapter (reads from $_SERVER)
  • EnvConstAdapter (reads from $_ENV)
  • PutenvAdapter (optional, provides putenv() / getenv() support)

Thus, this PR introduces a new method: Env::extend, allowing developers to:

  • Register one or more custom adapters that read environment variables from any external source.
  • Load these variables before configuration is compiled, ensuring they are available early in the bootstrapping process.
  • Create custom, secure, and flexible solutions while adhering to Laravel’s existing contract for environment management.

Example

The perfect place for registering an extra adapter might be in the bootstrap/app.php file, right before the application builder, so the ApplicationBuilder already has access to all the necessary environment variables.

\Illuminate\Support\Env::extend('aws_secrets', fn() => new AwsSecretsManagerAdapter);

In theory, this approach could serve as a more direct alternative to how Laravel Vapor currently loads parameters ("secrets") from Amazon EC2 Systems Manager (SSM). For this reason, I’ve added support for multiple adapters, ensuring flexibility in case Vapor adopts this solution and/or if the application needs to integrate with multiple external sources of "secrets".

Copy link

Thanks for submitting a PR!

Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

@andrii-androshchuk andrii-androshchuk marked this pull request as ready for review February 23, 2025 16:00
@taylorotwell taylorotwell merged commit 703e7fb into laravel:12.x Feb 23, 2025
41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants