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

Certainty Laravel Package

paragonie/certainty

Automate and manage cacert.pem for PHP projects to ensure reliable TLS certificate validation across diverse environments. Avoid disabling verification, reduce support burden, and keep HTTP clients secure. Requires PHP 8.3+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require paragonie/certainty:^3
    

    Requires PHP 8.3+ (or use ^2 for PHP < 8.3).

  2. First Use Case: Fetch the latest CA bundle in a Laravel HTTP client (e.g., Guzzle):

    use ParagonIE\Certainty\RemoteFetch;
    
    $fetch = new RemoteFetch();
    $bundlePath = $fetch->getLatestBundle(); // Returns path to verified cacert.pem
    
  3. Where to Look First:


Implementation Patterns

Core Workflows

  1. Runtime Fetching (Recommended):

    // Laravel Service Provider (e.g., AppServiceProvider)
    public function boot()
    {
        $bundlePath = (new RemoteFetch())->getLatestBundle();
        config(['http.connections.guzzle.options' => [
            'curl' => [
                CURLOPT_CAINFO => $bundlePath,
            ],
        ]]);
    }
    
    • Pros: Always up-to-date, verifies signatures.
    • Cons: Slight latency on first request.
  2. Composer Pre-Update (Optimized): Add to composer.json:

    {
      "scripts": {
        "post-autoload-dump": [
          "ParagonIE\\Certainty\\Composer::postAutoloadDump"
        ]
      }
    }
    
    • Usage in Code:
      $bundlePath = (new \ParagonIE\Certainty\Fetch())->getLatestBundle();
      
    • Pros: Zero runtime overhead (bundles pre-fetched).
    • Cons: Requires composer update to stay current.
  3. Custom Data Directory:

    $fetch = new RemoteFetch('/custom/path/to/certs');
    $bundlePath = $fetch->getLatestBundle();
    
    • Useful for shared hosting or containerized environments.

Integration Tips

  • Laravel HTTP Clients: Bind the bundle path to a config value and inject it into Guzzle/HTTP clients:

    $client = Http::withOptions([
        'curl' => [
            CURLOPT_CAINFO => config('certainty.bundle_path'),
        ],
    ]);
    
  • Trust Channels: Filter bundles by trust channel (e.g., "Mozilla") for enterprise use:

    $fetch = new RemoteFetch();
    $bundle = $fetch->getBundle('2025-09-09', 'Mozilla');
    
  • Fallback Servers: Configure a replica Chronicle URL for high availability:

    $fetch = new RemoteFetch(null, 'https://replica.pie-hosted.net');
    
  • Caching: Cache the bundle path in Laravel’s cache (e.g., Redis) to avoid repeated RemoteFetch calls:

    $bundlePath = Cache::remember('certainty.bundle_path', now()->addDays(7), function () {
        return (new RemoteFetch())->getLatestBundle();
    });
    

Gotchas and Tips

Pitfalls

  1. PHP < 8.3:

    • Use ^2 branch (e.g., paragonie/certainty:^2) for legacy support.
    • Symlink Warning: VirtualBox Shared Folders may break symlink creation (use absolute paths).
  2. Offline Environments:

    • RemoteFetch fails without internet. Use Fetch with pre-downloaded bundles:
      $fetch = new \ParagonIE\Certainty\Fetch('/path/to/pre-downloaded/bundle');
      
  3. Composer Lockfile:

    • Avoid pinning certainty to a specific version (e.g., 3.0.2). Use ^3 to auto-update bundles.
    • Exception: Pin if using non-RemoteFetch workflows (e.g., air-gapped systems).
  4. Chronicle Failures:

    • If php-chronicle.pie-hosted.com is down, switch to a replica:
      $fetch = new RemoteFetch(null, 'https://replica.pie-hosted.net');
      
  5. 32-bit Systems:

    • Sodium verification is slow on 32-bit PHP. Disable it via:
      $fetch = new RemoteFetch();
      $fetch->setVerifySignatures(false); // Not recommended for production
      

Debugging

  • Verify Bundle Integrity:

    $fetch = new RemoteFetch();
    $bundle = $fetch->getBundle(); // Returns full bundle data with metadata
    var_dump($bundle->getSha256()); // Checksum
    var_dump($bundle->getSignature()); // Ed25519 signature
    
  • Log Failures: Enable verbose logging for RemoteFetch:

    $fetch = new RemoteFetch();
    $fetch->setLogger(new \Monolog\Logger('certainty', [new \Monolog\Handler\StreamHandler(storage_path('logs/certainty.log'))]));
    
  • Check for Stale Bundles: Compare local bundle timestamps with the latest release:

    composer show paragonie/certainty | grep -E "version|time"
    

Extension Points

  1. Custom Bundle Sources: Extend ParagonIE\Certainty\Fetch to support internal CA repositories:

    class InternalFetch extends \ParagonIE\Certainty\Fetch {
        public function getLatestBundle() {
            return '/path/to/internal/cacert.pem';
        }
    }
    
  2. Override Chronicle URL: For enterprise isolation, host your own Chronicle instance:

    $fetch = new RemoteFetch(null, 'https://your-chronicle.example.com');
    
  3. Add Trust Channels: Extend the TrustChannel enum for custom channels (e.g., "Internal"):

    namespace App\Certainty;
    use ParagonIE\Certainty\TrustChannel;
    
    class CustomTrustChannel extends TrustChannel {
        public const INTERNAL = 'Internal';
    }
    
  4. Hook into Bundle Updates: Listen for post-autoload-dump events to trigger custom logic:

    // composer.json
    {
      "scripts": {
        "post-autoload-dump": [
          "ParagonIE\\Certainty\\Composer::postAutoloadDump",
          "@custom-cert-script"
        ]
      }
    }
    

Performance Tips

  • Avoid Repeated Fetches: Cache the bundle path in Laravel’s cache or session:

    $bundlePath = Cache::rememberForever('certainty.bundle_path', function () {
        return (new RemoteFetch())->getLatestBundle();
    });
    
  • Use Fetch in Production: Pre-download bundles via CI/CD and use Fetch in production to eliminate runtime network calls:

    # In CI/CD pipeline
    composer require paragonie/certainty:^3
    vendor/bin/certainty-update
    
  • Parallelize Updates: For monorepos or large projects, run composer update in parallel with:

    composer update --no-plugins --no-scripts && composer update
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
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