Created
August 14, 2026 01:37
-
-
Save theodson/9a7cecb9472c62ec86cd148459e2350e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # Rebuild the CA bundle Herd's PHP uses, appending locally-trusted development | |
| # root CAs (OrbStack, mkcert) that ship in the macOS login keychain but are | |
| # absent from the Mozilla bundle Herd manages. | |
| # | |
| # Why: PHP/curl verifies against a static cacert.pem and does NOT consult the | |
| # macOS keychain. Browsers and system curl do, which is why https://*.orb.local | |
| # works everywhere except PHP, where it fails with: | |
| # cURL error 60: SSL certificate ... self-signed certificate in certificate chain (19) | |
| # | |
| # Re-run this after Herd updates cacert.pem, or after OrbStack regenerates its | |
| # root CA (e.g. a reinstall). | |
| # | |
| set -euo pipefail | |
| HERD_PHP_CONFIG="${HOME}/Library/Application Support/Herd/config/php" | |
| UPSTREAM="${HERD_PHP_CONFIG}/cacert.pem" | |
| OUTPUT="${HERD_PHP_CONFIG}/cacert-with-local-cas.pem" | |
| # Development root CAs to pull from the login keychain, by common-name match. | |
| LOCAL_CAS=( | |
| "OrbStack Development Root CA" | |
| "mkcert" | |
| ) | |
| if [[ ! -f "${UPSTREAM}" ]]; then | |
| echo "error: Herd CA bundle not found at ${UPSTREAM}" >&2 | |
| exit 1 | |
| fi | |
| TMP="$(mktemp)" | |
| trap 'rm -f "${TMP}"' EXIT | |
| cat "${UPSTREAM}" > "${TMP}" | |
| for ca in "${LOCAL_CAS[@]}"; do | |
| if certs="$(security find-certificate -a -c "${ca}" -p "${HOME}/Library/Keychains/login.keychain-db" 2>/dev/null)" \ | |
| && [[ -n "${certs}" ]]; then | |
| { | |
| printf '\n# ---- local development CA: %s ----\n' "${ca}" | |
| printf '%s\n' "${certs}" | |
| } >> "${TMP}" | |
| echo "added: ${ca}" | |
| else | |
| echo "skipped (not in login keychain): ${ca}" | |
| fi | |
| done | |
| mv "${TMP}" "${OUTPUT}" | |
| trap - EXIT | |
| echo | |
| echo "wrote ${OUTPUT} ($(grep -c 'BEGIN CERTIFICATE' "${OUTPUT}") certificates)" | |
| echo "Herd's php.ini files should point curl.cainfo/openssl.cafile at this file." | |
| echo "Run 'herd restart' for PHP-FPM to pick up changes." |
Comments are disabled for this gist.