For local development environments that need TLS certificates, it's useful to mimic public certificate authority behavior with a private CA that belongs to your organization.
This repo is a very simple wrapper around the openssl
certificate signing command, which
runs without dependencies inside of GitHub actions. You store your CA's private key as a
repository secret, and signed certificates are stored as workflow run artifacts.
Important
Before continuing, create a new private repository in your GitHub organization using this repository as a template. Click the green "Use this template" button above.
If you've already completed setup, skip to the Get a signed cert section.
The following steps assume you have a POSIX-ish shell and openssl
available on your
local machine so make sure it's installed before proceeding. The included shell scripts
also depend on tee
and base64
with the flag -w0
but can be easily adapted if
those aren't available.
You only need to do this once. Skip to the Get a signed cert section if you completed setup previously.
On your local machine, create a CA key and certificate, combined into a single file. You
only need to do this once. Use the provided new-ca.sh
shell script for convenience:
CA_NAME="Acme, Inc. Private CA" ./new-ca.sh
Create a repository secret named CA_KEY_AND_CERT
with the contents of your combined CA key
and certificate PEM file.
- In GitHub, navigate to the settings page for actions secrets and variables
- In the "Secrets" tab, select "New repository secret"
- Name your secret
CA_KEY_AND_CERT
- Paste the contents of your combined CA key and certificate PEM file as the "Secret" value
Note that once you've stored the private key as a GitHub repository secret you can destroy the key on your local machine (just be sure to keep a copy of the CA cert). Your CA will then only exist inside of your GitHub repo.
Presuming you want your leaf ("server") certificates to be accepted as valid by TLS clients (i.e. web browsers, curl, etc.) you'll need to add the CA certificate created in step one (just the cert, not the combined key and cert) to the relevant "trust stores" in your development environment.
On your local machine, create a new private key and use it to generate a CSR for whatever
DNS name you want to appear in your signed cert. Use the provided new-csr.sh
shell
script for convenience:
DNS_NAME=www.example.com ./new-csr.sh
You'll need the private key to configure TLS for your server later, so make a note of its
location. It's the file ending in .key
.
Certificates are signed using GitHub Actions. This repository includes a workflow named "sign" that you can initiate directly from the GitHub UI or API. In the UI, at the top of the workflow runs list, you should see a banner that reads "This workflow has a workflow_dispatch event trigger." To the right of that is a button named "Run workflow" which you can use to initiate a new signing request.
The only required input is a base64-encoded certificate signing request. If you used the
provided shell script in the previous step then the CSR file ending in .b64
contains the
data you need.
Run the workflow with your base64-encoded CSR as input. Assuming the run completes successfully your signed cert is available as a downloadable artifact from the workflow run details page.
Pop the private key and signed cert from the previous step into any server's TLS configuration and it should work.