{project_name} freely discloses its own URLs, for instance through the OIDC Discovery endpoint, or as part of the password reset link in an email. If the hostname was dynamically interpreted from a hostname header, it could provide a potential attacker with an opportunity to manipulate a URL in the email, redirect a user to the attacker's fake domain, and steal sensitive data such as action tokens, passwords, etc.
By explicitly setting the `hostname` option, we avoid a situation where tokens could be issued by a fraudulent issuer. The server can be started with an explicit hostname using the following command:
NOTE: The examples start the {project_name} instance in production mode, which requires a public certificate and private key in order to secure communications. For more information, refer to the <@links.server id="configuration-production"/>.
As demonstrated in the previous example, the scheme and port are not explicitly required. In such cases, {project_name} automatically handles these aspects. For instance, the server would be accessible at `https://my.keycloak.org:8443` in the given example. However, a reverse proxy will typically expose {project_name} at the default ports, e.g. `443`. In that case it’s desirable to specify the full URL in the `hostname` option rather than keeping the parts of the URL dynamic. The server can then be started with:
Similarly, your reverse proxy might expose {project_name} at a different context path. It is possible to configure {proxy_name} to reflect that via the `hostname` and `hostname-admin` options. See the following example:
{project_name} has the capability to offer a separate URL for backchannel requests, enabling internal communication while maintaining the use of a public URL for frontchannel requests. Moreover, the backchannel is dynamically resolved based on incoming headers. Consider the following example:
In this manner, your applications, referred to as clients, can connect with {project_name} through your local network, while the server remains publicly accessible at `https://my.keycloak.org`.
As you can observe, the HTTPS protocol is the default choice, adhering to {project_name}'s commitment to security best practices. However, {project_name} also provides the flexibility for users to opt for HTTP if necessary. This can be achieved simply by specifying the HTTP listener, consult the <@links.server id="enabletls"/> for details. With an edge TLS-termination proxy you can start the server as follows:
The result of this configuration is that you can continue to access {project_name} at `https://my.keycloak.org` via HTTPS, while the proxy interacts with the instance using HTTP and port `8080`.
If you fully trust your proxy, which correctly sets the Forwarded header, and you don't want to hardcode the hostname, {project_name} can accommodate this. You simply need to initiate the server as follows:
The `proxy-headers` option can be also used to resolve the URL partially dynamically when `hostname` option is not specified as a full URL. For example:
In this case, scheme, port and context path are resolved dynamically from X-Forwarded-* headers, while hostname is statically defined as `my.keycloak.org`.
WARNING: If either `forwarded` or `xforwarded` is selected, make sure your reverse proxy properly sets and overwrites the `Forwarded` or `X-Forwarded-*` headers respectively. To set these headers, consult the documentation for your reverse proxy. Misconfiguration will leave {project_name} exposed to security vulnerabilities.
This allows you to access {project_name} at `https://my.keycloak.org` and the Admin Console at `https://admin.my.keycloak.org:8443`, while the backend continues to use `https://my.keycloak.org`.
NOTE: Keep in mind that hostname and proxy options do not change the ports on which the server listens. Instead it changes only the ports of static resources like JavaScript and CSS links, OIDC well-known endpoints, redirect URIs, etc. that will be used in front of the proxy. You need to use HTTP configuration options to change the actual ports the server is listening on. Refer to the <@links.server id="all-config"/> for details.
{project_name} exposes several endpoints, each with a different purpose. They are typically used for communication among applications or for managing the server. We recognize 3 main endpoint groups:
The base URL for each group has an important impact on how tokens are issued and validated, on how links are created for actions that require the user to be redirected to {project_name} (for example, when resetting password through email links), and, most importantly, how applications will discover these endpoints when fetching the OpenID Connect Discovery Document from `realms/{realm-name}/.well-known/openid-configuration`.
Users and applications use the frontend URL to access {project_name} through a front channel. The front channel is a publicly accessible communication channel. For example browser-based flows (accessing the login page, clicking on the link to reset a password or binding the tokens) can be considered as frontchannel requests.
The backend endpoints are those accessible through a public domain or through a private network. They're related to direct backend communication between {project_name} and a client (an application secured by {project_name}). Such communication might be over a local network, avoiding a reverse proxy. Examples of the endpoints that belong to this group are the authorization endpoint, token and token introspection endpoint, userinfo endpoint, JWKS URI endpoint, etc.
The default value of `hostname-backchannel-dynamic` option is `false`, which means that the backchannel URLs are same as the frontchannel URLs. Dynamic resolution of backchannel URLs from incoming request headers can be enabled by setting the following options:
Similarly to the base frontend URL, you can also set the base URL for resources and endpoints of the administration console. The server exposes the administration console and static resources using a specific URL. This URL is used for redirect URLs, loading resources (CSS, JS), etc. It can be done by setting the `hostname-admin` option:
* `hostname` URL and `hostname-admin` URL are verified that full URL is used, incl. scheme and hostname. Port is validated only if present, otherwise default port for given protocol is assumed (80 or 443).
* In production profile (`kc.sh|bat start`), either `--hostname` or `--hostname-strict false` must be explicitly configured.
** This does not apply for dev profile (`kc.sh|bat start-dev`) where `--hostname-strict false` is the default value.
* If `--hostname` is not configured:
** `hostname-backchannel-dynamic` must be set to false.
** `hostname-strict` must be set to false.
* If `hostname-admin` is configured, `hostname` must be set to a URL (not just hostname). Otherwise {project_name} would not know what is the correct frontend URL (incl. port etc.) when accessing the Admin Console.
* If `hostname-backchannel-dynamic` is set to true, `hostname` must be set to a URL (not just hostname). Otherwise {project_name} would not know what is the correct frontend URL (incl. port etc.) when being access via the dynamically resolved bachchannel.