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.
48
docs/guide/docker.md
Normal file
|
@ -0,0 +1,48 @@
|
|||
# Docker
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A configured [identity provider]
|
||||
|
||||
## Install
|
||||
|
||||
Install [docker] and [docker-compose]. Docker-compose is a tool for defining and running multi-container Docker applications. We've created an example docker-compose file that creates a minimal, but complete test environnement for pomerium.
|
||||
|
||||
## Download
|
||||
|
||||
Copy and paste the contents of the provided example [basic.docker-compose.yml] and save it locally as `docker-compose.yml`.
|
||||
|
||||
## Configure
|
||||
|
||||
Edit the [docker-compose.yml] to match your [identity provider] settings.
|
||||
|
||||
Place your domain's wild-card TLS certificate next to the compose file. If you don't have one handy, the included [script] generates one from [LetsEncrypt].
|
||||
|
||||
## Run
|
||||
|
||||
You can then download the latest pomerium release of pomerium in docker form along some example containers and an nginx load balancer all in one step.
|
||||
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
Pomerium is configured to delegate access to two test apps [helloworld] and [httpbin].
|
||||
|
||||
## Navigate
|
||||
|
||||
Open a browser and navigate to `hello.your.domain.com` or `httpbin.your.domain.com`. You should see something like the following in your browser.
|
||||
|
||||

