Using a reverse proxy

Learn how to configure Keycloak together with a reverse proxy, api gateway, or load balancer.

Distributed environments frequently require the use of a reverse proxy. For Keycloak, your choice of proxy modes depends on the TLS termination in your environment.

Proxy modes

The following proxy modes are available:

edge

Enables communication through HTTP between the proxy and Keycloak. This mode is suitable for deployments with a highly secure internal network where the reverse proxy keeps a secure connection (HTTP over TLS) with clients while communicating with Keycloak using HTTP.

reencrypt

Requires communication through HTTPS between the proxy and Keycloak. This mode is suitable for deployments where internal communication between the reverse proxy and Keycloak should also be protected. Different keys and certificates are used on the reverse proxy as well as on Keycloak.

passthrough

Enables communication through HTTP or HTTPS between the proxy and Keycloak. This mode is suitable for deployments where the reverse proxy is not terminating TLS. The proxy instead is forwarding requests to the Keycloak server so that secure connections between the server and clients are based on the keys and certificates used by the Keycloak server.

Configure the proxy mode in Keycloak

To select the proxy mode, enter this command:

bin/kc.[sh|bat] start --proxy <mode>

Configure the reverse proxy

Some Keycloak features rely on the assumption that the remote address of the HTTP request connecting to Keycloak is the real IP address of the clients machine.

When you have a reverse proxy or a load balancer in front of Keycloak, this might not be the case, so please make sure your reverse proxy is configured correctly by performing these actions:

  • Set the X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host HTTP headers.

To set these headers, consult the documentation for your reverse proxy.

Take extra precautions to ensure that the X-Forwarded-For header is set by your reverse proxy. If this header is incorrectly configured, rogue clients can set this header and trick Keycloak into thinking the client is connected from a different IP address than the actual address. This precaution can be more critical if you do any deny or allow listing of IP addresses.

Different context-path on reverse proxy

Keycloak assumes it is exposed through the reverse proxy under the same context path as Keycloak is configured for. By default Keycloak is exposed through the root (/), which means it expects to be exposed through the reverse proxy on / as well. You can use hostname-path or hostname-url in these cases, for example using --hostname-path=/auth if Keycloak is exposed through the reverse proxy on /auth.

Alternatively you can also change the context path of Keycloak itself to match the context path for the reverse proxy using the http-relative-path option, which will change the context-path of Keycloak itself to match the context path used by the reverse proxy.

Trust the proxy to set hostname

By default, Keycloak needs to know under which hostname it will be called. If your reverse proxy is configured to check for the correct hostname, you can set Keycloak to accept any hostname.

bin/kc.[sh|bat] start --proxy <mode> --hostname-strict=false

Exposing the administration console

By default, the administration console URLs are created solely based on the requests to resolve the proper scheme, host name, and port. For instance, if you are using the edge proxy mode and your proxy is misconfigured, backend requests from your TLS termination proxy are going to use plain HTTP and potentially cause the administration console from being accessible because URLs are going to be created using the http scheme and the proxy does not support plain HTTP.

In order to proper expose the administration console, you should make sure that your proxy is setting the X-Forwarded-* headers herein mentioned in order to create URLs using the scheme, host name, and port, being exposed by your proxy.

Exposed path recommendations

When using a reverse proxy, Keycloak only requires certain paths need to be exposed. The following table shows the recommended paths to expose.

Keycloak Path Reverse Proxy Path Exposed Reason

/

-

No

When exposing all paths, admin paths are exposed unnecessarily.

/admin/

-

No

Exposed admin paths lead to an unnecessary attack vector.

/js/

-

Yes (see note below)

Access to keycloak.js needed for "internal" clients, e.g. the account console

/welcome/

-

No

No need exists to expose the welcome page after initial installation.

/realms/

/realms/

Yes

This path is needed to work correctly, for example, for OIDC endpoints.

/resources/

/resources/

Yes

This path is needed to serve assets correctly. It may be served from a CDN instead of the Keycloak path.

/robots.txt

/robots.txt

Yes

Search engine rules

/metrics

-

No

Exposed metrics lead to an unnecessary attack vector.

/health

-

No

Exposed health checks lead to an unnecessary attack vector.

Note:
As it’s true that the js path is needed for internal clients like the account console, it’s good practice to use keycloak.js from a JavaScript package manager like npm or yarn for your external clients.

We assume you run Keycloak on the root path / on your reverse proxy/gateway’s public API. If not, prefix the path with your desired one.

Enabling client certificate lookup

When the proxy is configured as a TLS termination proxy the client certificate information can be forwarded to the server through specific HTTP request headers and then used to authenticate clients. You are able to configure how the server is going to retrieve client certificate information depending on the proxy you are using.

The server supports some of the most commons TLS termination proxies such as:

Proxy Provider

Apache HTTP Server

apache

HAProxy

haproxy

NGINX

nginx

To configure how client certificates are retrieved from the requests you need to:

Enable the corresponding proxy provider
bin/kc.[sh|bat] build --spi-x509cert-lookup-provider=<provider>
Configure the HTTP headers
bin/kc.[sh|bat] start --spi-x509cert-lookup-<provider>-ssl-client-cert=SSL_CLIENT_CERT --spi-x509cert-lookup-<provider>-ssl-cert-chain-prefix=CERT_CHAIN --spi-x509cert-lookup-<provider>-certificate-chain-length=10

When configuring the HTTP headers, you need to make sure the values you are using correspond to the name of the headers forwarded by the proxy with the client certificate information.

The available options for configuring a provider are:

Option Description

ssl-client-cert

The name of the header holding the client certificate

ssl-cert-chain-prefix

The prefix of the headers holding additional certificates in the chain and used to retrieve individual certificates accordingly to the length of the chain. For instance, a value CERT_CHAIN will tell the server to load additional certificates from headers CERT_CHAIN_0 to CERT_CHAIN_9 if certificate-chain-length is set to 10.

certificate-chain-length

The maximum length of the certificate chain.

trust-proxy-verification

Enable trusting NGINX proxy certificate verification, instead of forwarding the certificate to keycloak and verifying it in keycloak.

Configuring the NGINX provider

The NGINX SSL/TLS module does not expose the client certificate chain. Keycloak’s NGINX certificate lookup provider rebuilds it by using the Keycloak truststore.

If you are using this provider, please take a look at the Configuring trusted certificates for outgoing requests guide about how to configure a Keycloak Truststore.

Relevant options

Type Default

hostname-path

This should be set if proxy uses a different context-path for Keycloak.

CLI: --hostname-path

Env: KC_HOSTNAME_PATH

hostname-url

Set the base URL for frontend URLs, including scheme, host, port and path.

CLI: --hostname-url

Env: KC_HOSTNAME_URL

http-relative-path

Set the path relative to '/' for serving resources.

The path must start with a '/'.

CLI: --http-relative-path

Env: KC_HTTP_RELATIVE_PATH

/

proxy

The proxy address forwarding mode if the server is behind a reverse proxy.

CLI: --proxy

Env: KC_PROXY

none, edge, reencrypt, passthrough

none

On this page