Let’s Encrypt KeystoneJS!

KeystoneJS now has support for Let’s Encrypt! This means you can run your site over SSL, for free, with only a few lines of code!


There are many reasons to encrypt the web; privacy, security and performance are some of them.

When someone connects they have the right to their privacy, meaning that their ISP and intermediate servers can’t snoop what they are reading. They also expect that the site they are reading has not been altered (security), and to make use of web performance boosts like HTTP/2 and Brotli compression, a HTTPS connection is required.


The configuration needs to be provided before you run keystone.start(), passing an object to the letsencrypt key. The object has the DNS name(s) of your site (domains), the admin email (email), whether you would like to auto-register (register), and an indication that you agree with the Terms of Service (tos). You can also specify your own directory for storing the keys with configDir, otherwise it will use $HOME/letsencrypt/etc.

The port it listens on for HTTPS defaults to the regular port + 1 (so 3001 by default), but you can choose a different one with the main ssl port setting.

There is also the ssl: ‘force’ setting, which automatically redirects users to HTTPS when they connect to your HTTP port.

If you then run your application and connect to the HTTPS port for the first time, it will contact Let’s Encrypt, which will verify that the application is listening on ports 80 and 443 on all the domains you specified before signing your shiny new SSL certificate.

It will also automatically refresh your certificate when it’s running out, so once it works, your job is done.

Once it works, your job is done!


As you might have noticed, your application needs to be accessible on a public DNS address, using the standard HTTP and HTTPS ports. Since it is best practice to not run your app as root, you need to redirect those ports to the KeystoneJS ports, using a proxy or a firewall.

If you don’t know how to do this, ask us on gitter or Stack Overflow! Since I normally run my apps on single NixOS VMs so I do the redirect with iptables on the host itself:

iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 3000
iptables -A PREROUTING -t nat -p tcp --dport 443 -j REDIRECT --to-port 3001


Encrypting your traffic comes at a performance cost. If this is a concern, you will need to either offload the encryption to a proxy, or run multiple app servers in parallel behind a proxy.

If you do the former, you will need to set up Let’s Encrypt on your proxy and not on Keystone. If the latter, you need to share the certificate storage between your servers (for example by mirroring, or by contributing a new backend for storing the certificate in MongoDB ;-) )


Make sure your site responds to ports 80 and 443 on the DNS names you specified.

Read the server log output.

Try using https://github.com/Daplie/letsencrypt-cli to manually create the certificates.


Q: How secure is this?

A: As secure as regular SSL certificates. The green padlock in your address bar signifies that the site your are looking at is the site you intended to see, and that anything you send to the site is not readable by others.

This does not protect against your site being hacked course, so regular security measures still apply.


This support is based on the https://github.com/Daplie/letsencrypt-express client, many thanks to them!

Let’s Encrypt is sponsored by these outstanding companies.

The relevant KeystoneJS code was contributed by Yaska.eu.