Skip to main content

Keycloak + Pomerium (OIDC)

Keycloak is an open-source identity and access management solution that supports the OpenID Connect (OIDC) specification. With Pomerium as your identity-aware proxy, you can authenticate and authorize requests to your applications while letting Keycloak handle user sign-in, tokens, and sessions.

This guide shows how to integrate a self-hosted Keycloak instance as your OIDC provider for Pomerium. The steps focus on Keycloak but apply to most generic OIDC providers.

Prerequisites

Docker Compose Configuration

Create a file named docker-compose.yaml:

docker-compose.yaml
services:
mykeycloak:
image: quay.io/keycloak/keycloak:22.0.1
command:
- start-dev
environment:
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
ports:
- 8080:8080
networks:
default:
aliases:
- keycloak.localhost.pomerium.io

pomerium:
image: pomerium.com/pomerium/pomerium:latest
volumes:
- ./config.yaml:/pomerium/config.yaml:ro
ports:
- 443:443

verify:
image: pomerium.com/pomerium/verify:latest
environment:
JWKS_ENDPOINT: https://pomerium/.well-known/pomerium/jwks.json

Run docker compose up. When Keycloak starts, visit http://localhost:8080 to open the Keycloak Admin Console.

Keycloak Setup

Access the Keycloak admin console

Sign in with admin / admin.

Create a Realm

  1. Select master (top-left) and Create Realm.
  2. Enter a name (for example, Pomerium) and select Create.

Create a new realm

Create a User

  1. Go to Users and Add users.
  2. Enter a username and Create.
  3. Select Credentials, then Set password and disable Temporary.

Create a user Set the user's password

Create a Client

  1. Go to Clients > Create client.
  2. Client type: OpenID Connect.
  3. Client ID: mynewclient.
  4. Enable Standard flow and Direct access grants.
  5. Save.

Create a client

In Access settings:

  • Valid redirect URIs: https://authenticate.localhost.pomerium.io/oauth2/callback
  • Web Origins: https://authenticate.localhost.pomerium.io
  • Turn on Client authentication.

Save. Under Credentials, copy the Client secret:

Get client secret

Pomerium Configuration

Create config.yaml:

config.yaml
authenticate_service_url: https://authenticate.localhost.pomerium.io

idp_provider: oidc
idp_client_id: 'mynewclient'
idp_client_secret: 'your_client_secret' # Replace with the actual secret
idp_provider_url: 'http://keycloak.localhost.pomerium.io:8080/realms/Pomerium'

signing_key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSVA2TUN5UFI5OUNmSEVkU0s4cVdzbk51Q0RyMVZ3ay93RER1RVhyQitELzZvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFQ0JTK3gyQnJRNVJqNHJFcU5PSEVsUFVESXJiRlNhRitoWEhEL1RYby9rQWVKU1lJSjJHVwpZMnE0a0NPNTU4RmdoYmxDTUplYVdjV1luT3JuZkpxeXRnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=

routes:
- from: https://verify.localhost.pomerium.io
to: http://verify:8000
allow_any_authenticated_user: true
pass_identity_headers: true
Do not reuse this sample signing_key in production. :::

Test the Integration

Visit https://verify.localhost.pomerium.io.

tip

If you notice a self-signed certificate warning, see Handle Self-Signed Certificate Warning to bypass it.

You'll be redirected to Keycloak to sign in, then back to the Verify service:

Sign in to Keycloak Realm Access Verify app

You can see user claims from Keycloak in the JWT payload, confirming that Pomerium has authenticated and authorized your request.

Additional Resources