polokij / laravel-vault-env
HashiCorp Vault 客户端用于 Laravel,支持从 Vault 密钥动态设置环境变量
v0.1.11
2024-08-21 19:38 UTC
Requires
- php: >=8.0
- laravel/framework: ^9.0 | ^10.0 | ^11.0
Requires (Dev)
- barryvdh/laravel-ide-helper: ^2.13
- phpunit/phpunit: ^10.4
README
此包提供了 HashiCorp Vault API 的基本功能。
动机
在使用 Laravel 开发我的多租户应用程序时,我遇到了缺少能够从 vault 获取环境变量并将其应用于应用程序启动的包。以下是所需功能的简短实现
- Vault API Client + Service + Facade
- artisan command to unseal the vault
- artisan command for create the secret engine
- Laravel bootstraper which apply the env variables fetched from Vault
需求
- Laravel 9+
- PHP 8+
安装
添加 composer 包
composer require polokij/laravel-vault-env
设置 .env 变量
VAULT_ADDR=http://vault:8200
# Required is no VAULT_ADDR specified
VAULT_HOST=vault
VAULT_PORT=8200
VAULT_SCHEME=https
# The storage engine thich will be used by default kv2 or secrets, or whatewhere
VAULT_DEFAULT_ENGINE=kv2
# The prefix will be added to each key on put/get requests
VAULT_KEY_PREFIX=TenantRootPath
VAULT_TOKEN=
发布配置
php artisan vendor:publish --provider="LaravelVault\VaultServiceProvider"
使用方法
- 使用 json 文件解密 Vault:
php artisan vault:unseal -f secret/file.json
- 使用密钥作为命令参数解密 Vault:
php artisan vault:unseal $key
- 检查密封状态:
php artisan vault:unseal -s
- 创建新的密钥存储:
php artisan vault:storage create new_storage_name
- 访问密钥
Vault::secret('my-secret', ['foo' => 'bar']); // push the secret to Vault Vault::secret('my-secret'); // pull the secret from Vault - return ['foo' => 'bar'] Vault::instance()->sys->get('some/not/implemented/endpoints'); // call the other endpoints on sys group Vault::instance()->auth->get('some/not/implemented/endpoints'); // call the other endpoints on auth group
使用动态环境变量启动应用程序
多租户应用程序示例
bootstrap/app.php
$app = new Illuminate\Foundation\Application( $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__) ); $app->afterLoadingEnvironment(function () use ($app) { // checking is the feature enabled if (env('VAULT_LOAD_ENV', false)) { try { $tenantId = env('TENANT_ID'); // resolving tenant_id by headers - make sure proxy override this header for security reason if (!$tenantId) { $headers = collect(getallheaders()); $tenantIdHeader = env('TENANT_ID_HEADER', 'tenant-id'); $tenantId = $headers ->first(fn($value, $key) => $key === $tenantIdHeader || strtolower($key) === $tenantIdHeader); } if (!$tenantId) { throw new Exception('Missed Tenant_id '); } $envRepository = Env::getRepository(); $vaultDefaultPrefix = $envRepository->get('VAULT_KEY_PREFIX'); $envRepository->set('VAULT_KEY_PREFIX', $vaultDefaultPrefix.'/'.$tenantId); (new LoadEnvironmentVariablesVault)->bootstrap($app); } catch (Throwable $e) { // preparing the logs for exception $app->instance('config', $config = new Repository([])); throw $e; } } });
另一种方法
要启用此功能,请在 app/Console/Kernel.php 和 app/Http/Kernel.php 文件中重写启动器的数组 app/Console/Kernel.php
use LaravelVault\LoadEnvironmentVariablesVault; class Kernel extends ConsoleKernel { /** * The bootstrap classes for the application. * * @var string[] */ protected $bootstrappers = [ LoadEnvironmentVariables::class, LoadEnvironmentVariablesVault::class, // <-- added custom bootstrapper LoadConfiguration::class, HandleExceptions::class, RegisterFacades::class, SetRequestForConsole::class, RegisterProviders::class, BootProviders::class, ];
app/Http/Kernel.php
use LaravelVault\LoadEnvironmentVariablesVault; class Kernel extends HttpKernel { /** * The bootstrap classes for the application. * * @var string[] */ protected $bootstrappers = [ LoadEnvironmentVariables::class, LoadEnvironmentVariablesVault::class, LoadConfiguration::class, HandleExceptions::class, RegisterFacades::class, RegisterProviders::class, BootProviders::class, ];
性能
正在调查 ))
待办事项
- 测试实现
- 重构 VaultClient 以通过入口点分离方法,简化项目开发
许可证
MIT 许可证 (MIT)。有关更多信息,请参阅许可证文件。