Sorry, you need to enable JavaScript to visit this website.
Skip to main content
Welcome to our website! Explore our services and portfolio.

How Guzzle validates SSL certificates when making outbound API requests

Submitted by admin on



Here are the most common Certificate Authorities (CAs) you'll encounter:

Major Commercial CAs

CA

Known For

DigiCert

Enterprise, acquired Symantec/Verisign's SSL business

Sectigo (formerly Comodo)

High volume, affordable certs

GlobalSign

Popular in enterprise and IoT

Entrust

Government and financial sector

GoDaddy

Popular with small/medium sites

IdenTrust

Issues intermediate certs to other CAs

Free / Automated CAs

CA

Known For

Let's Encrypt

Free, automated, widely adopted — backed by Mozilla, EFF, Cisco

ZeroSSL

Free alternative to Let's Encrypt

Buypass

Free tier available, Norway-based

Government / Specialized CAs

CA

Known For

ISRG

The nonprofit behind Let's Encrypt

Actalis

European/Italian government use

SwissSign

Swiss federal government




In Practice

  • Most SaaS APIs (like Constant Contact, Stripe, Twilio) use DigiCert or Sectigo
  • Most modern websites are moving toward Let's Encrypt for automatic renewal
  • IdenTrust is notable because it cross-signed Let's Encrypt's root early on, which is why LE certs were trusted so broadly from the start

All of these are pre-included in Ubuntu's ca-certificates package



Sometime we need to understand how PHP's HTTP client validates SSL certificates when making outbound API requests. 

Here's how it works:

How SSL Trust Works in PHP API Calls

When your Drupal app calls the Constant Contact API, the trust chain works like this:

1. The OS/Server Certificate Bundle PHP (via cURL under the hood) uses a CA certificate bundle — typically the system's trusted CA store or a bundled cacert.pem file. Constant Contact's cert is signed by a trusted CA (like DigiCert), which is already in that bundle, so it's trusted automatically.

2. How Drupal or your phpapp handles it. Guzzle (or a similar HTTP client) delegates the request to PHP's cURL extension. The relevant settings are:

php
CURLOPT_SSL_VERIFYPEER => true  // verifies the cert chain CURLOPT_SSL_VERIFYHOST => 2     // verifies the hostname matches CURLOPT_CAINFO => '/path/to/cacert.pem'  // the CA bundle to trust

Where the CA Bundle Comes From

Source

Location

Linux system store

/etc/ssl/certs/ca-certificates.crt

PHP's bundled certs

Compiled in, or set via curl.cainfo in php.ini

Guzzle's bundle

Pulled from guzzlehttp/guzzle via Composer

You can check what your PHP install is using:

php
var_dump(openssl_get_cert_locations()); // or echo ini_get('curl.cainfo');

Common Issues & Fixes

SSL verification failing in dev/local? Check your CA bundle is up to date:

bash
# On Ubuntu/Debian sudo apt-get update && sudo apt-get install ca-certificates
 # Or point PHP to Mozilla's bundle via Composer composer require guzzlehttp/guzzle  # ships its own cacert.pem

Manually specifying the CA bundle in php.ini:

ini
curl.cainfo = "/etc/ssl/certs/ca-certificates.crt" openssl.cafile = "/etc/ssl/certs/ca-certificates.crt"




 

 

If you need to pass custom Guzzle options (e.g. a specific CA file), look for where the library instantiates its Guzzle client and pass:

php
$client = new \GuzzleHttp\Client([     'verify' => '/path/to/cacert.pem', // or false to disable (dev only!) ]);

The Short Answer

Find out what vendor the third party API service uses.   You can then check that it exists in the system ca store.

# Check if [vendor] certs are present in the system store 
grep -r "[third party vendor]" /etc/ssl/certs/ # Or list all trusted CAs awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)}; {print | cmd}' \ < /etc/ssl/certs/ca-certificates.crt | grep -i [third party vendor]







Your server trusts [Third Party]'s SSL cert because [ThirdParty]'s SSL cert Vendor (their CA) is already in your system/PHP trust store — no special configuration needed in normal production environments. Issues usually only arise when the CA bundle is outdated or missing in containerized/minimal server environments.