docs: add kubernetes (#33)

- Update PR template to use Go language conventions.
- Moved healthcheck middleware to hijack a request before logging.
- Rewrote the quickstart guides to follow a similar pattern.
- Added an overview blurb on pomerium and its goals.
- Add an "example config" section to docs.
This commit is contained in:
Bobby DeSimone 2019-01-27 22:22:14 -08:00 committed by GitHub
parent b1912128f3
commit bcecee5ee3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 663 additions and 105 deletions

98
docs/docs/examples.md Normal file
View file

@ -0,0 +1,98 @@
---
sidebarDepth: 3
---
# Example Configurations
A collection of copy-and-pasteable example pomerium configurations for various types of clouds, use-cases, and deployments. All of these files can also be found in the git repository in the `docs/docs/examples/` directory.
:::tip
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`
<<< @/env.example
## Docker
Uses the [latest pomerium build](https://hub.docker.com/r/pomerium/pomerium) 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.
- Uses pre-configured built-in nginx load balancer
- Runs separate containers for each service
- Comes with a pre-configured instance of on-prem Gitlab-CE
- Routes default to on-prem [helloworld], [httpbin] containers.
Customize for your identity provider run `docker-compose up -f basic.docker-compose.yml`
#### basic.docker-compose.yml
<<< @/docs/docs/examples/basic.docker-compose.yml
### Gitlab On-premise
- Docker and Docker-Compose based.
- Uses pre-configured built-in nginx load balancer
- Runs separate containers for each service
- Comes with a pre-configured instance of on-prem Gitlab-CE
- Routes default to on-prem [helloworld], [httpbin], and [gitlab] containers.
Customize for your identity provider run `docker-compose up -f gitlab.docker-compose.yml`
#### gitlab.docker-compose.yml
<<< @/docs/docs/examples/gitlab.docker-compose.yml
## Kubernetes
### Google Kubernetes Engine
- Uses GKE's built-in ingress to do [HTTPS load balancing]
- HTTPS (TLS) between client and load balancer
- Routes default to hosted version of httpbin.org
- Includes all-in-one script
#### kubernetes_gke.sh
<<< @/scripts/kubernetes_gke.sh
#### authenticate.deploy.yml
<<< @/docs/docs/examples/kubernetes/authenticate.deploy.yml
#### authenticate.service.yml
<<< @/docs/docs/examples/kubernetes/authenticate.service.yml
#### proxy.deploy.yml
<<< @/docs/docs/examples/kubernetes/proxy.deploy.yml
#### proxy.service.yml
<<< @/docs/docs/examples/kubernetes/proxy.service.yml
#### ingress.yml
<<< @/docs/docs/examples/kubernetes/ingress.yml
[gitlab]: https://docs.gitlab.com/ee/user/project/container_registry.html
[helloworld]: https://hub.docker.com/r/tutum/hello-world
[httpbin]: https://httpbin.org/
[https load balancing]: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress

View file

@ -0,0 +1,100 @@
# Example Pomerium configuration.
#
# NOTE! Change IDP_* settings to match your identity provider settings!
# NOTE! Generate new SHARED_SECRET and COOKIE_SECRET keys!
# 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! Wrap URLs in quotes to avoid parse errors
version: "3"
services:
# NGINX routes to pomerium's services depending on the request.
nginx-proxy:
image: jwilder/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
environment:
- SERVICES=authenticate
# auth settings
- REDIRECT_URL=https://sso-auth.corp.beyondperimeter.com/oauth2/callback
# Identity Provider Settings (Must be changed!)
- IDP_PROVIDER="google"
- IDP_PROVIDER_URL="https://accounts.google.com"
- IDP_CLIENT_ID=851877082059-bfgkpj09noog7as3gpc3t7r6n9sjbgs6.apps.googleusercontent.com
- IDP_CLIENT_SECRET=P34wwijKRNP3skP5ag5I12kz
- SCOPE="openid email"
- PROXY_ROOT_DOMAIN=beyondperimeter.com
- ALLOWED_DOMAINS=*
# shared service settings
# Generate 256 bit random keys e.g. `head -c32 /dev/urandom | base64`
- SHARED_SECRET=aDducXQzK2tPY3R4TmdqTGhaYS80eGYxcTUvWWJDb2M=
- COOKIE_SECRET=V2JBZk0zWGtsL29UcFUvWjVDWWQ2UHExNXJ0b2VhcDI=
# if passing certs as files
# - CERTIFICATE_KEY=corp.beyondperimeter.com.crt
# - CERTIFICATE_KEY_FILE=corp.beyondperimeter.com.key
# Or, you can pass certifcates as bas64 encoded values. e.g. `base64 -i cert.pem`
# - CERTIFICATE=
# - CERTIFICATE_KEY=
# nginx settings
- VIRTUAL_PROTO=https
- VIRTUAL_HOST=sso-auth.corp.beyondperimeter.com
- VIRTUAL_PORT=443
volumes: # volumes is optional; used if passing certificates as files
- ./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
environment:
- SERVICES=proxy
# proxy settings
- AUTHENTICATE_SERVICE_URL=https://sso-auth.corp.beyondperimeter.com
- ROUTES=https://httpbin.corp.beyondperimeter.com=http://httpbin,https://hello.corp.beyondperimeter.com=http://hello-world/
# Generate 256 bit random keys e.g. `head -c32 /dev/urandom | base64`
- SHARED_SECRET=aDducXQzK2tPY3R4TmdqTGhaYS80eGYxcTUvWWJDb2M=
- COOKIE_SECRET=V2JBZk0zWGtsL29UcFUvWjVDWWQ2UHExNXJ0b2VhcDI=
# If set, a JWT based signature is appended to each request header `x-pomerium-jwt-assertion`
# - SIGNING_KEY=LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU0zbXBaSVdYQ1g5eUVneFU2czU3Q2J0YlVOREJTQ0VBdFFGNWZVV0hwY1FvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFaFBRditMQUNQVk5tQlRLMHhTVHpicEVQa1JyazFlVXQxQk9hMzJTRWZVUHpOaTRJV2VaLwpLS0lUdDJxMUlxcFYyS01TYlZEeXI5aWp2L1hoOThpeUV3PT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
# if passing certs as files
# - CERTIFICATE_KEY=corp.beyondperimeter.com.crt
# - CERTIFICATE_KEY_FILE=corp.beyondperimeter.com.key
# Or, you can pass certifcates as bas64 encoded values. e.g. `base64 -i cert.pem`
# - CERTIFICATE=
# - CERTIFICATE_KEY=
# nginx settings
- VIRTUAL_PROTO=https
- VIRTUAL_HOST=*.corp.beyondperimeter.com
- VIRTUAL_PORT=443
volumes: # volumes is optional; used if passing certificates as files
- ./cert.pem:/pomerium/cert.pem:ro
- ./privkey.pem:/pomerium/privkey.pem:ro
expose:
- 443
# https://httpbin.corp.beyondperimeter.com
httpbin:
image: kennethreitz/httpbin:latest
expose:
- 80
# Simple hello world
# https://hello.corp.beyondperimeter.com
hello-world:
image: tutum/hello-world:latest
expose:
- 80

View file

@ -0,0 +1,91 @@
version: "3"
services:
nginx:
image: jwilder/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:
build: .
restart: always
depends_on:
- "gitlab"
environment:
- POMERIUM_DEBUG=true
- SERVICES=authenticate
# auth settings
- REDIRECT_URL=https://sso-auth.corp.beyondperimeter.com/oauth2/callback
- IDP_PROVIDER="gitlab"
- IDP_PROVIDER_URL=https://gitlab.corp.beyondperimeter.com
- IDP_CLIENT_ID=022dbbd09402441dc7af1924b679bc5e6f5bf0d7a555e55b38c51e2e4e6cee76
- IDP_CLIENT_SECRET=fb7598c520c346915ee369eee57688938fe4f31329a308c4669074da562714b2
- PROXY_ROOT_DOMAIN=beyondperimeter.com
- ALLOWED_DOMAINS=*
- SKIP_PROVIDER_BUTTON=false
# shared service settings
# Generate 256 bit random keys e.g. `head -c32 /dev/urandom | base64`
- SHARED_SECRET=aDducXQzK2tPY3R4TmdqTGhaYS80eGYxcTUvWWJDb2M=
- COOKIE_SECRET=V2JBZk0zWGtsL29UcFUvWjVDWWQ2UHExNXJ0b2VhcDI=
- VIRTUAL_PROTO=https
- VIRTUAL_HOST=sso-auth.corp.beyondperimeter.com
- VIRTUAL_PORT=443
volumes: # volumes is optional; used if passing certificates as files
- ./cert.pem:/pomerium/cert.pem:ro
- ./privkey.pem:/pomerium/privkey.pem:ro
expose:
- 443
pomerium-proxy:
build: .
restart: always
environment:
- POMERIUM_DEBUG=true
- SERVICES=proxy
# proxy settings
- AUTHENTICATE_SERVICE_URL=https://sso-auth.corp.beyondperimeter.com
- ROUTES=https://httpbin.corp.beyondperimeter.com=http://httpbin,https://hello.corp.beyondperimeter.com=http://hello-world/
# Generate 256 bit random keys e.g. `head -c32 /dev/urandom | base64`
- SHARED_SECRET=aDducXQzK2tPY3R4TmdqTGhaYS80eGYxcTUvWWJDb2M=
- COOKIE_SECRET=V2JBZk0zWGtsL29UcFUvWjVDWWQ2UHExNXJ0b2VhcDI=
- SIGNING_KEY=LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU0zbXBaSVdYQ1g5eUVneFU2czU3Q2J0YlVOREJTQ0VBdFFGNWZVV0hwY1FvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFaFBRditMQUNQVk5tQlRLMHhTVHpicEVQa1JyazFlVXQxQk9hMzJTRWZVUHpOaTRJV2VaLwpLS0lUdDJxMUlxcFYyS01TYlZEeXI5aWp2L1hoOThpeUV3PT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
# nginx settings
- VIRTUAL_PROTO=https
- VIRTUAL_HOST=*.corp.beyondperimeter.com
- VIRTUAL_PORT=443
volumes: # volumes is optional; used if passing certificates as files
- ./cert.pem:/pomerium/cert.pem:ro
- ./privkey.pem:/pomerium/privkey.pem:ro
expose:
- 443
gitlab:
hostname: gitlab.corp.beyondperimeter.com
image: gitlab/gitlab-ce:latest
restart: always
expose:
- 443
- 80
- 22
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.corp.beyondperimeter.com'
nginx['ssl_certificate'] = '/etc/gitlab/trusted-certs/corp.beyondperimeter.com.crt'
nginx['ssl_certificate_key'] = '/etc/gitlab/trusted-certs/corp.beyondperimeter.com.key'
VIRTUAL_PROTO: https
VIRTUAL_HOST: gitlab.corp.beyondperimeter.com
VIRTUAL_PORT: 443
volumes:
- ./cert.pem:/etc/gitlab/trusted-certs/corp.beyondperimeter.com.crt
- ./privkey.pem:/etc/gitlab/trusted-certs/corp.beyondperimeter.com.key
- $HOME/gitlab/config:/etc/gitlab
- $HOME/gitlab/logs:/var/log/gitlab
- $HOME/gitlab/data:/var/opt/gitlab

View file

@ -0,0 +1,82 @@
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: REDIRECT_URL
value: https://sso-auth.corp.beyondperimeter.com/oauth2/callback
- 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: PROXY_ROOT_DOMAIN
value: beyondperimeter.com
- name: ALLOWED_DOMAINS
value: "*"
- 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: CERTIFICATE
valueFrom:
secretKeyRef:
name: certificate
key: certificate
- name: CERTIFICATE_KEY
valueFrom:
secretKeyRef:
name: certificate-key
key: certificate-key
- name: VIRTUAL_PROTO
value: https
- name: VIRTUAL_HOST
value: sso-auth.corp.beyondperimeter.com
- name: VIRTUAL_PORT
value: "443"
readinessProbe:
httpGet:
path: /ping
port: 443
scheme: HTTPS
livenessProbe:
httpGet:
path: /ping
port: 443
scheme: HTTPS
initialDelaySeconds: 10
timeoutSeconds: 1

View file

@ -0,0 +1,14 @@
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

View file

@ -0,0 +1,39 @@
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"
- "sso-auth.corp.beyondperimeter.com"
rules:
- host: "*.corp.beyondperimeter.com"
http:
paths:
- path: /
backend:
serviceName: pomerium-proxy-service
servicePort: 443
- path: /*
backend:
serviceName: pomerium-proxy-service
servicePort: 443
- host: "sso-auth.corp.beyondperimeter.com"
http:
paths:
- path: /*
backend:
serviceName: pomerium-authenticate-service
servicePort: 443
- path: /
backend:
serviceName: pomerium-authenticate-service
servicePort: 443

View file

@ -0,0 +1,74 @@
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: ROUTES
value: https://httpbin.corp.beyondperimeter.com=https://httpbin.org
- name: SERVICES
value: proxy
- name: AUTHENTICATE_SERVICE_URL
value: https://sso-auth.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
- name: CERTIFICATE
valueFrom:
secretKeyRef:
name: certificate
key: certificate
- name: CERTIFICATE_KEY
valueFrom:
secretKeyRef:
name: certificate-key
key: certificate-key
- name: VIRTUAL_PROTO
value: https
- name: VIRTUAL_HOST
value: "*.corp.beyondperimeter.com"
- name: VIRTUAL_PORT
value: "443"
readinessProbe:
httpGet:
path: /ping
port: 443
scheme: HTTPS
livenessProbe:
httpGet:
path: /ping
port: 443
scheme: HTTPS
initialDelaySeconds: 10
timeoutSeconds: 1

View file

@ -0,0 +1,17 @@
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View file

@ -0,0 +1,212 @@
---
title: Identity Providers
description: >-
This article describes how to connect pomerium to third-party identity
providers / single-sign-on services. You will need to generate keys, copy
these into your promerium settings, and enable the connection.
---
# Identity Provider Configuration
This article describes how to configure pomerium to use a third-party identity service for single-sign-on.
There are a few configuration steps required for identity provider integration. Most providers support [OpenID Connect] which provides a standardized interface for authentication. In this guide we'll cover how to do the following for each identity provider:
1. Establish a **Redirect URL** with the identity provider which is called after authentication.
2. Generate a **Client ID** and **Client Secret**.
3. Configure pomerium to use the **Client ID** and **Client Secret** keys.
## Azure
If you plan on allowing users to log in using a Microsoft Azure Active Directory account, either from your company or from external directories, you must register your application through the Microsoft Azure portal. If you don't have a Microsoft Azure account, you can [signup](https://azure.microsoft.com/en-us/free) for free.
You can access the Azure management portal from your Microsoft service, or visit <https://portal.azure.com> and sign in to Azure using the global administrator account used to create the Office 365 organization.
::: tip
There is no way to create an application that integrates with Microsoft Azure AD without having **your own** Microsoft Azure AD instance.
:::
If you have an Office 365 account, you can use the account's Azure AD instance instead of creating a new one. To find your Office 365 account's Azure AD instance:
1. [Sign in](https://portal.office.com) to Office 365.
2. Navigate to the [Office 365 Admin Center](https://portal.office.com/adminportal/home#/homepage).
3. Open the **Admin centers** menu drawer located in the left menu.
4. Click on **Azure AD**.
This will bring you to the admin center of the Azure AD instance backing your Office 365 account.
### Create a new application
Login to Microsoft Azure and choose **Azure Active Directory** from the sidebar.
![Select Active Directory](./microsoft/azure-dashboard.png)
Then under **MANAGE**, select **App registrations**.
![Select App registrations](./microsoft/azure-app-registrations.png)
Then click on the **+ ADD** button to add a new application.
Enter a name for the application, select **Web app/API** as the **Application Type**, and for **Sign-on URL** enter your application URL.
![Create application form](./microsoft/azure-create-application.png)
Next you will need to create a key which will be used as the **Client Secret** in Pomeriunm's configuration settings. Click on **Keys** from the **Settings** menu.
Enter a name for the key and choose the desired duration.
::: tip
If you choose an expiring key, make sure to record the expiration date in your calendar, as you will need to renew the key (get a new one) before that day in order to ensure users don't experience a service interruption.
:::
Click on **Save** and the key will be displayed. **Make sure to copy the value of this key before leaving this screen**, otherwise you may need to create a new key. This value is used as the **Client Secret**.
![Creating a Key](./microsoft/azure-create-key.png)
Next you need to ensure that the Pomerium's Redirect URL is listed in allowed reply URLs for the created application. Navigate to **Azure Active Directory** -> **Apps registrations** and select your app. Then click **Settings** -> **Reply URLs** and add Pomerium's redirect URL. For example, `https://sso-auth.corp.beyondperimeter.com/oauth2/callback`.
![Add Reply URL](./microsoft/azure-redirect-url.png)
The final, and most unique step to Azure AD provider, is to take note of your specific endpoint. Navigate to **Azure Active Directory** -> **Apps registrations** and select your app. ![Application dashboard](./microsoft/azure-application-dashbaord.png) Click on **Endpoints**
![Endpoint details](./microsoft/azure-endpoints.png)
The **OpenID Connect Metadata Document** value will form the basis for Pomerium's **Provider URL** setting. For example, if your **Azure OpenID Connect** is `https://login.microsoftonline.com/0303f438-3c5c-4190-9854-08d3eb31bd9f/v2.0/.well-known/openid-configuration` your **Pomerium Identity Provider URL** would be `https://login.microsoftonline.com/0303f438-3c5c-4190-9854-08d3eb31bd9f/v2.0`.
### Configure Pomerium
At this point, you will configure the integration from the Pomerium side. Your [environmental variables] should look something like:
```bash
# Azure
REDIRECT_URL="https://sso-auth.corp.beyondperimeter.com/oauth2/callback"
IDP_PROVIDER="azure"
IDP_PROVIDER_URL="https://login.microsoftonline.com/{REPLACE-ME-SEE-ABOVE}/v2.0"
IDP_CLIENT_ID="REPLACE-ME"
IDP_CLIENT_SECRET="REPLACE-ME"
```
## Gitlab
:::warning
Gitlab currently does not provide callers with a user email, under any scope, to a caller unless that user has selected her email to be public. Because Pomerium is by nature very centric, users are cautioned from using Pomerium until [this gitlab bug](https://gitlab.com/gitlab-org/gitlab-ce/issues/44435#note_88150387) is fixed.
:::
Log in to your Gitlab account and go to the [APIs & services](https://console.developers.google.com/projectselector/apis/credentials).
Navigate to **User Settings** then **Applications** using the left-hand menu.
On the **Applications** page, add a new application by setting the following parameters:
Field | Description
------------ | --------------------------------------------
Name | The name of your web app
Redirect URI | `https://${redirect-url}/oauth2/callback`
Scopes | **Must** select **read_user** and **openid**
![Create New Credentials](./gitlab/gitlab-create-application.png)
1.Click **Save Application** to proceed.
Your `Client ID` and `Client Secret` will be displayed:
![Gitlab OAuth Client ID and Secret](./gitlab/gitlab-credentials.png)
Set `Client ID` and `Client Secret` in Pomerium's settings. Your [environmental variables] should look something like this.
```bash
REDIRECT_URL="https://sso-auth.corp.beyondperimeter.com/oauth2/callback"
IDP_PROVIDER="gitlab"
# NOTE!!! Provider url is optional, but should be set if you are running an on-premise instance
# defaults to : https://gitlab.com, a local copy would look something like `http://gitlab.corp.beyondperimeter.com`
IDP_PROVIDER_URL="https://gitlab.com"
IDP_CLIENT_ID="yyyy"
IDP_CLIENT_SECRET="xxxxxx"
```
When a user first uses pomerium to login, they will be presented with an authorization screen similar to the following.
![gitlab access authorization screen](./gitlab/gitlab-verify-access.png)
## Google
Log in to your Google account and go to the [APIs & services](https://console.developers.google.com/projectselector/apis/credentials). Navigate to **Credentials** using the left-hand menu.
![API Manager Credentials](./google/google-credentials.png)
On the **Credentials** page, click **Create credentials** and choose **OAuth Client ID**.
![Create New Credentials](./google/google-create-new-credentials.png)
On the **Create Client ID** page, select **Web application**. In the new fields that display, set the following parameters:
Field | Description
------------------------ | -----------------------------------------
Name | The name of your web app
Authorized redirect URIs | `https://${redirect-url}/oauth2/callback`
![Web App Credentials Configuration](./google/google-create-client-id-config.png)
Click **Create** to proceed.
Your `Client ID` and `Client Secret` will be displayed:
![OAuth Client ID and Secret](./google/google-oauth-client-info.png)
Set `Client ID` and `Client Secret` in Pomerium's settings. Your [environmental variables] should look something like this.
```bash
REDIRECT_URL="https://sso-auth.corp.beyondperimeter.com/oauth2/callback"
IDP_PROVIDER="google"
IDP_PROVIDER_URL="https://accounts.google.com"
IDP_CLIENT_ID="yyyy.apps.googleusercontent.com"
IDP_CLIENT_SECRET="xxxxxx"
```
## Okta
[Log in to your Okta account](https://login.okta.com) and head to your Okta dashboard. Select **Applications** on the top menu. On the Applications page, click the **Add Application** button to create a new app.
![Okta Applications Dashboard](./okta/okta-app-dashboard.png)
On the **Create New Application** page, select the **Web** for your application.
![Okta Create Application Select Platform](./okta/okta-create-app-platform.png)
Next, provide the following information for your application settings:
Field | Description
---------------------------- | -----------------------------------------------------
Name | The name of your application.
Base URIs (optional) | The domain(s) of your application.
Login redirect URIs | `https://${redirect-url}/oauth2/callback`.
Group assignments (optional) | The user groups that can sign in to this application.
Grant type allowed | **You must enable Refresh Token.**
![Okta Create Application Settings](./okta/okta-create-app-settings.png)
Click **Done** to proceed. You'll be taken to the **General** page of your app.
Go to the **General** page of your app and scroll down to the **Client Credentials** section. This section contains the **Client ID** and **Client Secret** to be used in the next step.
![Okta Client ID and Secret](./okta/okta-client-id-and-secret.png)
At this point, you will configure the integration from the Pomerium side. Your [environmental variables] should look something like this.
```bash
REDIRECT_URL="https://sso-auth.corp.beyondperimeter.com/oauth2/callback"
IDP_PROVIDER="okta"
IDP_PROVIDER_URL="https://dev-108295-admin.oktapreview.com/"
IDP_CLIENT_ID="0oairksnr0C0fEJ7l0h7"
IDP_CLIENT_SECRET="xxxxxx"
```
[environmental variables]: https://en.wikipedia.org/wiki/Environment_variable
[oauth2]: https://oauth.net/2/
[openid connect]: https://en.wikipedia.org/wiki/OpenID_Connect

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

53
docs/docs/readme.md Normal file
View file

@ -0,0 +1,53 @@
# Overview
## What
Pomerium is an open-source, identity-aware access proxy.
## Why
Traditional [perimeter](https://www.redbooks.ibm.com/redpapers/pdfs/redp4397.pdf) [security](https://en.wikipedia.org/wiki/Perimeter_Security)has some shortcomings, namely:
- Insider threat is not well addressed and 28% of breaches are [by internal actors](http://www.documentwereld.nl/files/2018/Verizon-DBIR_2018-Main_report.pdf).
- Impenetrable fortress in theory falls in practice; multiple entry points (like VPNs), lots of firewall rules, network segmentation creep.
- Failure to encapsulate a heterogeneous mix of cloud, on-premise, cloud, and multi-cloud environments.
- User's don't like VPNs.
Pomerium attempts to mitigate these shortcomings by by adopting the following principles.
- Trust flows from user, device, and context.
- Network location _does not impart trust_. Treat both internal and external networks as completely untrusted.
- Act like you are already breached, because your probably are.
- Every device, user, and application's communication should be authenticated, authorized, and encrypted.
- Policy should be dynamic, and built from multiple sources.
## Resources
### Books
- [Zero Trust Networks](http://shop.oreilly.com/product/0636920052265.do) by Gilman and Barth
### Papers
- Forrester [Build Security Into Your Network's DNA: The Zero Trust Network Architecture](http://www.virtualstarmedia.com/downloads/Forrester_zero_trust_DNA.pdf)
- Google BeyondCorp 1 [An overview: "A New Approach to Enterprise Security"](https://research.google.com/pubs/pub43231.html)
- Google BeyondCorp 2 [How Google did it: "Design to Deployment at Google"](https://research.google.com/pubs/pub44860.html)
- Google BeyondCorp 3 [Google's front-end infrastructure: "The Access Proxy"](https://research.google.com/pubs/pub45728.html)
- Google BeyondCorp 4 [Migrating to BeyondCorp: Maintaining Productivity While Improving Security](https://research.google.com/pubs/pub46134.html)
- Google BeyondCorp 5 [The human element: "The User Experience"](https://research.google.com/pubs/pub46366.html)
- Google BeyondCorp 6 [Secure your endpoints: "Building a Healthy Fleet"](https://ai.google/research/pubs/pub47356)
### Posts
- Google [Securing your business and securing your fleet the BeyondCorp way](https://cloud.google.com/blog/products/identity-security/securing-your-business-and-securing-your-fleet-the-beyondcorp-way)
- Google [Preparing for a BeyondCorp world: Understanding your device inventory](https://cloud.google.com/blog/products/identity-security/preparing-beyondcorp-world-understanding-your-device-inventory)
- Google [How BeyondCorp can help businesses be more productive](https://www.blog.google/products/google-cloud/how-beyondcorp-can-help-businesses-be-more-productive/)
- Google [How to use BeyondCorp to ditch your VPN, improve security and go to the cloud](https://www.blog.google/products/google-cloud/how-use-beyondcorp-ditch-your-vpn-improve-security-and-go-cloud/)
- Wall Street Journal [Google Moves Its Corporate Applications to the Internet](https://blogs.wsj.com/cio/2015/05/11/google-moves-its-corporate-applications-to-the-internet/)
### Videos
- [USENIX Enigma 2016 - NSA TAO Chief on Disrupting Nation State Hackers](https://youtu.be/bDJb8WOJYdA?list=PLKb9-P1fRHxhSmCy5OaYZ5spcY8v3Pbaf)
- [What, Why, and How of Zero Trust Networking](https://youtu.be/eDVHIfVSdIo?list=PLKb9-P1fRHxhSmCy5OaYZ5spcY8v3Pbaf) by Armon Dadgar, Hashicorp
- [O'Reilly Security 2017 NYC Beyondcorp: Beyond Fortress Security](https://youtu.be/oAvDASLehpY?list=PLKb9-P1fRHxhSmCy5OaYZ5spcY8v3Pbaf) by Neal Muller, Google
- [Be Ready for BeyondCorp: enterprise identity, perimeters and your application](https://youtu.be/5UiWAlwok1s?list=PLKb9-P1fRHxhSmCy5OaYZ5spcY8v3Pbaf) by Jason Kent

113
docs/docs/signed-headers.md Normal file
View file

@ -0,0 +1,113 @@
---
title: Signed Headers
description: >-
This article describes how to secure your app with signed headers. When
configured, pomerium uses JSON Web Tokens (JWT) to make sure that a request to
your app is authorized.
---
# Securing your app with signed headers
This page describes how to secure your app with signed headers. When configured, pomerium uses JSON Web Tokens (JWT) to make sure that a request to your app is authorized.
::: warning
Health checks don't include JWT headers and pomerium doesn't handle health checks. If your health check returns access errors, make sure that you have it configured correctly and that your JWT header validation whitelists the health check path.
:::
## Prerequisites
To secure your app with signed headers, you'll need the following:
- An application you want users to connect to.
- A [JWT] library that supports the `ES256` algorithm.
## Rationale
Signed headers provide **secondary** security in case someone bypasses mTLS and network segmentation. This protects your app from the following kind of risks:
- Pomerium is accidentally disabled;
- Misconfigured firewalls;
- Mutually-authenticated TLS;
- Access from within the project.
To properly secure your app, you must use signed headers for all app types.
## Verification
To secure your app with JWT, cryptographically verify the header, payload, and signature of the JWT. The JWT is in the HTTP request header `x-pomerium-iap-jwt-assertion`. If an attacker bypasses pomerium, they can forge the unsigned identity headers, `x-pomerium-authenticated-user-{email,id}`. JWT provides a more secure alternative.
Note that pomerium it strips the `x-pomerium-*` headers provided by the client when the request goes through the serving infrastructure.
Verify that the JWT's header conforms to the following constraints:
[JWT] | description
:-----: | ---------------------------------------------------------------------------------------------------
`exp` | Expiration time in seconds since the UNIX epoch. Allow 1 minute for skew.
`iat` | Issued-at time in seconds since the UNIX epoch. Allow 1 minute for skew.
`aud` | The client's final domain e.g. `httpbin.corp.example.com`.
`iss` | Issuer must be `pomerium-proxy`.
`sub` | Subject is the user's id. Can be used instead of the `x-pomerium-authenticated-user-id` header.
`email` | Email is the user's email. Can be used instead of the `x-pomerium-authenticated-user-email` header.
### Manual verification
Though you will very likely be verifying signed-headers programmatically in your application's middleware, and using a third-party JWT library, if you are new to JWT it may be helpful to show what manual verification looks like. The following guide assumes you are using the provided [docker-compose.yml] as a base and [httpbin]. Httpbin gives us a convienient way of inspecting client headers.
1. Provide pomerium with a base64 encoded Elliptic Curve ([NIST P-256] aka [secp256r1] aka prime256v1) Private Key. In production, you'd likely want to get these from your KMS.
```bash
# see ./scripts/generate_self_signed_signing_key.sh
openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem
openssl req -x509 -new -key ec_private.pem -days 1000000 -out ec_public.pem -subj "/CN=unused"
# careful! this will output your private key in terminal
cat ec_private.pem | base64
```
Copy the base64 encoded value of your private key to `pomerium-proxy`'s environmental configuration variable `SIGNING_KEY`.
```bash
SIGNING_KEY=ZxqyyIPPX0oWrrOwsxXgl0hHnTx3mBVhQ2kvW1YB4MM=
```
2. Reload `pomerium-proxy`. Navigate to httpbin (by default, `https://httpbin.corp.${YOUR-DOMAIN}.com`), and login as usual. Click **request inspection**. Select `/headers'. Click **try it out** and then **execute**. You should see something like the following.
![httpbin displaying jwt headers](./signed-headers/inspect-headers.png)
3. `X-Pomerium-Jwt-Assertion` is the signature value. It's less scary than it looks and basically just a compressed, json blob as described above. Navigate to [jwt.io] which provides a helpful GUI to manually verify JWT values.
4. Paste the value of `X-Pomerium-Jwt-Assertion` header token into the `Encoded` form. You should notice that the decoded values look much more familiar.
![httpbin displaying decoded jwt](./signed-headers/verifying-headers-1.png)
5. Finally, we want to cryptographically verify the validity of the token. To do this, we will need the signer's public key. You can simply copy and past the output of `cat ec_public.pem`.
![httpbin displaying verified jwt](./signed-headers/verifying-headers-2.png)
**Viola!** Hopefully walking through a manual verification has helped give you a better feel for how signed JWT tokens are used as a secondary validation mechanism in pomerium.
::: warning
In an actual client, you'll want to ensure that all the other claims values are valid (like expiration, issuer, audience and so on) in the context of your application. You'll also want to make sure you have a safe and reliable mechanism for distributing pomerium-proxy's public signing key to client apps (typically, a [key management service]).
:::
### Automatic verification
In the future, we will be adding example client implementations for:
- Python
- Go
- Java
- C#
- PHP
[developer tools]: https://developers.google.com/web/tools/chrome-devtools/open
[docker-compose.yml]: https://github.com/pomerium/pomerium/blob/master/docker-compose.yml
[httpbin]: https://httpbin.org/
[jwt]: https://jwt.io/introduction/
[jwt.io]: https://jwt.io/
[key management service]: https://en.wikipedia.org/wiki/Key_management
[nist p-256]: https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf
[secp256r1]: https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB