Example configs

A collection of copy-and-paste-able configurations for various types of clouds, use-cases, and deployments. These files can also be found in the git repository in the docs/docs/examples/ directory.

Remember to set your identity provider settings and to generate new secret keys!

Binary

  • Suitable for bare-metal and virtual-machines
  • No docker, docker-compose, or kubernetes required
  • Minimal configuration
  • Pomerium services are run in "all-in-one" mode
  • No load balancer required
  • Great for testing Pomerium
  • Routes default to hosted version of httpbin.org

Customize for your identity provider and run source ./env && ./bin/pomerium

#!/bin/bash

# Main configuration flags
# export ADDRESS=":8443"                      # optional, default is 443
# export POMERIUM_DEBUG=true                  # optional, default is false
# export SERVICE="all"                        # optional, default is all
# export LOG_LEVEL="info"                     # optional, default is debug

export AUTHENTICATE_SERVICE_URL=https://authenticate.corp.example.com
export AUTHORIZE_SERVICE_URL=https://authorize.corp.example.com

# Certificates can be loaded as files or base64 encoded bytes. If neither is set, a
# pomerium will attempt to locate a pair in the root directory
export CERTIFICATE_FILE="./cert.pem"        # optional, defaults to `./cert.pem`
export CERTIFICATE_KEY_FILE="./privkey.pem" # optional, defaults to `./certprivkey.pem`
# export CERTIFICATE="xxxxxx"                 # base64 encoded cert, eg. `base64 -i cert.pem`
# export CERTIFICATE_KEY="xxxx"               # base64 encoded key, eg. `base64 -i privkey.pem`

# Generate 256 bit random keys  e.g. `head -c32 /dev/urandom | base64`
export SHARED_SECRET=9wiTZq4qvmS/plYQyvzGKWPlH/UBy0DMYMA2x/zngrM=
export COOKIE_SECRET=uPGHo1ujND/k3B9V6yr52Gweq3RRYfFho98jxDG5Br8=
# If set, a JWT based signature is appended to each request header `x-pomerium-jwt-assertion`
# export SIGNING_KEY="Replace with base64'd private key from ./scripts/self-signed-sign-key.sh"

# Identity Provider Settings

# Azure
# export IDP_PROVIDER="azure"
# export IDP_PROVIDER_URL="https://login.microsoftonline.com/REPLACEME/v2.0"
# export IDP_CLIENT_ID="REPLACEME
# export IDP_CLIENT_SECRET="REPLACEME"

# Gitlab
# export IDP_PROVIDER="gitlab"
# export IDP_PROVIDER_URL="https://gitlab.onprem.example.com" # optional, defaults to `https://gitlab.com`
# export IDP_CLIENT_ID="REPLACEME
# export IDP_CLIENT_SECRET="REPLACEME"

## GOOGLE
export IDP_PROVIDER="google"
export IDP_PROVIDER_URL="https://accounts.google.com" # optional for google
export IDP_CLIENT_ID="REPLACE-ME.googleusercontent.com"
export IDP_CLIENT_SECRET="REPLACEME"

# IF GSUITE and you want to get user groups you will need to set a service account
# see identity provider docs for gooogle for more info :
# export IDP_SERVICE_ACCOUNT=$(echo '{"impersonate_user": "bdd@pomerium.io"}' | base64)

# OKTA
# export IDP_PROVIDER="okta"
# export IDP_CLIENT_ID="REPLACEME"
# export IDP_CLIENT_SECRET="REPLACEME"
# export IDP_PROVIDER_URL="https://REPLACEME.oktapreview.com/oauth2/default"

# OneLogin
# export IDP_PROVIDER="onelogin"
# export IDP_CLIENT_ID="REPLACEME"
# export IDP_CLIENT_SECRET="REPLACEME"
# export IDP_PROVIDER_URL="https://openid-connect.onelogin.com/oidc" #optional, defaults to `https://openid-connect.onelogin.com/oidc`

# export SCOPE="openid email" # generally, you want the default OIDC scopes

# Proxied routes and per-route policies are defined in a policy provided either
# directly as a base64 encoded yaml/json file, or as a path pointing to a
# policy file (`POLICY_FILE`)
export POLICY_FILE="./policy.example.yml"

Docker

Uses the latest pomerium build from docker hub. Docker and docker-compose are great tools for standing up and testing multiple service, and containers without having to stand-up a full on cluster.

Basic

  • Minimal container-based configuration.
  • Docker and Docker-Compose based.
  • Runs a single container for all pomerium services
  • Routes default to on-premise helloworld, httpbin.

Customize for your identity provider run docker-compose up -f basic.docker-compose.yml

basic.docker-compose.yml

# Example Pomerium configuration.
#
# NOTE! Change IDP_* settings to match your identity provider settings!
# NOTE! Generate new SHARED_SECRET and COOKIE_SECRET keys! e.g. `head -c32 /dev/urandom | base64`
# NOTE! Replace `corp.beyondperimeter.com` with whatever your domain is
# NOTE! Make sure certificate files (cert.pem/privkey.pem) are in the same directory as this file
# NOTE! Make sure your policy file (policy.example.yaml) is in the same directory as this file

version: "3"
services:
  pomerium:
    image: pomerium/pomerium:latest # or `build: .` to build from source
    environment:
      - POMERIUM_DEBUG=true
      - SERVICES=all
      - IDP_PROVIDER=google
      - IDP_PROVIDER_URL=https://accounts.google.com
      - IDP_CLIENT_ID=REPLACE_ME.apps.googleusercontent.com
      - IDP_CLIENT_SECRET=REPLACE_ME
      - SHARED_SECRET=aDducXQzK2tPY3R4TmdqTGhaYS80eGYxcTUvWWJDb2M=
      - COOKIE_SECRET=V2JBZk0zWGtsL29UcFUvWjVDWWQ2UHExNXJ0b2VhcDI=
      - CERTIFICATE_FILE=cert.pem
      - CERTIFICATE_KEY_FILE=privkey.pem
      - AUTHENTICATE_SERVICE_URL=https://authenticate.corp.beyondperimeter.com
      - AUTHORIZE_SERVICE_URL=https://authorize.corp.beyondperimeter.com
      - POLICY_FILE=./policy.yaml
    volumes:
      - ./cert.pem:/pomerium/cert.pem:ro
      - ./privkey.pem:/pomerium/privkey.pem:ro
      - ./policy.example.yaml:/pomerium/policy.yaml:ro
    ports:
      - 443:443

  # https://httpbin.corp.beyondperimeter.com
  httpbin:
    image: kennethreitz/httpbin:latest
    expose:
      - 80
  # https://hello.corp.beyondperimeter.com
  hello:
    image: gcr.io/google-samples/hello-app:1.0
    expose:
      - 8080

NGINX micro-services

  • Docker and Docker-Compose based.
  • Uses pre-configured built-in nginx load balancer
  • Runs separate containers for each service
  • Routes default to on-premise helloworld, and httpbin.

Customize for your identity provider run docker-compose up -f nginx.docker-compose.yml

nginx.docker-compose.yml

version: "3"
services:
  nginx:
    image: pomerium/nginx-proxy:latest
    ports:
      - "443:443"
    volumes:
      # NOTE!!! : nginx must be supplied with your wildcard certificates. And it expects
      # it in the format of whatever your wildcard domain name is in.
      # see : https://github.com/jwilder/nginx-proxy#wildcard-certificates
      # So, if your subdomain is corp.beyondperimeter.com, you'd have the following :
      - ./cert.pem:/etc/nginx/certs/corp.beyondperimeter.com.crt:ro
      - ./privkey.pem:/etc/nginx/certs/corp.beyondperimeter.com.key:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro

  pomerium-authenticate:
    image: pomerium/pomerium:latest # or `build: .` to build from source
    restart: always
    environment:
      - POMERIUM_DEBUG=true
      - SERVICES=authenticate
      # Identity Provider Settings (Must be changed!)
      - IDP_PROVIDER=google
      - IDP_PROVIDER_URL=https://accounts.google.com
      - IDP_CLIENT_ID=REPLACE_ME.apps.googleusercontent.com
      - IDP_CLIENT_SECRET=REPLACE_ME
      - SHARED_SECRET=aDducXQzK2tPY3R4TmdqTGhaYS80eGYxcTUvWWJDb2M=
      - COOKIE_SECRET=V2JBZk0zWGtsL29UcFUvWjVDWWQ2UHExNXJ0b2VhcDI=
      # nginx settings
      - VIRTUAL_PROTO=https
      - VIRTUAL_HOST=authenticate.corp.beyondperimeter.com
      - VIRTUAL_PORT=443
    volumes:
      - ./cert.pem:/pomerium/cert.pem:ro
      - ./privkey.pem:/pomerium/privkey.pem:ro
    expose:
      - 443

  pomerium-proxy:
    image: pomerium/pomerium:latest # or `build: .` to build from source
    restart: always
    environment:
      - POMERIUM_DEBUG=true
      - SERVICES=proxy
      - POLICY_FILE=policy.yaml
      - AUTHENTICATE_SERVICE_URL=https://authenticate.corp.beyondperimeter.com
      # IMPORTANT! If you are running pomerium behind another ingress (loadbalancer/firewall/etc)
      # you must tell pomerium proxy how to communicate using an internal hostname for RPC
      - AUTHENTICATE_INTERNAL_URL=pomerium-authenticate
      - AUTHORIZE_SERVICE_URL=https://pomerium-authorize
      # When communicating internally, rPC is going to get a name conflict expecting an external
      # facing certificate name (i.e. authenticate-service.local vs *.corp.example.com).
      - OVERRIDE_CERTIFICATE_NAME=*.corp.beyondperimeter.com
      - SHARED_SECRET=aDducXQzK2tPY3R4TmdqTGhaYS80eGYxcTUvWWJDb2M=
      - COOKIE_SECRET=V2JBZk0zWGtsL29UcFUvWjVDWWQ2UHExNXJ0b2VhcDI=
      # nginx settings
      - VIRTUAL_PROTO=https
      - VIRTUAL_HOST=*.corp.beyondperimeter.com
      - VIRTUAL_PORT=443
    volumes:
      - ./cert.pem:/pomerium/cert.pem:ro
      - ./privkey.pem:/pomerium/privkey.pem:ro
      - ./policy.example.yaml:/pomerium/policy.yaml:ro
    expose:
      - 443

  pomerium-authorize:
    image: pomerium/pomerium:latest # or `build: .` to build from source
    restart: always
    environment:
      - POMERIUM_DEBUG=true
      - SERVICES=authorize
      - POLICY_FILE=policy.yaml
      - SHARED_SECRET=aDducXQzK2tPY3R4TmdqTGhaYS80eGYxcTUvWWJDb2M=
      # nginx settings
      - VIRTUAL_PROTO=https
      - VIRTUAL_HOST=authorize.corp.beyondperimeter.com
      - VIRTUAL_PORT=443
    volumes:
      - ./cert.pem:/pomerium/cert.pem:ro
      - ./privkey.pem:/pomerium/privkey.pem:ro
      - ./policy.example.yaml:/pomerium/policy.yaml:ro
    expose:
      - 443

  # https://httpbin.corp.beyondperimeter.com
  httpbin:
    image: kennethreitz/httpbin:latest
    expose:
      - 80
  # https://hello.corp.beyondperimeter.com
  hello:
    image: gcr.io/google-samples/hello-app:1.0
    expose:
      - 8080

Helm

  • Uses Google Kubernetes Engine's built-in ingress to do HTTPS load balancing
  • HTTPS (TLS) between client, load balancer, and services
  • gRPC requests are routed behind the load balancer
  • Routes default to hosted version of httpbin.org
  • Includes installer script

helm_gke.sh

#!/bin/bash
# PRE-REQ: Install Helm : You should verify the content of this script before running.
# curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
# NOTE! This will create real resources on Google's cloud. Make sure you clean up any unused
# resources to avoid being billed. For reference, this tutorial cost me <10 cents for a couple of hours.
# NOTE! You must change the identity provider client secret setting, and service account setting!
# NOTE! If you are using gsuite, you should also set `authenticate.idp.serviceAccount`, see docs !

echo "=> [GCE] creating cluster"
gcloud container clusters create pomerium

echo "=> [GCE] get cluster credentials so we can use kubctl locally"
gcloud container clusters get-credentials pomerium

echo "=> [GCE] ensure your user account has the cluster-admin role in your cluster"
kubectl create \
	clusterrolebinding \
	user-admin-binding \
	--clusterrole=cluster-admin \
	--user=$(gcloud config get-value account)

echo "=> Create a service account that Tiller, the server side of Helm, can use for deploying your charts."
kubectl create serviceaccount tiller --namespace kube-system

echo "=> Grant the Tiller service account the cluster-admin role in your cluster"
kubectl create clusterrolebinding tiller-admin-binding --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

echo "=> initialize Helm to install Tiller in your cluster"
helm init --service-account=tiller
helm repo update

echo "=> wait a minute for tiller to get setup"
sleep 60

echo "=> install pomerium with helm"
echo " replace configuration settings to meet your specific needs and identity provider settings"

helm install ./helm/ \
	--set service.type="NodePort" \
	--set ingress.secret.name="pomerium-tls" \
	--set ingress.secret.cert=$(base64 -i "$HOME/.acme.sh/*.corp.pomerium.io_ecc/*.corp.pomerium.io.cer") \
	--set ingress.secret.key=$(base64 -i "$HOME/.acme.sh/*.corp.pomerium.io_ecc/*.corp.pomerium.io.key") \
	--set config.policy="$(cat policy.example.yaml | base64)" \
	--set authenticate.idp.provider="google" \
	--set authenticate.idp.clientID="REPLACE_ME" \
	--set authenticate.idp.clientSecret="REPLACE_ME" \
	--set-string ingress.annotations."kubernetes\.io/ingress\.allow-http"=false \
	--set ingress.annotations."cloud\.google\.com/app-protocols"=\"{\"https\":\"HTTPS\"}\"

# When done, clean up by deleting the cluster!
# helm del $(helm ls --all --short) --purge # deletes all your helm instances
# gcloud container clusters delete pomerium # deletes your cluster

Kubernetes

  • Uses Google Kubernetes Engine's built-in ingress to do HTTPS load balancing
  • HTTPS (TLS) between client, load balancer, and services
  • gRPC requests are routed behind the load balancer
  • Routes default to hosted version of httpbin.org
  • Includes installer script

kubernetes_gke

#!/bin/bash
# NOTE! This will create real resources on Google's cloud. Make sure you clean up any unused
# resources to avoid being billed. For reference, this tutorial cost me <10 cents for a couple of hours.
# NOTE! You must change the identity provider client secret setting, and service account setting!

echo "=> creating cluster"
gcloud container clusters create pomerium --num-nodes 1

echo "=> get cluster credentials os we can use kubctl locally"
gcloud container clusters get-credentials pomerium

echo "=> create pomerium namespace"
kubectl create ns pomerium

echo "=> create our cryptographically random keys forshared-secret andcookie-secret from urandom"
kubectl create secret generic -n pomerium shared-secret --from-literal=shared-secret=$(head -c32 /dev/urandom | base64)
kubectl create secret generic -n pomerium cookie-secret --from-literal=cookie-secret=$(head -c32 /dev/urandom | base64)

echo "=> initiliaze secrets for TLS wild card certificatescertificate andcertificate-key"
kubectl create secret generic -n pomerium certificate --from-literal=certificate=$(base64 -i cert.pem)
kubectl create secret generic -n pomerium certificate-key --from-literal=certificate-key=$(base64 -i privkey.pem)

echo "=> load TLS to ingress"
kubectl create secret tls -n pomerium pomerium-tls --key privkey.pem --cert cert.pem

echo "=> initiliaze a configmap setting for POLICY frompolicy.example.yaml"
kubectl create configmap -n pomerium policy --from-literal=policy=$(cat policy.example.yaml | base64)

echo "=> settingidp-client-secret, you changed this right? :)"
exit 1 # comment out or delete this line once you change the following two settings
kubectl create secret generic -n pomerium idp-client-secret --from-literal=idp-client-secret=REPLACE_ME
kubectl create secret generic -n pomerium idp-service-account --from-literal=idp-service-account=$(base64 -i gsuite.service.account.json)

echo "=> apply the proxy, authorize, and authenticate deployment configs"
kubectl apply -f docs/docs/examples/kubernetes/authorize.deploy.yml
kubectl apply -f docs/docs/examples/kubernetes/authenticate.deploy.yml
kubectl apply -f docs/docs/examples/kubernetes/proxy.deploy.yml

echo "=> apply the proxy, authorize, and authenticate service configs"
kubectl apply -f docs/docs/examples/kubernetes/proxy.service.yml
kubectl apply -f docs/docs/examples/kubernetes/authenticate.service.yml
kubectl apply -f docs/docs/examples/kubernetes/authorize.service.yml

echo "=> create and apply the Ingress; this is GKE specific"
kubectl apply -f docs/docs/examples/kubernetes/ingress.yml

# Alternatively, nginx-ingress can be used
# kubectl apply -f docs/docs/examples/kubernetes/ingress.nginx.yml

# When done, clean up by deleting the cluster!
# gcloud container clusters delete pomerium

authenticate.deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pomerium-authenticate
  labels:
    app: pomerium-authenticate
  namespace: pomerium
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pomerium-authenticate
  template:
    metadata:
      labels:
        app: pomerium-authenticate
    spec:
      containers:
        - image: pomerium/pomerium:latest
          name: pomerium-authenticate
          ports:
            - containerPort: 443
              name: https
              protocol: TCP
          env:
            - name: SERVICES
              value: authenticate
            - name: IDP_PROVIDER
              value: google
            - name: IDP_PROVIDER_URL
              value: https://accounts.google.com
            - name: IDP_CLIENT_ID
              value: 851877082059-bfgkpj09noog7as3gpc3t7r6n9sjbgs6.apps.googleusercontent.com 
            - name: SHARED_SECRET
              valueFrom:
                secretKeyRef:
                  name: shared-secret
                  key: shared-secret
            - name: COOKIE_SECRET
              valueFrom:
                secretKeyRef:
                  name: cookie-secret
                  key: cookie-secret
            - name: IDP_CLIENT_SECRET
              valueFrom:
                secretKeyRef:
                  name: idp-client-secret
                  key: idp-client-secret
            - name: IDP_SERVICE_ACCOUNT
              valueFrom:
                secretKeyRef:
                  name: idp-service-account
                  key: idp-service-account
            - name: CERTIFICATE
              valueFrom:
                secretKeyRef:
                  name: certificate
                  key: certificate
            - name: CERTIFICATE_KEY
              valueFrom:
                secretKeyRef:
                  name: certificate-key
                  key: certificate-key
          readinessProbe:
            httpGet:
              path: /ping
              port: 443
              scheme: HTTPS
          livenessProbe:
            httpGet:
              path: /ping
              port: 443
              scheme: HTTPS
            initialDelaySeconds: 10
            timeoutSeconds: 1

authenticate.service.yml

apiVersion: v1
kind: Service
metadata:
  name: pomerium-authenticate-service
  namespace: pomerium
  annotations:
    cloud.google.com/app-protocols: '{"https":"HTTPS"}'
spec:
  ports:
    - port: 443
      name: https
  selector:
    app: pomerium-authenticate
  type: NodePort

authorize.deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pomerium-authorize
  labels:
    app: pomerium-authorize
  namespace: pomerium
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pomerium-authorize
  template:
    metadata:
      labels:
        app: pomerium-authorize
    spec:
      containers:
        - image: pomerium/pomerium:latest
          name: pomerium-authorize
          ports:
            - containerPort: 443
              name: https
              protocol: TCP
          env:
            - name: POLICY
              valueFrom:
                configMapKeyRef:
                  name: policy
                  key: policy
            - name: SERVICES
              value: authorize
            - name: SHARED_SECRET
              valueFrom:
                secretKeyRef:
                  name: shared-secret
                  key: shared-secret
            - name: CERTIFICATE
              valueFrom:
                secretKeyRef:
                  name: certificate
                  key: certificate 
            - name: CERTIFICATE_KEY
              valueFrom:
                secretKeyRef:
                  name: certificate-key
                  key: certificate-key
          readinessProbe:
            httpGet:
              path: /ping
              port: 443
              scheme: HTTPS
          livenessProbe:
            httpGet:
              path: /ping
              port: 443
              scheme: HTTPS
            initialDelaySeconds: 10
            timeoutSeconds: 1

authorize.service.yml

apiVersion: v1
kind: Service
metadata:
  name: pomerium-authorize-service
  namespace: pomerium
  annotations:
    cloud.google.com/app-protocols: '{"https":"HTTPS"}'
spec:
  ports:
    - port: 443
      name: https
  selector:
    app: pomerium-authorize
  type: NodePort

proxy.deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pomerium-proxy
  labels:
    app: pomerium-proxy
  namespace: pomerium
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pomerium-proxy
  template:
    metadata:
      labels:
        app: pomerium-proxy
    spec:
      containers:
        - image: pomerium/pomerium:latest
          name: pomerium-proxy
          ports:
            - containerPort: 443
              name: https
              protocol: TCP
          env:
            - name: SERVICES
              value: proxy
            - name: AUTHORIZE_SERVICE_URL
              value: https://pomerium-authorize-service.pomerium.svc.cluster.local
            - name: AUTHENTICATE_SERVICE_URL
              value: https://authenticate.corp.beyondperimeter.com
            - name: AUTHENTICATE_INTERNAL_URL
              value: "pomerium-authenticate-service.pomerium.svc.cluster.local"
            - name: OVERRIDE_CERTIFICATE_NAME
              value: "*.corp.beyondperimeter.com"
            - name: SHARED_SECRET
              valueFrom:
                secretKeyRef:
                  name: shared-secret
                  key: shared-secret
            - name: COOKIE_SECRET
              valueFrom:
                secretKeyRef:
                  name: cookie-secret
                  key: cookie-secret
            - name: IDP_CLIENT_SECRET
              valueFrom:
                secretKeyRef:
                  name: idp-client-secret
                  key: idp-client-secret
            # e.g. service account for group retrieval, e.g. gsuite
            - name: IDP_SERVICE_ACCOUNT
              valueFrom:
                secretKeyRef:
                  name: idp-service-account
                  key: idp-service-account
            - name: CERTIFICATE
              valueFrom:
                secretKeyRef:
                  name: certificate
                  key: certificate
            - name: CERTIFICATE_KEY
              valueFrom:
                secretKeyRef:
                  name: certificate-key
                  key: certificate-key
            - name: POLICY
              valueFrom:
                configMapKeyRef:
                  name: policy
                  key: policy
          readinessProbe:
            httpGet:
              path: /ping
              port: 443
              scheme: HTTPS
          livenessProbe:
            httpGet:
              path: /ping
              port: 443
              scheme: HTTPS
            initialDelaySeconds: 10
            timeoutSeconds: 1

proxy.service.yml

apiVersion: v1
kind: Service
metadata:
  name: pomerium-proxy-service
  namespace: pomerium
  annotations:
    cloud.google.com/app-protocols: '{"https":"HTTPS"}'

spec:
  ports:
    - port: 443
      protocol: TCP
      name: https
      targetPort: https
  selector:
    app: pomerium-proxy
  type: NodePort

ingress.yml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: pomerium-ingress
  namespace: pomerium
  annotations:
    kubernetes.io/ingress.allow-http: "false"
    kubernetes.io/ingress.global-static-ip-name: pomerium

spec:
  tls:
    - secretName: pomerium-tls
      hosts:
        - "*.corp.beyondperimeter.com"
        - "authenticate.corp.beyondperimeter.com"
        - "authorize.corp.beyondperimeter.com"

  rules:
    - host: "*.corp.beyondperimeter.com"
      http:
        paths:
          - paths:
            backend:
              serviceName: pomerium-proxy-service
              servicePort: https
    - host: "authenticate.corp.beyondperimeter.com"
      http:
        paths:
          - paths:
            backend:
              serviceName: pomerium-authenticate-service
              servicePort: https
    - host: "authorize.corp.beyondperimeter.com"
      http:
        paths:
          - paths:
            backend:
              serviceName: pomerium-authorize-service
              servicePort: https