|
||||
|
||||
And in your terminal.
|
||||
|
||||
[](https://asciinema.org/a/tfbSWkUZgMRxHAQDqmcjjNwUg)
|
||||
|
||||
[basic.docker-compose.yml]: ../docs/examples.html#basic-docker-compose-yml
|
||||
[docker]: https://docs.docker.com/install/
|
||||
[docker-compose]: (https://docs.docker.com/compose/install/)
|
||||
[helloworld]: https://hub.docker.com/r/tutum/hello-world
|
||||
[httpbin]: https://httpbin.org/
|
||||
[identity provider]: ../docs/identity-providers.md
|
||||
[letsencrypt]: https://letsencrypt.org/
|
||||
[script]: https://github.com/pomerium/pomerium/blob/master/scripts/generate_wildcard_cert.sh
|
75
docs/guide/from-source.md
Normal file
|
@ -0,0 +1,75 @@
|
|||
# From source
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Install [git](https://git-scm.com/) version control system
|
||||
- Install the [go](https://golang.org/doc/install) programming language
|
||||
- A configured [identity provider].
|
||||
|
||||
## Download
|
||||
|
||||
Retrieve the latest copy of pomerium's source code by cloning the repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/pomerium/pomerium.git $HOME/pomerium
|
||||
```
|
||||
|
||||
## Make
|
||||
|
||||
Build pomerium from source in a single step using make.
|
||||
|
||||
```bash
|
||||
cd $HOME/pomerium
|
||||
make
|
||||
```
|
||||
|
||||
The command will run all the tests, some code linters, then build the binary. If all is good, you should now have a freshly built pomerium binary in the `pomerium/bin` directory.
|
||||
|
||||
## Configure
|
||||
|
||||
Make a copy of the [env.example] and name it something like `env`.
|
||||
|
||||
```bash
|
||||
cp env.example env
|
||||
```
|
||||
|
||||
Modify your `env` configuration to to match your [identity provider] settings.
|
||||
|
||||
```bash
|
||||
vim env
|
||||
```
|
||||
|
||||
Place your domain's wild-card TLS certificate next to the compose file. If you don't have one handy, the included [script] generates one from [LetsEncrypt].
|
||||
|
||||
## Run
|
||||
|
||||
Finally, source the the configuration `env` file and run pomerium.
|
||||
|
||||
```bash
|
||||
source ./env
|
||||
./bin/pomerium
|
||||
```
|
||||
|
||||
Assuming your configuration file ready to go, you can simply use this one-liner.
|
||||
|
||||
```bash
|
||||
make && source ./env && ./bin/pomerium
|
||||
```
|
||||
|
||||
## Navigate
|
||||
|
||||
Browse to `httpbin.your.domain.com`. You should see something like the following in your browser.
|
||||
|
||||

|
||||
|
||||
[certbot]: https://certbot.eff.org/docs/install.html
|
||||
[docker]: https://docs.docker.com/install/
|
||||
[docker-compose]: (https://docs.docker.com/compose/install/)
|
||||
[download]: https://github.com/pomerium/pomerium/releases
|
||||
[env.example]: https://github.com/pomerium/pomerium/blob/master/env.example
|
||||
[google gke]: https://cloud.google.com/kubernetes-engine/docs/quickstart#create_cluster
|
||||
[helloworld]: https://hub.docker.com/r/tutum/hello-world
|
||||
[httpbin]: https://httpbin.org/
|
||||
[identity provider]: ../docs/identity-providers.md
|
||||
[letsencrypt]: https://letsencrypt.org/
|
||||
[script]: https://github.com/pomerium/pomerium/blob/master/scripts/generate_wildcard_cert.sh
|
Before Width: | Height: | Size: 395 KiB |
Before Width: | Height: | Size: 240 KiB |
Before Width: | Height: | Size: 262 KiB |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 92 KiB |
|
@ -1,212 +0,0 @@
|
|||
---
|
||||
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.
|
||||
|
||||

|
||||
|
||||
Then under **MANAGE**, select **App registrations**.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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**.
|
||||
|
||||

|
||||
|
||||
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`.
|
||||
|
||||

|
||||
|
||||
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.  Click on **Endpoints**
|
||||
|
||||

|
||||
|
||||
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**
|
||||
|
||||

|
||||
|
||||
1.Click **Save Application** to proceed.
|
||||
|
||||
Your `Client ID` and `Client Secret` will be displayed:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
On the **Credentials** page, click **Create credentials** and choose **OAuth Client ID**.
|
||||
|
||||

|
||||
|
||||
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`
|
||||
|
||||

|
||||
|
||||
Click **Create** to proceed.
|
||||
|
||||
Your `Client ID` and `Client Secret` will be displayed:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
On the **Create New Application** page, select the **Web** for your application.
|
||||
|
||||

|
||||
|
||||
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.**
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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
|
BIN
docs/guide/kubernetes-gke.png
Normal file
After Width: | Height: | Size: 257 KiB |
83
docs/guide/kubernetes.md
Normal file
|
@ -0,0 +1,83 @@
|
|||
# Kubernetes
|
||||
|
||||
This quickstart will show you how to deploy Pomerium with Kubernetes. For the purpose of this guide, we will be using Google's Kubernetes Engine. However, there are countless ways to work with Kubernetes:
|
||||
|
||||
- [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/)
|
||||
- [Azure Kubernetes Service](https://azure.microsoft.com/en-us/services/kubernetes-service/)
|
||||
- [Amazon Elastic Kubernetes Service (Amazon EKS)](https://aws.amazon.com/eks/)
|
||||
- [OpenShift Kubernetes](https://www.openshift.com/learn/topics/kubernetes/)
|
||||
- Or locally, with [minikube](https://kubernetes.io/docs/setup/minikube/)
|
||||
|
||||
Most of the following steps should be very similar using any other provider.
|
||||
|
||||
:::tip
|
||||
|
||||
Google Cloud Platform has a [free trial with $300 credits](https://cloud.google.com/free/docs/gcp-free-tier).
|
||||
|
||||
:::
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A [Google Cloud Account](https://console.cloud.google.com/)
|
||||
- A configured [identity provider]
|
||||
- Install [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
|
||||
- Install the [Google Cloud SDK](https://cloud.google.com/kubernetes-engine/docs/quickstart)
|
||||
|
||||
## Download
|
||||
|
||||
Retrieve the latest copy of pomerium's source-code by cloning the repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/pomerium/pomerium.git $HOME/pomerium
|
||||
```
|
||||
|
||||
## Configure
|
||||
|
||||
Edit the the [example kubernetes files][./scripts/kubernetes_gke.sh] to match your [identity provider] settings:
|
||||
|
||||
- `./docs/docs/examples/authenticate.deploy.yml`
|
||||
- `./docs/docs/examples/authenticate.service.yml`
|
||||
- `./docs/docs/examples/proxy.deploy.yml`
|
||||
- `./docs/docs/examples/proxy.service.yml`
|
||||
- `./docs/docs/examples/ingress.yml`
|
||||
|
||||
Place your domain's wild-card TLS certificate (`privkey.pem` and `cert.pem`) in the root of the repository. If you don't have one handy, the included [script] generates one from [LetsEncrypt].
|
||||
|
||||
Edit [./scripts/kubernetes_gke.sh] making sure to change the identity provider secret value to match your [identity provider] settings.
|
||||
|
||||
## Run
|
||||
|
||||
Run [./scripts/kubernetes_gke.sh] which will:
|
||||
|
||||
1. Provision a new cluster
|
||||
2. Create authenticate and proxy [deployments](https://cloud.google.com/kubernetes-engine/docs/concepts/deployment).
|
||||
3. Provision and apply authenticate and proxy [services](https://cloud.google.com/kubernetes-engine/docs/concepts/service).
|
||||
4. Configure an ingress to do serve TLS between client and load balancer
|
||||
|
||||
```bash
|
||||
sh ./scripts/kubernetes_gke.sh
|
||||
```
|
||||
|
||||
You should see roughly the following in your terminal. Note, provisioning does take a few minutes.
|
||||
|
||||
[](https://asciinema.org/a/223821)
|
||||
|
||||
And if you check out Google's Kubernetes Engine dashboard you'll see something like:
|
||||
|
||||

|
||||
|
||||
## Navigate
|
||||
|
||||
Open a browser and navigate to `httpbin.your.domain.com`.
|
||||
|
||||
You should see something like the following in your browser.
|
||||
|
||||

|
||||
|
||||
[./scripts/kubernetes_gke.sh]: ../docs/examples.html#google-kubernetes-engine
|
||||
[example kubernetes files]: ../docs/examples.html#google-kubernetes-engine
|
||||
[helloworld]: https://hub.docker.com/r/tutum/hello-world
|
||||
[httpbin]: https://httpbin.org/
|
||||
[identity provider]: ../docs/identity-providers.md
|
||||
[letsencrypt]: https://letsencrypt.org/
|
||||
[script]: https://github.com/pomerium/pomerium/blob/master/scripts/generate_wildcard_cert.sh
|
Before Width: | Height: | Size: 109 KiB |
Before Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 139 KiB |
|
@ -1,78 +1 @@
|
|||
# Quick start
|
||||
|
||||
## Using Docker
|
||||
|
||||
- Install [docker] and [docker-compose].
|
||||
- Grab Pomerium's included example [`docker-compose.yml`](https://raw.githubusercontent.com/pomerium/pomerium/master/docker-compose.yml) directly or by cloning the repository.
|
||||
- Update `docker-compose.yml` to match your [identity provider] settings.
|
||||
- Copy your subdomain's wild-card TLS certificate next to the compose file. If you don't have one handy, the included [script] generates one from [LetsEncrypt].
|
||||
- Run docker-compose by runnig the command `$ docker-compose up`.
|
||||
- Pomerium is configured to delegate access to two test apps [helloworld] and [httpbin]. Navigate to `hello.corp.example.com` or `httpbin.corp.example.com`. You should see something like the following in your browser and in your terminal.
|
||||
|
||||

|
||||
|
||||
[](https://asciinema.org/a/tfbSWkUZgMRxHAQDqmcjjNwUg)
|
||||
|
||||
## From source
|
||||
|
||||
### Get the code
|
||||
|
||||
Using [git](https://git-scm.com/), retrieve the latest copy of pomerium's source code by cloning the repository.
|
||||
|
||||
```bash
|
||||
# where `$HOME/pomerium` is the directory you want to save pomerium
|
||||
git clone https://github.com/pomerium/pomerium.git $HOME/pomerium
|
||||
```
|
||||
|
||||
Build pomerium from source in a single step using make.
|
||||
|
||||
```bash
|
||||
cd $HOME/pomerium
|
||||
make
|
||||
```
|
||||
|
||||
The command will run all the tests, some code linters, then build the binary. If all is good, you should now have a freshly built pomerium binary in the `pomerium/bin` directory.
|
||||
|
||||
### Configure
|
||||
|
||||
Make a copy of the [env.example] and name it something like `env`.
|
||||
|
||||
```bash
|
||||
cp env.example env
|
||||
```
|
||||
|
||||
Modify your `env` configuration to to match your [identity provider] settings.
|
||||
|
||||
```bash
|
||||
vim env
|
||||
```
|
||||
|
||||
### Run
|
||||
|
||||
Finally, source the the configuration `env` file and run pomerium.
|
||||
|
||||
```bash
|
||||
source ./env
|
||||
./bin/pomerium
|
||||
```
|
||||
|
||||
### All-in-one
|
||||
|
||||
Assuming your configuration file ready to go, you can simply use this one-liner.
|
||||
|
||||
```bash
|
||||
make && source ./env && ./bin/pomerium
|
||||
```
|
||||
|
||||
[certbot]: https://certbot.eff.org/docs/install.html
|
||||
[docker]: https://docs.docker.com/install/
|
||||
[docker-compose]: (https://docs.docker.com/compose/install/)
|
||||
[download]: https://github.com/pomerium/pomerium/releases
|
||||
[env.example]: https://github.com/pomerium/pomerium/blob/master/env.example
|
||||
[helloworld]: https://hub.docker.com/r/tutum/hello-world
|
||||
[httpbin]: https://httpbin.org/
|
||||
[identity provider]: ./identity-providers.md
|
||||
[kms]: https://en.wikipedia.org/wiki/Key_management
|
||||
[letsencrypt]: https://letsencrypt.org/
|
||||
[script]: https://github.com/pomerium/pomerium/blob/master/scripts/generate_wildcard_cert.sh
|
||||
[source]: https://github.com/pomerium/pomerium#start-developing
|
||||
# Prerequisites
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
---
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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`.
|
||||
|
||||

|
||||
|
||||
**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
|
Before Width: | Height: | Size: 450 KiB |
Before Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 386 KiB |