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

Ca Bundle Laravel Package

composer/ca-bundle

Find the system CA root bundle path for TLS verification, with automatic fallback to a bundled Mozilla CA file. Simple API for curl, PHP streams, and HTTP clients like Guzzle; includes CA file validation and cache reset utilities.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require composer/ca-bundle
    

    Add to composer.json under require if using a monorepo or custom setup.

  2. First Use Case: Resolve the CA bundle path for a cURL request:

    $caPath = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
    curl_setopt($curl, CURLOPT_CAINFO, $caPath); // or CURLOPT_CAPATH if dir
    
  3. Where to Look First:

    • Core Class: \Composer\CaBundle\CaBundle (static methods).
    • Key Methods:
      • getSystemCaRootBundlePath() (primary entry point).
      • getBundledCaBundlePath() (fallback to Mozilla’s cacert.pem).
    • Documentation: README.md for integration examples (cURL, Guzzle, streams).

Implementation Patterns

Usage Patterns

  1. HTTP Client Integration:

    • Guzzle: Pass the CA path directly to the client constructor:
      $client = new \GuzzleHttp\Client([
          \GuzzleHttp\RequestOptions::VERIFY => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
      ]);
      
    • PHP Streams: Use with stream_context_create:
      $context = stream_context_create([
          'ssl' => [
              'cafile' => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(),
          ],
      ]);
      file_get_contents('https://example.com', false, $context);
      
  2. Environment-Specific Overrides:

    • Cache the CA path in a service container (e.g., Laravel’s bind):
      $app->bind(\Composer\CaBundle\CaBundle::class, function () {
          return \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
      });
      
    • Use environment variables to force a specific path (e.g., for testing):
      $caPath = getenv('CA_BUNDLE_PATH') ?? \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
      
  3. Validation Workflows:

    • Check if OpenSSL parsing is safe before validation:
      if (\Composer\CaBundle\CaBundle::isOpensslParseSafe()) {
          $cert = \Composer\CaBundle\CaBundle::validateCaFile('/path/to/cert.pem');
      }
      
  4. Testing:

    • Mock the CA bundle path in tests:
      \Composer\CaBundle\CaBundle::reset(); // Clear static cache
      \Composer\CaBundle\CaBundle::setCaPath('/path/to/test/cacert.pem'); // If extending
      
    • Use the bundled CA for isolated tests:
      $caPath = \Composer\CaBundle\CaBundle::getBundledCaBundlePath();
      

Workflows

  1. CI/CD Pipelines:

    • Ensure consistent CA paths across environments by relying on the system resolver:
      # .github/workflows/test.yml
      - name: Install dependencies
        run: composer require composer/ca-bundle
      - name: Run tests with CA bundle
        run: php tests/integration/ssl_test.php
      
    • Use the bundled CA for Docker builds where system paths may vary:
      RUN curl -sSL https://curl.se/ca/cacert.pem -o /usr/local/share/ca-certificates/cacert.pem \
          && update-ca-certificates
      
  2. Legacy System Migration:

    • Replace hardcoded paths (e.g., /etc/ssl/certs/ca-certificates.crt) with the dynamic resolver:
      // Before
      curl_setopt($curl, CURLOPT_CAINFO, '/etc/ssl/certs/ca-certificates.crt');
      
      // After
      curl_setopt($curl, CURLOPT_CAINFO, \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath());
      
  3. Multi-Cloud Deployments:

    • Standardize CA resolution across AWS Lambda, GCP, and Kubernetes:
      $caPath = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
      // Works on Lambda (fallback to bundled), GCP (system path), or Kubernetes (host-mounted).
      

Gotchas and Tips

Pitfalls

  1. Static Cache:

    • The package caches resolved paths statically. Clear the cache when testing or switching environments:
      \Composer\CaBundle\CaBundle::reset();
      
    • Gotcha: Forgetting to reset can lead to stale paths in tests or after environment changes.
  2. OpenSSL Parsing Safety:

    • openssl_x509_parse() may not be available or safe on all PHP builds (e.g., disabled for security). Always check:
      if (!\Composer\CaBundle\CaBundle::isOpensslParseSafe()) {
          throw new \RuntimeException('OpenSSL parsing is not supported.');
      }
      
  3. Path Format Ambiguity:

    • The method returns either a file path (e.g., /etc/ssl/certs/ca-certificates.crt) or a directory path (e.g., /etc/ssl/certs/). Always check is_dir():
      $caPath = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
      if (is_dir($caPath)) {
          curl_setopt($curl, CURLOPT_CAPATH, $caPath); // Directory
      } else {
          curl_setopt($curl, CURLOPT_CAINFO, $caPath);  // File
      }
      
  4. Bundled CA Updates:

    • The bundled cacert.pem is updated quarterly (see releases). If you rely on the fallback, ensure your app can handle updates without breaking:
      // Example: Validate the bundled CA on startup
      $bundledPath = \Composer\CaBundle\CaBundle::getBundledCaBundlePath();
      if (!file_exists($bundledPath)) {
          throw new \RuntimeException('Bundled CA certificate missing!');
      }
      
  5. PHP Version Deprecations:

    • PHP 7.1+: Required for v1.5.x. Avoid mixing versions (e.g., PHP 7.1 with v1.5.x).
    • PHP 8.4+: May trigger deprecation warnings (fixed in v1.5.0+). Use the latest version.
  6. Open_Basedir Restrictions:

    • If open_basedir is enabled, the bundled CA path may be inaccessible. Test in restricted environments:
      if (!is_readable(\Composer\CaBundle\CaBundle::getBundledCaBundlePath())) {
          throw new \RuntimeException('CA bundle inaccessible due to open_basedir restrictions.');
      }
      

Debugging Tips

  1. Log CA Paths:

    • Add debug logs to verify paths:
      $caPath = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
      \Log::debug('Using CA path:', ['path' => $caPath, 'is_dir' => is_dir($caPath)]);
      
  2. Validate Certificates:

    • Use openssl CLI to verify the resolved path:
      openssl verify -CApath /path/to/resolved/ca /path/to/cert.pem
      
  3. Check System Paths:

    • Manually inspect common paths if the resolver fails:
      $paths = [
          '/etc/ssl/certs/ca-certificates.crt', // Debian/Ubuntu
          '/etc/pki/tls/certs/ca-bundle.crt',   // RHEL/CentOS
          '/usr/local/etc/openssl/cert.pem',    // macOS (Homebrew)
          '/etc/ssl/cert.pem',                  // macOS (default)
      ];
      
  4. Fallback Behavior:

    • If the system path is invalid, the package falls back to the bundled CA. Force the fallback for testing:
      // Simulate a missing system CA
      \Composer\CaBundle\CaBundle::reset();
      $caPath = \Composer\CaBundle\CaBundle::getBundledCaBundlePath();
      

Extension Points

  1. Custom CA Paths:

    • Extend the class to support custom paths (e.g., for air-gapped environments):
      class CustomCaBundle extends \Composer\CaBundle\CaBundle {
          public static function getSystemCaRootBundlePath(): string {
              $customPath = getenv('CUSTOM_CA_PATH');
              return $customPath ?? parent::getSystemCaRootBundlePath();
          }
      }
      
  2. Override Trust Stores:

    • Modify the list
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.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views