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

Cloud Secret Manager Laravel Package

google/cloud-secret-manager

Idiomatic PHP client for Google Cloud Secret Manager. Install via Composer, authenticate with Google Cloud credentials, then use SecretManagerServiceClient to create, access, and manage secrets over REST or gRPC with robust error handling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require google/cloud-secret-manager
    
  2. Authenticate (choose one method):
    • Service Account Key (for local/dev):
      putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json');
      
    • Workload Identity Federation (for GCP environments): Configure IAM roles and use the default application credentials.
  3. First use case: Fetch a secret in Laravel’s AppServiceProvider:
    use Google\Cloud\SecretManager\V1\SecretManagerServiceClient;
    use Google\Cloud\SecretManager\V1\GetSecretRequest;
    
    public function boot()
    {
        $client = new SecretManagerServiceClient();
        $request = (new GetSecretRequest())
            ->setName('projects/YOUR_PROJECT_ID/secrets/YOUR_SECRET_ID/versions/latest');
    
        $secret = $client->getSecret($request);
        config(['services.db.password' => $secret->getPayload()->getData()]);
    }
    

Where to Look First


Implementation Patterns

1. Laravel Configuration Integration

Pattern: Replace .env values with dynamic Secret Manager fetches. Example:

// config/services.php
return [
    'db' => [
        'password' => fn() => app(SecretManagerService::class)->get('database_password'),
    ],
    'mail' => [
        'password' => fn() => app(SecretManagerService::class)->get('smtp_password'),
    ],
];

Service Provider:

// app/Providers/SecretManagerServiceProvider.php
public function register()
{
    $this->app->singleton(SecretManagerService::class, function ($app) {
        $client = new SecretManagerServiceClient();
        return new SecretManagerService($client);
    });
}

2. Tag-Based Secret Routing

Pattern: Use tags to fetch environment-specific secrets (e.g., env:production). Example:

public function getSecretByTag(string $tag, string $secretName)
{
    $filter = sprintf('tags.%s=%s', $tag, app()->environment());
    $request = (new ListSecretsRequest())
        ->setParent('projects/YOUR_PROJECT_ID')
        ->setFilter($filter);

    $secrets = $this->client->listSecrets($request);
    foreach ($secrets->getSecrets() as $secret) {
        if ($secret->getName() === $secretName) {
            return $this->client->accessSecretVersion($secret->getName(), 'latest');
        }
    }
    throw new \RuntimeException("Secret not found");
}

3. Automated Rotation with Laravel Tasks

Pattern: Schedule secret rotations via Laravel’s scheduler. Example:

// app/Console/Commands/RotateDatabasePassword.php
public function handle()
{
    $newPassword = Str::random(32);
    $secretName = 'projects/YOUR_PROJECT_ID/secrets/db_password';

    $this->client->addSecretVersion(
        $secretName,
        (new AddSecretVersionRequest())
            ->setPayload((new SecretPayload())
                ->setData($newPassword)
            )
    );

    // Update Laravel config (e.g., via database or another secret)
    $this->updateConfig($newPassword);
}

Schedule:

// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->command(RotateDatabasePassword::class)
             ->dailyAt('03:00')
             ->when(function () {
                 return app()->environment('production');
             });
}

4. CI/CD Secret Injection

Pattern: Inject secrets into pipelines using GCP Workload Identity. GitHub Actions Example:

- name: Authenticate with GCP
  uses: google-github-actions/auth@v1
  with:
    workload_identity_provider: 'projects/YOUR_PROJECT_ID/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
    service_account: 'my-service-account@YOUR_PROJECT_ID.iam.gserviceaccount.com'

- name: Fetch secrets
  run: |
    SECRET_VALUE=$(gcloud secrets versions access latest --secret=my-secret)
    echo "SECRET_VALUE=$SECRET_VALUE" >> $GITHUB_ENV

5. Caching Secrets for Performance

Pattern: Cache secrets in Redis with TTL-based invalidation. Example:

public function getCachedSecret(string $secretName, int $ttl = 3600)
{
    $cacheKey = "secret:{$secretName}";
    if (cache()->has($cacheKey)) {
        return cache()->get($cacheKey);
    }

    $secret = $this->client->accessSecretVersion($secretName, 'latest');
    cache()->put($cacheKey, $secret->getPayload()->getData(), $ttl);
    return $secret->getPayload()->getData();
}

6. Error Handling and Retries

Pattern: Use Laravel’s exception handling for API errors. Example:

try {
    $secret = $this->client->accessSecretVersion($secretName, 'latest');
    return $secret->getPayload()->getData();
} catch (ApiException $e) {
    if ($e->getStatus()->getCode() === 5) { // Permission denied
        Log::error("Access denied to secret {$secretName}", ['error' => $e->getMessage()]);
        throw new \RuntimeException("Unauthorized access to secret");
    }
    throw $e;
}

7. Dynamic Feature Flags

Pattern: Store feature flags as secrets and toggle them dynamically. Example:

// config/feature-flags.php
return [
    'new_checkout_flow' => fn() => app(SecretManagerService::class)->get('feature_flags_new_checkout'),
];

// In a controller:
if (config('feature-flags.new_checkout_flow') === 'enabled') {
    // Enable new flow
}

Gotchas and Tips

Pitfalls

  1. Authentication Failures:

    • Gotcha: Forgetting to set GOOGLE_APPLICATION_CREDENTIALS or misconfiguring IAM roles.
    • Fix: Use Workload Identity Federation in GCP environments. Test locally with:
      putenv('GOOGLE_APPLICATION_CREDENTIALS=' . __DIR__ . '/service-account.json');
      
    • Debug: Check logs for ApiException with status code 403 (Permission Denied).
  2. Resource Name Format:

    • Gotcha: Incorrect secret name format (e.g., missing versions/latest).
    • Fix: Use the helper method:
      $secretName = SecretManagerServiceClient::secretVersionName(
          'projects/YOUR_PROJECT_ID',
          'secrets/YOUR_SECRET_ID',
          'versions/latest'
      );
      
  3. Large Secrets:

    • Gotcha: Secrets > 64KB may fail silently or return truncated data.
    • Fix: Split secrets into multiple versions or use Google Cloud Storage for large payloads.
  4. Delayed Destruction:

    • Gotcha: Accidentally destroying secrets without enabling delayed destruction.
    • Fix: Set a retention period when creating/updating secrets:
      $request = (new DestroySecretRequest())
          ->setName($secretName)
          ->setForceDestroy(false) // Enable delayed destruction
          ->setRetentionPeriod('30d');
      
  5. gRPC vs REST:

    • Gotcha: gRPC methods (e.g., streaming) may not work if not explicitly enabled.
    • Fix: Install gRPC dependencies:
      composer require google/cloud-common grpc/grpc
      
      Then configure the client:
      $client = new SecretManagerServiceClient([
          'grpc' => [
              'settings' => [
                  'default_metadata' => [
                      'x-goog-api-client' => 'laravel-app/1.0.0',
                  ],
              ],
          ],
      ]);
      
  6. Caching Invalidation:

    • Gotcha: Stale cached secrets after rotation.
    • Fix: Invalidate cache on secret updates:
      $this->client->addSecretVersion($secretName, $payload);
      cache()->forget("secret:{$secretName}");
      
  7. Cross-Project Access:

    • Gotcha: Accessing secrets in another project without proper IAM permissions.
    • Fix: Grant the service account roles/secretmanager.secretAccessor on the target project.

8

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.
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core