🔐 Free SSL, Free Wildcard SSL, and Fully Automated HTTPS for node.js, issued by Let's Encrypt v2 via ACME. Issues and PRs on Github.
Go to file
AJ ONeal 4294bf3870 update docs 2019-11-01 05:08:54 -06:00
bin tabs -> spaces 2019-10-31 16:26:18 -06:00
logo add some logos back 2019-11-01 04:34:43 -06:00
tests tabs -> spaces 2019-10-31 16:26:18 -06:00
.gitignore wip: yeah! 2019-10-20 02:51:19 -06:00
.prettierrc v3.0.7: update manager with bugfix 2019-10-29 04:25:38 -06:00
LICENSE Initial commit 2019-10-16 00:26:05 +00:00
MIGRATION_GUIDE_V2_V3.md add,update -> set 2019-10-31 16:25:43 -06:00
README.md update docs 2019-11-01 05:08:54 -06:00
accounts.js tabs -> spaces 2019-10-31 16:26:18 -06:00
certificates.js tabs -> spaces 2019-10-31 16:26:18 -06:00
errors.js tabs -> spaces 2019-10-31 16:26:18 -06:00
greenlock.js tabs -> spaces 2019-10-31 16:26:18 -06:00
manager-underlay.js tabs -> spaces 2019-10-31 16:26:18 -06:00
order.js tabs -> spaces 2019-10-31 16:26:18 -06:00
package-lock.json v3.0.16: update deps 2019-10-31 06:42:09 -06:00
package.json tabs -> spaces 2019-10-31 16:26:18 -06:00
plugins.js tabs -> spaces 2019-10-31 16:26:18 -06:00
user-events.js tabs -> spaces 2019-10-31 16:26:18 -06:00
utils.js tabs -> spaces 2019-10-31 16:26:18 -06:00


New Documentation & v2/v3 Migration Guide

Greenlock v3 was just released from private beta today (Nov 1st, 2019).

We're still working on the full documentation for this new version, so please be patient.

To start, check out the Migration Guide.

"Greenlock Logo"

"Greenlock Function"

Greenlock is Let's Encrypt for JavaScript

| Built by Root for Hub

Greenlock™ is an Automated Certificate Management Environement 🔐.

It uses Let's Encrypt to generate Free SSL Certificates, including Wildcard SSL. It supports Automated Renewal of certs for Fully Automated HTTPS.

It's written in plain JavaScript and works in Node, Browsers, and WebPack.

the easiest way to integrate Let's Encrypt into your projects, products, and infrastructure.

  • Wildcard Certificates
  • IoT Environments
  • Enterprise and On-Prem
  • Private Networks
  • Localhost Development
  • Web Hosting Providers
  • Commercial support

We've built it simple enough for Hobbyists, and robust enough for the Enterprise.

Easy to Customize

