Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Vault Symfony Bundle Laravel Package

damienfern/vault-symfony-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require damienfern/vault-symfony-bundle
    
  2. Enable the bundle in config/bundles.php:
    return [
        // ...
        DamienFern\VaultBundle\VaultBundle::class => ['all' => true],
    ];
    
  3. Configure Vault in config/packages/vault.yaml (choose token or AppRole auth):
    vault:
        address: 'https://vault.example.com:8200'
        path: 'myapp/production'  # Secrets path in Vault
        token: '%env(Vault_TOKEN)%'  # Or use AppRole below
    
    For AppRole:
    vault:
        address: 'https://vault.example.com:8200'
        path: 'myapp/production'
        app_role:
            role_id: '%env(VAULT_ROLE_ID)%'
            secret_id: '%env(VAULT_SECRET_ID)%'
    

First Use Case: Fetch Secrets as Environment Variables

The bundle automatically injects Vault secrets as environment variables (e.g., DB_PASSWORD from Vault → $_ENV['DB_PASSWORD']). Use them in Symfony services or .env:

# config/services.yaml
services:
    App\Service\Database:
        arguments:
            $dsn: '%env(DATABASE_URL)%'  # Populated from Vault

Implementation Patterns

Workflow: Secure Secrets Management

  1. Store secrets in Vault:
    vault kv put myapp/production DB_PASSWORD="s3cr3t" DB_USER="admin"
    
  2. Configure the bundle (as above) to point to this path.
  3. Access secrets via Symfony’s %env() or $_ENV:
    $password = $_ENV['DB_PASSWORD']; // Auto-populated
    
  4. Rotate secrets:
    • Update Vault (vault kv put myapp/production DB_PASSWORD="new_s3cr3t").
    • The bundle does not auto-revoke cache (see Gotchas), so restart PHP workers or use a webhook (future feature).

Integration Tips

  • Dynamic Configuration: Use the bundle with Symfony’s ParameterBag to load secrets at runtime:
    $container->get('vault.client')->get('myapp/production');
    
  • Environment-Specific Paths: Override path per environment (e.g., myapp/development vs. myapp/production) in vault.yaml.
  • Fallback to .env: Combine with Symfony’s .env.local for local overrides:
    # .env.local
    DB_PASSWORD=local_override  # Overrides Vault if needed
    

Example: Database Service

# config/services.yaml
services:
    Doctrine\DBAL\Connection:
        factory: ['@App\Factory\DatabaseFactory']
        arguments:
            $dsn: '%env(DATABASE_URL)%'  # Vault-injected
            $username: '%env(DB_USER)%'
            $password: '%env(DB_PASSWORD)%'

Gotchas and Tips

Pitfalls

  1. No Auto-Refresh:

    • Secrets are loaded once at bootstrap. To update:
      • Restart PHP workers (e.g., php-fpm).
      • Use a Vault webhook (planned in future versions) to trigger cache invalidation.
    • Workaround: Implement a custom VaultClient service to manually refresh secrets:
      $client = $container->get('vault.client');
      $client->refresh(); // Hypothetical method (not yet implemented)
      
  2. AppRole Token Leak Risk:

    • secret_id is long-lived. Rotate it via Vault’s auth/approle/rotate-secret-id API after use.
    • Tip: Use short-lived secret_ids or Vault’s periodic token renewal.
  3. Missing Error Handling:

    • The bundle lacks a custom Vault exception class (planned). Catch RuntimeException for now:
      try {
          $client->get('nonexistent/path');
      } catch (RuntimeException $e) {
          // Handle Vault errors (e.g., 404, auth failure)
      }
      
  4. Path Permissions:

    • Ensure the Vault path exists and your token/AppRole has read access:
      vault kv get myapp/production
      

Debugging Tips

  • Enable Debug Mode: Add debug: true to vault.yaml to log HTTP requests:
    vault:
        debug: true
    
  • Validate Configuration: Use the Symfony CLI to check connectivity:
    php bin/console debug:container vault.client
    
  • Check Vault Logs: Inspect Vault server logs for auth failures or permission errors.

Extension Points

  1. Custom Secret Processing: Override the DamienFern\VaultBundle\Service\VaultClient to transform secrets (e.g., base64 decode):

    // src/Service/CustomVaultClient.php
    class CustomVaultClient extends VaultClient {
        public function get(string $path): array {
            $data = parent::get($path);
            return array_map('base64_decode', $data);
        }
    }
    

    Register it in services.yaml:

    services:
        App\Service\CustomVaultClient: ~
        vault.client: '@App\Service\CustomVaultClient'
    
  2. Add Integration Tests: Mock the Vault HTTP client in tests:

    use Symfony\Component\HttpClient\MockHttpClient;
    
    $client = new VaultClient(
        new MockHttpClient([new Response(200, [], json_encode(['DB_PASSWORD' => 'test']))])
    );
    
  3. APCu Caching (Future): Watch for the planned APCu integration to reduce Vault API calls.

Configuration Quirks

  • HTTPS Requirement: Vault requires HTTPS in production. Use http:// only for local/dev.
  • Token vs. AppRole: Prefer AppRole for production (tokens are long-lived; AppRole supports short-lived secrets).
  • Path Format: Use kv/v2/ paths (e.g., myapp/production) for KV v2 secrets. The bundle defaults to v2.

Pro Tips

  • Secret Rotation Strategy: Use Vault’s transit engine to encrypt secrets, then rotate keys via:
    vault write -f transit/keys/mykey rotate
    
  • Symfony Cache Warmup: Pre-load secrets during deploy:
    php bin/console cache:warmup --env=prod
    
  • Monitor Vault Health: Add a health check endpoint:
    // src/Controller/VaultHealthCheck.php
    class VaultHealthCheck {
        public function __invoke(VaultClient $client) {
            try {
                $client->get('sys/health');
                return new Response('OK');
            } catch (Exception $e) {
                return new Response('Vault Unavailable', 500);
            }
        }
    }
    
    Route it in config/routes.yaml:
    _vault_health:
        path: /_health/vault
        controller: App\Controller\VaultHealthCheck
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle