At Cerebrum, we’ve integrated Ory Kratos, a sophisticated authentication solution, into our products. However, this integration presented a unique challenge during local development: Ory Kratos heavily relies on secure cookies for its browser operations.

In production, our infrastructure naturally operates under an HTTPS domain. But when developing locally with a hosted Ory Kratos server, an issue emerged. Authenticating users from local machines proved more cumbersome than expected. Ory Kratos would set its cookies for the HTTPS domain, and the service running on localhost would continually and unsuccessfully attempt to access these cookies via HTTP.

There are several other scenarios where HTTPS is necessary for local development:

  1. Testing HTTPS-only features: Some web features, especially those related to security and privacy, only work over HTTPS. Testing them locally requires an HTTPS setup.
  2. Working with browser APIs: Modern browser APIs such as Service Workers, Geolocation, and others mandate that the application be served over HTTPS. To test and develop with these APIs locally, HTTPS is essential.
  3. WebRTC development: Developing and testing WebRTC applications often necessitates an HTTPS setup for real-time communication.

Here are the steps to set up HTTPS locally:

  1. Install a Local Certificate Authority
  2. Generate a Local SSL Certificate
  3. Update Your Host Files
  4. Configure Your App/Server to use HTTPS
  5. Test your setup

Let’s dive into it.

Install a local certificate authority

Before you can use HTTPS, you need a certificate. For local development, we'll create a local certificate authority (CA). We’ll use mkcert to create a local certificate. Here are ways to install mkcert in different OSes.

On macOS

# Using HomeBrew
brew install mkcert
brew install nss         # if you use Firefox
# Using MacPorts
sudo port selfupdate
sudo port install mkcert
sudo port install nss        # if you use Firefox

On Linux, first, install certutil.

sudo apt install libnss3-tools
#OR
sudo yum install nss-tools
#OR
sudo pacman -S nss
#OR
sudo zypper install mozilla-nss-tools

Then you can install using Homebrew on Linux

brew install mkcert

For Arch Linux users, mkcert is available on the official Arch Linux repository.

sudo pacman -Syu mkcert

On Windows

# Using Chocolatey
choco install mkcert
# Using Scoop
scoop bucket add extras
scoop install mkcert

Generate a local SSL certificate

Run the below command to create a local CA:

mkcert -install

This command will create a local CA and store the root certificate in your system trust store.

Now that we have a CA, we can generate SSL certificates for our local domains.

  1. Choose a domain for your local environment, e.g., example.com.
  2. Run the command to generate the certificate:
mkcert example.com

This will produce two files: example.com.pem (the certificate) and example.com-key.pem (the private key).

If you want to generate SSL certificates for all subdomains under the main domain then you can run this command.

mkcert *.example.com

This will produce two files: _wildcard.example.com.pem (the certificate) and _wildcard.example.com-key.pem (the private key).

Note: These wildcards only go one level deep, so this won't match a.b.example.com

Update your hosts file

To ensure that your local domain resolves to your machine, update your hosts file.

  1. Open /etc/hosts on Linux/Mac or C:\Windows\System32\drivers\etc\hosts on Windows.
  2. Add the following line:
127.0.0.1 example.com       # For root domain
127.0.0.1 local.example.com # any subdomain

Configure your app/server to use HTTPS

You'll need to tell your web server or web app to use the certificate and private key generated in the previous step.

For example, if you're using ExpressJS:

const https = require('https');
const fs = require('fs');
const express = require('express');
const app = express();

https.createServer({
	key: fs.readFileSync('path-to-private-key.pem'),
	cert: fs.readFileSync('path-to-ceritificate.pem')
}, app).listen(3000);

Now you can access it using the https url such as https://local.cerebrum.com:3000

For example, if you're using Next.JS:

  1. install local-ssl-proxy & concurrently to project using
npm i local-ssl-proxy concurrently --save-dev 
# OR
yarn add local-ssl-proxy concurrently --dev

Update your dev script in package.json with the below command.

concurrently \"next dev\" \"local-ssl-proxy --key <ABSOLUTE_PATH_TO_PRIVATE_KEY> --cert <ABSOLUTE_PATH_TO_CERTIFICATE> --source 5000 --target 3000\"

Now you can run npm run dev or yarn dev

  1. Now you can access it with https url like this https://local.example.com:5000

Test your setup

Now, launch your application and navigate to https://local.example.com:<PORT> in your browser. You should see a secure padlock indicating that the connection is secure.

Wrapping up

Setting up HTTPS locally might seem like a superfluous step in the development process, but its benefits — ensuring security and a seamless transition from your local environment to a production environment — cannot be understated. By following this guide, you'll have a secure local environment in no time.

Happy coding!



Share this post