[Custom SSL Cert & Domain Management](https://git.rootprojects.org/root/greenlock-manager-test.js)

SSL Certificate & Domain Management

Full Docs: https://git.rootprojects.org/root/greenlock-manager-test.js

This is what keeps the mapping of domains <-> certificates. In many cases it will interact with the same database as the Key & Cert Store, and probably the code as well.

  • set({ subject, altnames, renewAt })
  • find({ altnames, renewBefore })
    // should return a list of site configs:
            subject: 'example.com',
            altnames: ['example.com', 'exampleapi.com'],
            renewAt: 1575197231760
            subject: '*.example.com',
            altnames: ['*.example.com'],
            renewAt: 1575197231760,
            challenges: {
                'dns-01': {
                    module: 'acme-dns-01-dnsimple',
                    apikey: 'xxxx'
  • remove({ subject })
  • defaults() (both getter and setter)
        "subscriberEmail": "jane@example.com",
        "agreeToTerms": true,
        "challenges": {
            "http-01": {
                "module": "acme-http-01-standalone"
[Custom Key & Cert Storage](https://git.rootprojects.org/root/greenlock-store-test.js)

Key and Certificate Store

Full Docs: https://git.rootprojects.org/root/greenlock-store-test.js

This set of callbacks update your service with new certificates and keypairs.

Account Keys (JWK)

(though typically you only have one account key - because you only have one subscriber email)

  • accounts.setKeypair({ email, keypair })
  • accounts.checkKeypair({ email })

Certificate Keys (JWK + PEM)

(typically you have one for each set of domains, and each load balancer)

  • certificates.setKeypair({ subject, keypair })
  • certificates.checkKeypair({ subject }) (these are fine to implement the same as above, swapping subject/email)

Certificate PEMs

  • certificates.set({ subject, pems })
  • certificates.check({ subject })
[Custom ACME HTTP-01 Challenges](https://git.rootprojects.org/root/acme-http-01-test.js)

ACME Challenge HTTP-01 Strategies

Full Docs: https://git.rootprojects.org/root/acme-http-01-test.js

This validation and authorization strategy is done over plain HTTP on Port 80.

These are used to set files containing tokens that Let's Encrypt will fetch from each domain before authorizing a certificate.

NOT for Wildcards.

  • init({ request })
  • set({ challenge: { type, token, keyAuthorization, challengeUrl } })
  • get({ challenge: { type, token } })
  • remove({ challenge: { type, token } })
[Custom ACME DNS-01 Challenges](https://git.rootprojects.org/root/acme-dns-01-test.js)

ACME Challenge DNS-01 Strategies

Full Docs https://git.rootprojects.org/root/acme-dns-01-test.js

This validation and authorization strategy is done over DNS on UDP and TCP ports 53.

For Wildcards

These are used to set TXT records containing tokens that Let's Encrypt will fetch for each domain before authorizing a certificate.

  • init({ request })
  • zones()
  • set({ challenge: { type, dnsZone, dnsPrefix, dnsHost, keyAuthorizationDigest } })
  • get({ challenge: { type, dnsZone, dnsPrefix, dnsHost } })
  • remove({ challenge: { type, dnsZone, dnsPrefix, dnsHost } })

JavaScript Library


// Creates an instance of greenlock with certain default values

var gl = Greenlock.create({
    // Staging for testing environments
    staging: true,

    // This should be the contact who receives critical bug and security notifications
    // Optionally, you may receive other (very few) updates, such as important new features
    maintainerEmail: 'jon@example.com'
Parameter Description
maintainerEmail the developer contact for critical bug and security notifications
packageAgent if you publish your package for others to use, require('./package.json').name here

Add Approved Domains

    // The "Let's Encrypt Subscriber" (often the same as the maintainer)
    // NOT the end customer (except where that is also the maintainer)
    subscriberEmail: 'jon@example.com',
    agreeToTerms: true
    challenges: {
      "http-01": {
        module: "acme-http-01-webroot",
        webroot: "/path/to/webroot"
Parameter Description
agreeToTerms (default: false) either 'true' or a function that presents the Terms of Service and returns it once accepted
challenges['http-01'] provide an http-01 challenge module
challenges['dns-01'] provide a dns-01 challenge module
challenges['tls-alpn-01'] provide a tls-alpn-01 challenge module
challenges[type].module the name of your challenge module
challenges[type].xxxx module-specific options
servername the default servername to use for non-sni requests (many IoT clients)
subscriberEmail the contact who agrees to the Let's Encrypt Subscriber Agreement and the Greenlock Terms of Service
this contact receives renewal failure notifications
store override the default storage module
store.module the name of your storage module
store.xxxx options specific to your storage module
    subject: 'example.com',
    altnames: ['example.com', 'www.example.com', 'exampleapi.com']
Parameter Description
subject the first domain on, and identifier of the certificate
altnames first domain, plus additional domains
note: the order should always be the same
subscriberEmail if different from the default (i.e. multi-tenant, whitelabel)
challenges (same as main config) use if this site needs to use non-default http-01 or dns-01 validation

Retrieve Certificates (One-Off)

Disclaimer: This is only intended for testing, demos, and SNICallback (in Greenlock Express).

Greenlock is intended to be left running to allow it to fetech and renew certifictates automatically.

It is intended that you use the store callbacks to new certificates instantly as soon as they renew. This also protects you from accidentally stampeding the Let's Encrypt API with hundreds (or thousands) of certificate requests.

return greenlock.get({ servername }).then(function(site) {
    if (!site) {
        console.log(servername + ' was not found in any site config');

    var privkey = site.pems.privkey;
    var fullchain = site.pems.cert + '\n' + site.pems.chain + '\n';
Parameter Description
servername the first domain on, and identifier of the certificate

Renew Certificates

This will renew only domains that have reached their renewAt or are within the befault renewOffset.

Note: This runs at regular intervals, multiple times a day, in the background. You are not required to call it. If you implement the store callbacks, the certificates will automatically be saved (and if you don't implement them, they all get saved to disk).

return greenlock.renew({}).then(function(results) {
    results.forEach(function(site) {
        if (site.error) {
            console.error(site.subject, site.error);
        console.log('Renewed certificate for', site.subject, site.altnames);
Parameter Type Description
(optional) ALL parameters are optional, but some should be paired
force bool force silly options, such as tiny durations
renewBefore ms Check domains that are scheduled to renew before the given date in milliseconds


npm install --save @root/greenlock
npm install --save greenlock-manager-fs
npm install --save greenlock-store-fs
npm install --save acme-http-01-standalone

HTTP-01 & DNS-01 Integrations

For Public Web Servers running on a VPS, the default HTTP-01 challenge plugin will work just fine for most people.

However, for

  • Wildcard Certificates
  • IoT Environments
  • Enterprise On-Prem
  • Private Networks

Greenlock provides an easy way to integrate Let's Encrypt with your existing services through a variety of DNS-01 infrastructure

Why Typically file propagation is faster and more reliably than DNS propagation. Therefore, http-01 will be preferred to dns-01 except when wildcards or private domains are in use.

http-01 will only be supplied as a defaut if no other challenge is provided.

You can use ACME (Let's Encrypt) with several ready-made integrations

Ready-made Integrations

Greenlock Express integrates between Let's Encrypt's ACME Challenges and many popular services.

Type Service Plugin
dns-01 CloudFlare acme-dns-01-cloudflare
dns-01 Digital Ocean acme-dns-01-digitalocean
dns-01 DNSimple acme-dns-01-dnsimple
dns-01 DuckDNS acme-dns-01-duckdns
http-01 File System / Web Root acme-http-01-webroot
dns-01 GoDaddy acme-dns-01-godaddy
dns-01 Gandi acme-dns-01-gandi
dns-01 NameCheap acme-dns-01-namecheap
dns-01 Name.com acme-dns-01-namedotcom
dns-01 Route53 (AWS) acme-dns-01-route53
http-01 S3 (AWS, Digital Ocean, Scaleway) acme-http-01-s3
dns-01 Vultr acme-dns-01-vultr
dns-01 Build your own acme-dns-01-test
http-01 Build your own acme-http-01-test
tls-alpn-01 Contact us -

Search acme-http-01- or acme-dns-01- on npm to find more.

Commercial Support

Do you need...

  • training?
  • specific features?
  • different integrations?
  • bugfixes, on your timeline?
  • custom code, built by experts?
  • commercial support and licensing?

You're welcome to contact us in regards to IoT, On-Prem, Enterprise, and Internal installations, integrations, and deployments.

We have both commercial support and commercial licensing available.

We also offer consulting for all-things-ACME and Let's Encrypt.

Legal & Rules of the Road

Greenlock™ is a trademark of AJ ONeal

The rule of thumb is "attribute, but don't confuse". For example:

Built with Greenlock Express (a Root project).

Please contact us if you have any questions in regards to our trademark, attribution, and/or visible source policies. We want to build great software and a great community.

Greenlock™ | MPL-2.0 | Terms of Use | Privacy Policy