How to Create Trusted SSL Certificates for Localhost on MacOS with SSLoca

• ~400 words • 2 minute read

Recently I was working with the Stripe Elements toolkit for a piece of custom billing software my web development company uses. The library is a collection of well-designed UI components for interfacing with Stripe’s services. Specifically I was working with their Payment Request Button which is designed to work with the W3C Payment Request API standard currently being discussed.

To implement the Payment Request Button you need to be using a secure (https) connection. This isn’t difficult to setup using OpenSSL, but the Payment Request API requires a little more than a basic SSL certificate in place — it has to be a trusted as well. Stripe’s suggestion to use a service like ngrok is a good one, but not necessarily always possible or desirable. Such was the case for my project.

Creating a trusted SSL certificate for your localhost server on macOS turned out to require a lot of steps and a fair amount of research. When I finally generated the certificates and had everything running smoothly I decided to package it up in a single command you could run in the terminal and made a GitHub project out of it:

github.com/snaptortoise/ssloca

Now, instead of copying-and-pasting cryptic OpenSSL commands into the terminal like I’m sure so many developers before me have done, you can generate and trust these certificates in two lines:

git clone git@github.com:snaptortoise/ssloca.git && cd ssloca ./create-local-certificates.sh

You should end up with a folder called certs containing all the locally generate certificates including the root certificate and the certificate for your server. More information on what and how things are generated can be found in the code.

I called the project SSLoca — a portmanteau of SSL, local and loca, in Spanish. Because getting SSL to work locally made me feel a little crazy.

There’s plenty of room for improvement in my script, and I know there are lots of developers out there who have jumped through the same hoops to solve this problem. Please give it a look, let me know if you found it useful and by all means submit a pull request if you have thoughts on how to improve it.