One of my favorite current open source projects is Let’s Encrypt.  If you’re not already familiar with Let’s Encrypt, it’s both a set of software packages and a backend service layer that freely provides x.509 certificates that are implicitly trusted by most major browsers and operating systems.  Basically, with Let’s Encrypt, you can break free of the certificate authority cartel and get certificates that are just as cryptographically strong and secure at no cost.

I was recently talking to a customer about Let’s Encrypt and they asked me about using LE issued certificates with Twistlock, so I wrote this quick blog post to show how easy it is.  Remember that Twistlock has always shipped with it’s own self-signed CA that automatically issues x.509 certificates both for authentication to Twistlock and to protect our web UI and API via TLS.  While those certs are just as cryptographically strong as those issued by a well known CA, it’s a good practice to have that additional layer of defense in depth by making it easy for users to trust the signer.  While it’s technically possible to distribute our self-signed CA cert to your users, it’s much easier to just get LE certs that are trusted automatically.

The process we’ll follow to get the LE certs will be completely Dockerized – I’ll just run an LE provided image that will automate the entire process for certificate request and issuance using LE’s Certbot app and ACME request protocol.  As a user, I don’t need to do anything other than answer a few prompts and my certificates will be instantly issued to me and ready to use with Twistlock.

Note that the specific steps I’m following below uses LE’s online validation.  In this flow, the LE service will attempt to connect back to my host (where the Certbot app is running).  If you’re making a request in an environment where you can’t expose the host directly, you can also use their DNS based validation

First, let’s run a Dockerized version of Certbot:
root@my-host:/home/my-host# docker run -it --rm -p 443:443 --name certbot   -v /etc/letsencrypt:/etc/letsencrypt            -v /var/log/letsencrypt:/var/log/letsencrypt certonly --standalone -d

As you can see from the parameters I’m passing in Docker run, I provide the port that Certbot will listen on, the paths to write keys and log files, and the name I’m making the request for. Note that depending on my use cases, I may write the certificates to a volume that I map into another container later to make it easy to automate the entire flow.  In this example, though, we’ll keep it simple since we’ll be pasting these certificates into the Twistlock UI anyway.

When Certbot runs, it’ll automatically make the requests via ACME based on my inputs:

Unable to find image '' locally
latest: Pulling from letsencrypt/letsencrypt
3f992ab3df53: Pull complete
0aa0bd28396f: Pull complete
db7bb15088de: Pull complete
1b6d2bb5ddaa: Pull complete
a2bc8c956e6b: Pull complete
a3ed95caeb02: Pull complete
0188a1eb6a72: Pull complete
15e203f8acaf: Pull complete
5e51e50ba02e: Pull complete
76720957858d: Pull complete
d1c078317f7a: Pull complete
4c5b15d830d2: Pull complete
0c73a2e57e91: Pull complete
d373f519f3d0: Pull complete
03ca8876644f: Pull complete
f0a6a7ea38af: Pull complete
e32c63690ebd: Pull complete
Digest: sha256:8d8d3ae2e40846d402fa80436b59e4a50be02133f3b1861ea2a0c9f013b0736c
Status: Downloaded newer image for
Warning: This Docker image will soon be switching to Alpine Linux.
You can switch now using the certbot/certbot repo on Docker Hub.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices) (Enter 'c' to


Please read the Terms of Service at You must agree
in order to register with the ACME server at
(A)gree/(C)ancel: a

Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let’s Encrypt project and the non-profit
organization that develops Certbot? We’d like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
(Y)es/(N)o: n
Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for
Waiting for verification…
Cleaning up challenges

– Congratulations! Your certificate and chain have been saved at:
Your key file has been saved at:
Your cert will expire on 2017-10-15. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
“certbot renew”
– Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
– If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let’s Encrypt:
Donating to EFF:          

After the line about donating to EFF and Let’s Encrypt (which you totally should do!), you’re done with Certbot and the container exits.

Now, let’s look at the actual cert that was created (note the path ends with the hostname the request was issued to).

root@my-host:/home/my-host# openssl x509 -in /etc/letsencrypt/live/ -text
Version: 3 (0x2)
Serial Number:
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3
Not Before: Jul 17 17:18:00 2017 GMT
Not After : Oct 15 17:18:00 2017 GMT
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
X509v3 Subject Key Identifier:
X509v3 Authority Key Identifier:

Authority Information Access:
CA Issuers - URI:

X509v3 Subject Alternative Name:
X509v3 Certificate Policies:
User Notice:
Explicit Text: This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at

Let’s look at the other files in this path:

root@my-host:/home/my-host# ls /etc/letsencrypt/live/
cert.pem  chain.pem  fullchain.pem  privkey.pem  README

Finally, to use this cert with Twistlock, we just need to copy and paste the combined PEM of the certificate and key into the Console UI (shortened for brevity):

root@my-host:/home/my-host# cat /etc/letsencrypt/live/ /etc/letsencrypt/live/>; keys.pem
root@my-host:/home/my-host# cat keys.pem

Now, we just need to paste it into Twistlock:

After I do that, all future TLS connections are implicitly trusted using my new LE certificate:

Note that this validity and trust is implicit on macOS (and in Chrome, and on Windows) using the system wide CA trust store (as indicated by “Use System Defaults” above).

Pretty easy right?!  If you’ve worked in IT for very long, you’ve undoubtedly spent hundreds of dollars and many hours gettings certificates in the past, so it’s awesome to see how Let’s Encrypt has made this process as easy and accessible as it now is.

← Back to All Posts Next Post →