Skip to main content

Install Pomerium using Helm

This guide will show you how to deploy Pomerium with Helm on Kubernetes.


After re-evaluating the complexity required to both use and manage Helm for Pomerium, we've opted not to continue updating our Helm chart. Instead we've created a simpler deployment method, which you can read about on our Kubernetes Quickstart page.


  • Install kubectl.

  • Install helm.

  • A Kubernetes provider.

    • A cluster, with your local kubectl authorized to interact with it. The cluster configuration and node pool will depend on your provider and the scope of your project.

    • Export the configuration file from your Kubernetes host and export it to your KUBECONFIG environment variable (usually by placing it in ~/.kube).

      See Organizing Cluster Access Using kubeconfig Files for more information.

    • A namespace in the cluster for Pomerium. This document assumes the namespace pomerium, which you can create with kubectl create namespace pomerium.

  • A configured identity provider.

  • A domain space. The steps below use * as a placeholder value. We have set DNS records for this domain space to point to (localhost), so you can use this domain space when testing Pomerium locally.

  • TLS certificates. If you don't yet have a production environment with trusted certificates, this page will cover using mkcert to create locally trusted certificates, and cert-manager to manage them in the cluster.

  • A Postgres database.


This configuration installs Postgres as the data broker service. While this isn't strictly required when running Pomerium by itself, it is necessary for Pomerium Enterprise, and still highly recommended if not.

The configuration detailed below uses the Pomerium Ingress Controller. See our Ingress Controller doc for more detailed information and configuration options.


This setup uses mkcert to generate certificates that are trusted by your local web browser for testing, and cert-manager to manage them. If you already have a certificate solution, you can skip the steps below and move on to the next stage.

Install mkcert

After installing mkcert, confirm the presence and names of your local CA files:

mkcert -install
The local CA is already installed in the system trust store! 👍
The local CA is already installed in the Firefox and/or Chrome/Chromium trust store! 👍

ls "$(mkcert -CAROOT)"
rootCA-key.pem rootCA.pem

The output of mkcert -install may vary depending on your operating system.

Install and Configure cert-manager

If you haven't already, install cert-manager and create a CA issuer. You can follow their docs (listed below) or use the steps provided:

  1. Create a namespace for cert-manager:

    kubectl create namespace cert-manager
  2. Add the repository and update Helm:

    helm repo add jetstack
    helm repo update
  3. Install cert-manager to your cluster:

    helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace \
    --version v1.4.0 --set installCRDs=true
  4. Confirm deployment with kubectl get pods --namespace cert-manager:

    kubectl get pods --namespace cert-manager
    cert-manager-5d7f97b46d-8g942 1/1 Running 0 33s
    cert-manager-cainjector-69d885bf55-6x5v2 1/1 Running 0 33s
    cert-manager-webhook-8d7495f4-s5s6p 1/1 Running 0 33s
  5. In your Pomerium namespace, create a Kubernetes secret for the rootCA-key file in your local CA root:

    kubectl create secret tls pomerium-tls-ca --namespace=pomerium \
    --cert="$(mkcert -CAROOT)/rootCA.pem" --key="$(mkcert -CAROOT)/rootCA-key.pem"
  6. Define an Issuer configuration in issuer.yaml:

    kind: Issuer
    name: pomerium-issuer
    namespace: pomerium
    secretName: pomerium-tls-ca
  7. Apply and confirm:

    kubectl apply -f issuer.yaml created

    kubectl get --namespace pomerium
    pomerium-issuer True 10s

Install Pomerium

  1. Set your kubectl context to the Pomerium namespace:

    kubectl config set-context --current --namespace=pomerium
  2. Create certificate configurations for Pomerium. Our example is named pomerium-certificates.yaml, to differentiate from a configuration file for Pomerium Enterprise, if you choose to install it later:

    kind: Certificate
    name: pomerium-cert
    namespace: pomerium
    secretName: pomerium-tls
    name: pomerium-issuer
    kind: Issuer
    - server auth
    - client auth
    - pomerium-proxy.pomerium.svc.cluster.local
    - pomerium-authorize.pomerium.svc.cluster.local
    - pomerium-databroker.pomerium.svc.cluster.local
    - pomerium-authenticate.pomerium.svc.cluster.local
    # TODO - If you're not using the Pomerium Ingress controller, you may want a wildcard entry as well.
    #- "*" # Quotes are required to escape the wildcard

    If you already have a domain space for Pomerium with a certificate solution, use it in place of

  3. Apply the certificate configuration, and confirm:

    kubectl apply -f pomerium-certificates.yaml
    kubectl get certificate
    pomerium-cert True pomerium-tls 10s
  4. Create a values file for Helm to use when installing Pomerium. Our example is named pomerium-values.yaml.

        {' '}

    {' '}
    <PomeriumValues />

    :::tip The options required in the `authenticate.idp` block will vary depending on your [identity provider].

    If you changed the `*` value in `pomerium-certificates.yaml` update `config.rootDomain` to match, omitting the `*`. :::


    <summary>Default Certificate</summary>


    If you're using a single wildcard certificate for all routes managed by Pomerium, you can set it in an annotation for the ingress controller.

        Add a block defining the default certificate to `pomerium-values.yaml`:

    defaultCertSecret: 'namespace/certSecretName'

    Now when defining ingresses you need not specify individual certificates, as documented in our example service below.


  5. Add Pomerium's Helm repo:

    helm repo add pomerium
  6. Install Pomerium to the cluster:

    helm upgrade --install pomerium pomerium/pomerium --values ./pomerium-values.yaml

Define a Test Service

  1. So that we can create a valid test route, add Bitnami's Helm repo to pull nginx from:

    helm repo add bitnami
  2. Update Helm:

    helm repo update
  3. Install nginx to the cluster:

    helm upgrade --install nginx bitnami/nginx --set service.type=ClusterIP
  4. Create a new Ingress manifest (example-ingress.yaml) for our test service:

    kind: Ingress
    name: hello
    annotations: pomerium-issuer '[{"allow":{"and":[{"domain":{"is":""}}]}}]'
    ingressClassName: pomerium
    - host:
    - backend:
    name: nginx
    name: http
    path: /
    pathType: Prefix
    - hosts:
  5. Apply the nginx Ingress manifest to the cluster:

    kubectl apply -f example-ingress.yaml

If you are installing Pomerium with a valid domain name and certificates, update your DNS records to point to the external IP address of the pomerium-proxy service:

kubectl get svc pomerium-proxy
pomerium-proxy LoadBalancer 443:30006/TCP,9090:30707/TCP 2m37s

For development and testing, you can use kubectl to create a local proxy:

sudo -E kubectl --namespace pomerium port-forward service/pomerium-proxy 443:443

Open a browser and navigate to

You can also navigate to the special pomerium endpoint to see your current user details.

currently logged in user

Next Steps

Congratulations on installing Pomerium to your Kubernetes cluster!