Skip to content

Commit

Permalink
updated documentation for the verification
Browse files Browse the repository at this point in the history
  • Loading branch information
tsaarni committed Oct 31, 2024
1 parent 782fa00 commit 29724dd
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 35 deletions.
61 changes: 38 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@

This project provides an X509 client certificate lookup implementation for [Envoy proxy](https://www.envoyproxy.io/).
It allows Keycloak to retrieve the client certificate from the `x-forwarded-client-cert` (XFCC) header set by Envoy and use it for authorization.
For more information, refer to [Keycloak's reverse proxy documentation](https://www.keycloak.org/server/reverseproxy) and the section [Enabling client certificate lookup](https://www.keycloak.org/server/reverseproxy#_enabling_client_certificate_lookup).
See also [Envoy's documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert) on XFCC header.

See [Configuring Kubernetes Ingress Controllers for Client Certificate Forwarding](docs/ingress-controllers.md) for more information on how to configure Kubernetes ingress controllers for client certificate forwarding.
This project was created because the code submitted in [keycloak#33159](https://github.com/keycloak/keycloak/pull/33159) was not accepted.
Instead, Keycloak encourages the development of implementations for different proxies as extensions.


> ⚠️ **Alert:** There are implications that you should be aware of when enabling client certificate lookup in Keycloak.
For more information, see [Understanding Client Certificate Forwarding and Security Implications](docs/security-and-client-cert-forwarding.md).

This project was created because the code submitted in [keycloak#33159](https://github.com/keycloak/keycloak/pull/33159) was not accepted.
Instead, Keycloak encourages the development of implementations for different proxies as extensions.

## Installation

This project is not available on Maven Central.
Expand All @@ -26,6 +23,18 @@ Clone the repository and execute:
The JAR file will be created in the `target` directory.
Copy the JAR file to the `providers` directory in your Keycloak distribution.
For instance, in the official Keycloak Docker image releases, place the JAR file in the `/opt/keycloak/providers/`.

## Configuration

For information on how to use the project, refer to following documents:

* See [here](docs/ingress-controllers.md) on how to configure Kubernetes ingress controllers for client certificate forwarding.
* For more information on the Keycloak feature, refer to [Keycloak's reverse proxy documentation](https://www.keycloak.org/server/reverseproxy) and the section [Enabling client certificate lookup](https://www.keycloak.org/server/reverseproxy#_enabling_client_certificate_lookup).
* See also [Envoy's documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert) on XFCC header.


### Enable client certificate lookup (mandatory)

Add following command line parameter to `kc.sh` to choose the provider:

```
Expand All @@ -45,35 +54,41 @@ This project may require updates for newer Keycloak versions.
Refer to Keycloak's [Configuring Providers](https://www.keycloak.org/server/configuration-provider) documentation for more information.


## Configuration
### Authorizing clients that are allowed to send XFCC headers (optional)

### Authorizing clients that are allowed to send XFCC headers
If Keycloak is deployed in an environment where some clients must bypass the proxy, it is important to ensure that only Envoy can send XFCC headers.
This prevents clients from impersonating other users by sending XFCC headers.
For more information on the verification process, refer to [this section](docs/security-and-client-cert-forwarding.md#mitigation) of the security implications document.

If Keycloak is deployed in environment where not all requests are forwarded via the proxy, it is important to ensure that only requests from the proxy are allowed to send XFCC headers.
This is to prevent clients running inside the perimeter of the proxy from impersonating users.
The prerequisite for this is that the proxy uses TLS and client certificate authentication for the connection to Keycloak.
When the TLS connection is established, Keycloak will verify the client certificate, including the the certificate chain against trusted CAs.
After successful verification, the request is sent to Envoy Client certificate lookup SPI, which then uses the certificate chain information to authorize the use of XFCC headers.
Prerequisites:

The authorization is configured by specifying the expected list of X509 subject names in the client certificate chain:
* Envoy must TLS and client certificate authentication for its connection to Keycloak.
* Configure the list of expected client certificate subject names that are allowed to send XFCC headers.

The list is configured as a command line parameter to `kc.sh` in the following format:

```
--spi-x509cert-lookup-envoy-cert-path-verify="[ [ <leaf-cert>, <intermediate-cert>, ... ], ... ]"
--spi-x509cert-lookup-envoy-cert-path-verify="[ [ <leaf-cert-subject>, <intermediate-cert-subject>, ... ], ... ]"
```
The presence of this parameter is optional and its behavior is as follows:

The configuration is a JSON array of arrays.
Multiple chains of subject names can be specified in the configuration.
Each inner array represents a certificate chain, where the first element is the subject name of the leaf certificate and the following elements are for the intermediate certificates.
Root certificate is not included in the configuration.
| Parameter value | Description | Example |
| --- | --- | --- |
| Not set | Any client can send XFCC headers, and they will be processed. | N/A |
| Empty array | XFCC headers will not be processed from any client. | `--spi-x509cert-lookup-envoy-cert-path-verify='[]'` |
| Non-empty array | XFCC headers will be processed only if the client certificate chain matches the specified subject names. | `--spi-x509cert-lookup-envoy-cert-path-verify='[[ "CN=envoy" ]]'` |

For example, to allow the client certificate chain with the subject name `CN=envoy, O=example.com` and the intermediate certificate with the subject name `CN=intermediate, O=example.com`, use the following configuration:
The parameter value is a JSON array of arrays.
Each inner array represents a certificate chain, with the first element as the leaf certificate's subject name and subsequent elements as intermediate certificates.
Root certificates should not be included.
For example, to allow a client certificate chain with the subject name `CN=envoy, O=example.com` and an intermediate certificate with the subject name `CN=intermediate, O=example.com`, use:

```
--spi-x509cert-lookup-envoy-cert-path-verify='[["CN=envoy, O=example.com", "CN=intermediate, O=example.com"]]'
--spi-x509cert-lookup-envoy-cert-path-verify='[[ "CN=envoy, O=example.com", "CN=intermediate, O=example.com" ]]'
```

If the parameter is not set, the client certificate chain is not verified and all requests with XFCC headers are allowed.

The subject names must match exactly, as X.500 Distinguished Names (DN) are order-sensitive (`CN=envoy, O=example.com` is not the same as `O=example.com, CN=envoy`).
The path can be partial: verification succeeds if the expected subject names are found in order, even if the received chain has additional certificates.


## Development
Expand Down
25 changes: 13 additions & 12 deletions docs/security-and-client-cert-forwarding.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Understanding Client Certificate Forwarding and Security Implications

This document outlines the security implications and risks of enabling client certificate forwarding in reverse proxies.
This document outlines the security implications, risks of enabling client certificate forwarding in reverse proxies and mitigations.
These concerns are not exclusive to Envoy but apply to any reverse proxy that forwards client certificates.
The initial architectural assumption is that all requests originate from the proxy, preventing direct client access to Keycloak.
However, in environments like Kubernetes, some clients may bypass the proxy, leading to additional considerations.


## Overview

The `x-forwarded-client-cert` (XFCC) header is used by Envoy proxy to send the client certificate information to the backend service, such as Keycloak.
Expand All @@ -17,16 +16,15 @@ Keycloak then uses the certificate for authorization purposes.

![image](assets/xfcc-intro.drawio.svg)


## Scenarios

### Scenario 1: Failed Authentication of an Client Running Inside the Proxy's Perimeter

Pre-conditions:

* Keycloak is configured with the X509 client certificate lookup SPI for Envoy proxy.
* A client is created to Keycloak with "X509 client certificate" client authenticator enabled.
* A client running inside Kubernetes cluster connects to Keycloak directly, without going through the Envoy proxy, using mutually authenticated TLS.
- Keycloak is configured with the X509 client certificate lookup SPI for Envoy proxy.
- A client is created to Keycloak with "X509 client certificate" client authenticator enabled.
- A client running inside Kubernetes cluster connects to Keycloak directly, without going through the Envoy proxy, using mutually authenticated TLS.

Scenario:

Expand All @@ -39,10 +37,10 @@ The client certificate information from the TLS layer is not used.

Pre-conditions:

* Keycloak is configured with the X509 client certificate lookup SPI for Envoy proxy.
* A client is created to Keycloak with "X509 client certificate" client authenticator enabled.
* A malicious user has acquired (1) the client ID and (2) the subject name of the client certificate.
* Malicious user has gained access to the cluster e.g., through a compromised pod.
- Keycloak is configured with the X509 client certificate lookup SPI for Envoy proxy.
- A client is created to Keycloak with "X509 client certificate" client authenticator enabled.
- A malicious user has acquired (1) the client ID and (2) the subject name of the client certificate.
- Malicious user has gained access to the cluster e.g., through a compromised pod.

Scenario:

Expand All @@ -52,9 +50,12 @@ The forged certificate can be self-generated by the malicious user, as long as i

![image](assets/xfcc-scenario-2.drawio.svg)

## Mitigation

## TEST
The following diagram demonstrates the logic implemented by the [X509 client certificate lookup SPI for Envoy proxy](https://github.com/Nordix/keycloak-client-cert-lookup-for-envoy).
This mechanism is designed to accept client certificates forwarded by the Envoy proxy while also securely handling clients that bypass the proxy and connect directly to Keycloak.
These direct clients are authenticated using their TLS-level client certificates or other authenticators (e.g. client secret) and are prevented from impersonating other clients by sending XFCC headers.

This is a test
For this mitigation to be effective, Envoy must be configured to use TLS and client certificate authentication for its connection to Keycloak. Additionally, the X509 client certificate lookup SPI must be configured with the expected client certificate subject names for Envoy proxy.

![image](assets/client-authorization-flow.drawio.svg)

0 comments on commit 29724dd

Please sign in to comment.