# Certificates

Certificates (opens new window) and TLS (opens new window) play a vital role in zero-trust networks, and in Pomerium.

This document covers a few options in how to generate and set up TLS certificates suitable for working with pomerium.

This guide uses the following tools and resources:

It should be noted that there are countless ways of building and managing public-key infrastructure (opens new window). And although we hope this guide serves as a helpful baseline for generating and securing pomerium with certificates, these instructions should be modified to meet your own organization's tools, needs, and constraints. In a production environment you will likely be using your corporate load balancer, or a key management system to manage your certificate authority infrastructure.

# Why

Since one of Pomerium's core principles is to treat internal and external traffic impartially, Pomerium uses mutually authenticated TLS (opens new window) ubiquitously. For example, Pomerium uses mTLS between:

  • end-user and Pomerium
  • Pomerium's services regardless of if the network is "trusted"
  • Pomerium and the destination application

# Setting up DNS

First, you'll want to set a CNAME (opens new window) record for wild-card domain name you will be using with Pomerium.

pomerium add a text entry to your dns records

# Certificates

# Per-route automatic certificates

Pomerium itself can be used to retrieve, manage, and renew certificates certificates for free using Let's Encrypt, the only requirement is that Pomerium is able to receive public traffic on ports 80/443. This is probably the easiest option.

autocert: true

See the Autocert and Autocert Directory settings for more details.

# Self-signed wildcard certificate

In production, we'd use a public certificate authority such as LetsEncrypt. But for a local proof of concept or for development, we can use mkcert (opens new window) to make locally trusted development certificates with any names you'd like. The easiest, is probably to use *.localhost.pomerium.io which we've already pre-configured to point back to localhost.

# Install mkcert.
go get -u github.com/FiloSottile/mkcert
# Bootstrap mkcert's root certificate into your operating system's trust store.
mkcert -install
# Create your wildcard domain.
# *.localhost.pomerium.io is helper domain we've hard-coded to route to localhost
mkcert "*.localhost.pomerium.io"

# Manual DNS Let's Encrypt wildcard certificate

Once you've setup your wildcard domain, we can use acme.sh to create a certificate-signing request with LetsEncrypt.

# acme.sh : https://github.com/Neilpang/acme.sh
#			curl https://get.acme.sh | sh
# if you use a DNS service that supports API access, you may be able to automate
# this process. See https://github.com/Neilpang/acme.sh/wiki/dnsapi

echo "=> first generate a certificate signing request!"
$HOME/.acme.sh/acme.sh \
	--issue \
	-k ec-256 \
	-d '*.corp.example.com' \
	--dns \

read -p "press anykey once you've updated your TXT entries"

$HOME/.acme.sh/acme.sh \
	--renew \
	--ecc \
	-k ec-256 \
	-d '*.corp.example.com' \
	--dns \

LetsEncrypt will respond with the corresponding TXT record needed to verify our domain.

pomerium add a text entry to your dns records

It may take a few minutes for the DNS records to propagate. Once it does, you can run the following command to complete the certificate request process.

Here's how the above certificates signed by LetsEncrypt correspond to their respective Pomerium configuration settings:

Pomerium Config Certificate file
CERTIFICATE $HOME/.acme.sh/*.corp.example.com_ecc/fullchain.cer
CERTIFICATE_KEY $HOME/.acme.sh/*.corp.example.com_ecc/*.corp.example.com.key

Your end users will see a valid certificate for all domains delegated by Pomerium.

pomerium valid certificate

pomerium certificates A+ ssl labs rating


LetsEncrypt certificates must be renewed every 90 days (opens new window).

# Resources

Certificates, TLS, and Public Key Cryptography is a vast subject we cannot adequately cover here so if you are new to or just need a brush up, the following resources may be helpful: