描述
A side-effect of compiling OpenSSL statically, in advance, on a different machine is that we don't get "free" access to the SSL certificates that are stored in the macOS keychain as trusted. This creates problems if you are using tools like caddy or puma-dev that create a Certificate Authority and then install it into the OS as trusted. Browsers will trust those certs, but rv's Ruby (and commands run inside rv, like bundle install) will not trust those certs.
I've personally run into this issue while testing local gem servers — bundle install from an rv ruby will fail certificate validation, even though curl and my web browser have no trouble verifying the certs using the OS certificate list.
We can work around this by asking the OS for those certs and using them instead of the certs that ship inside the built Ruby:
#!/bin/bash
security export -t certs -f pemseq -k /Library/Keychains/System.keychain > cert.pem
security export -t certs -f pemseq -k /System/Library/Keychains/SystemRootCertificates.keychain >> cert.pem
Once we have that cert.pem file, we put the full path to that file into the SSL_CERT_FILE when running Ruby.
I have benchmarked the script above to create the file, and even including starting a new bash shell, the entire thing seems to take about 16ms:
❯ hyperfine 'bash update_certs.sh'
Benchmark 1: bash update_certs.sh
Time (mean ± σ): 16.1 ms ± 1.2 ms [User: 8.9 ms, System: 4.9 ms]
Range (min … max): 14.4 ms … 20.2 ms 132 runs
I'm thinking maybe we want to cache the certs file for... 1 minute? Enough that we don't have to pay 16ms literally every command, but also short enough that running puma-dev -install to update your certs will still work relatively quickly.