Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4c5ce49
Update the openid-connect.js to current latest version
javorszky Sep 19, 2025
d4f3405
Update pytest keycloak from 25.0.2 to 26.3
javorszky Sep 26, 2025
f3a222e
Remove unused variable from test_oidc.py
javorszky Sep 26, 2025
d024309
Add front channel logout configs to oidc conf
javorszky Sep 26, 2025
23dd484
Move the idp sid keyval into virtualserver template
javorszky Sep 30, 2025
2fe9b3e
Update keycloak image version and env vars
javorszky Oct 2, 2025
16d4925
Fix virtualserver template and snaps
javorszky Oct 2, 2025
b88074e
Keycloak 26.4 uses button type submit
javorszky Oct 3, 2025
958a0e8
Add fclo example
javorszky Oct 13, 2025
ffcbeea
Turn on oidc debug flag if main error level is debug
javorszky Oct 15, 2025
8fdd238
Add logic to enable oidc debug variable
javorszky Oct 15, 2025
af5e2ce
Add oidc fclo test files
javorszky Oct 21, 2025
d05e340
Fix the create keycloak and test setup functionality
javorszky Oct 21, 2025
14e28d6
Add fclo page tests
javorszky Oct 21, 2025
588fe40
Finish pytest for oidc fclo
javorszky Oct 22, 2025
ee28fee
Add configmap and snap tests
javorszky Oct 22, 2025
6bb25ea
Rewrite readme for examples/oidc-fclo
javorszky Oct 22, 2025
eb73a3f
Update python:3.14-bookworm Docker digest to 0cc5dcf (main) (#8450)
renovate[bot] Oct 22, 2025
b6e7281
Use renovate to monitor test data yaml files (#8445)
pdabelf5 Oct 23, 2025
ecf361d
Factor out creating oidc policy in fclo pytest
javorszky Oct 23, 2025
e8bee1a
Merge branch 'main' into feat/7781-oidc-front-channel-logout
javorszky Oct 23, 2025
3518e69
Reword OIDC Policies in fclo example readme
javorszky Oct 23, 2025
4716226
Add more detail to fclo readme
javorszky Oct 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
463 changes: 0 additions & 463 deletions charts/tests/__snapshots__/helmunit_test.snap

Large diffs are not rendered by default.

144 changes: 144 additions & 0 deletions examples/custom-resources/oidc-fclo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# OIDC with Front Channel Logout

In this example, we deploy two web applications, configure load balancing for them via VirtualServers, and protect the
applications using an [OIDC Policies](https://docs.nginx.com/nginx-ingress-controller/configuration/policy-resource/#oidc) and [Keycloak](https://www.keycloak.org/), and ensure behaviour is consistent across multiple replicas by enabling [Zone Synchronization](https://docs.nginx.com/nginx/admin-guide/high-availability/zone_sync/).

**Note**: The KeyCloak container does not support IPv6 environments.

**Note**: This example assumes that your default namespace is set to `default`. You can check this with

```shell
kubectl config view --minify | grep namespace
```

If it's not empty, and anything other than `default`, you can set to `default` with the following command:

```shell
kubectl config set-context --namespace default --current
```

## Prerequisites

1. Follow the [installation](https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-manifests/)
instructions to deploy NGINX Ingress Controller. This example requires that the HTTPS port of the Ingress
Controller is `443`.
2. Save the public IP address of the Ingress Controller into `/etc/hosts` of your machine:

```text
...

XXX.YYY.ZZZ.III fclo-one.example.com
XXX.YYY.ZZZ.III fclo-two.example.com
XXX.YYY.ZZZ.III keycloak.example.com
```

Here `fclo-one.example.com` and `fclo-two.example.com` are the domains for the two web applications protected by OIDC authentication, and `keycloak.example.com` is the domain for the Keycloak IdP.

## Step 1 - Deploy a TLS Secret

Create a secret with the TLS certificate and key that will be used for TLS termination of the web applications and
Keycloak:

```shell
kubectl apply -f tls-secret.yaml
```

## Step 2 - Deploy a Web Application

Create the application deployments and services:

```shell
kubectl apply -f two-webapps.yaml
```

## Step 3 - Deploy Keycloak

1. Create the Keycloak deployment and service:

```shell
kubectl apply -f keycloak.yaml
```

2. Create a VirtualServer resource for Keycloak:

```shell
kubectl apply -f virtual-server-idp.yaml
```

## Step 4 - Configure Keycloak

To set up Keycloak follow the steps in the "Configuring Keycloak" [section of the documentation](keycloak_setup.md). That guide will get you to create a user, two OIDC clients, and save the client secrets in the necessary files.

## Step 5 - Deploy the Client Secrets

By this step, you should have encoded and edited both the `client-secret-one.yaml` and `client-secret-two.yaml` files. If you haven't, go back to the previous step.

Apply the secrets that will be used by the OIDC policies for the two virtual server:

```shell
kubectl apply -f client-secret-one.yaml
kubectl apply -f client-secret-two.yaml
```

## Step 6 - Configure Zone Synchronization and Resolver

In this step we configure:

- [Zone Synchronization](https://docs.nginx.com/nginx/admin-guide/high-availability/zone_sync/). For the OIDC feature to
work when you have two or more replicas of the Ingress Controller, it is necessary to enable zone synchronization
among the replicas. This is to ensure that each replica has access to the required session information when authenticating via IDP such as Keycloak.
- The resolver can resolve the host names.

Steps:

1. Apply the ConfigMap `nginx-config.yaml`, which contains `zone-sync` configuration parameter that enable zone synchronization and the resolver using the kube-dns service.

```shell
kubectl apply -f nginx-config.yaml
```

## Step 7 - Deploy the OIDC Policies

Create policies with the names `oidc-one-policy` and `oidc-two-policy` that references the secrets from the previous step:

```shell
kubectl apply -f oidc-one.yaml
kubectl apply -f oidc-two.yaml
```

## Step 8 - Configure Load Balancing

Create VirtualServer resources for the web applications:

```shell
kubectl apply -f two-virtual-servers.yaml
```

Note that the VirtualServers reference the policies `oidc-one-policy` and `oidc-two-policy` created in Step 6.

## Step 9 - Test the Configuration

1. Open a web browser and navigate to the URL of one of the web applications: `https://fclo-one.example.com`. You will be
redirected to Keycloak.
2. Log in with the username and password for the user you created in Keycloak, `nginx-user` and `test`.
![keycloak](./keycloak.webp)
3. Once logged in, you will be redirected to the web application and get a response from it. Notice the field `User ID`
in the response, this will match the ID for your user in Keycloak. ![webapp](./webapp.webp)
4. If you then navigate to the URL of the other web application, `https://fclo-two.example.com`, you will already be authenticated, and you will see the same `User ID` on the page.

## Step 10 - Log Out

**Note:** As Front Channel Logout depends on an invisible iframe from keycloak that points to different domains, your browser's Content Security Policy will normally refuse to make the request. In order to make this work, you will need to install a browser extension that disables applying any CSP headers. This will lower your browser's protection, so please make sure to remove or disable the extension as soon as you're done with the test.

1. To log out, navigate to `https://fclo-one.example.com/logout`. Your session will be terminated, and you will be
redirected to the default post logout URI `https://fclo-one.example.com/_logout`.
![logout](./logout.webp). You can also initiate this logout from the other webapp as well
2. To confirm that you have been logged out, navigate to `https://fclo-one.example.com` or `https://fclo-two.example.com`. You will be redirected to Keycloak to log in again.
3. To confirm that front channel logout was responsible for this, you can look at the `nginx-ingress` pod's logs. You should look for the following two lines:

```text
OIDC Front-Channel Logout initiated for sid: <uuid v4>
GET /front_channel_logout?sid=<uuid v4>
```

These should show up twice, once for each client.
7 changes: 7 additions & 0 deletions examples/custom-resources/oidc-fclo/client-secret-one.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: fclo-secret-one
type: nginx.org/oidc
data:
client-secret: <client secret here>
7 changes: 7 additions & 0 deletions examples/custom-resources/oidc-fclo/client-secret-two.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: fclo-secret-two
type: nginx.org/oidc
data:
client-secret: <client secret here>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions examples/custom-resources/oidc-fclo/keycloak.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
apiVersion: v1
kind: Service
metadata:
name: keycloak
labels:
app: keycloak
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: keycloak
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
labels:
app: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:26.4
args: ["start-dev"]
env:
- name: KC_BOOTSTRAP_ADMIN_USERNAME
value: "admin"
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
value: "admin"
- name: KC_PROXY_HEADERS
value: "xforwarded"
ports:
- name: http
containerPort: 8080
- name: https
containerPort: 8443
readinessProbe:
httpGet:
path: /realms/master
port: 8080
40 changes: 40 additions & 0 deletions examples/custom-resources/oidc-fclo/keycloak_setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Keycloak Setup for Front Channel Logout example

This guide will help you configure KeyCloak using its administration dashboard:

- Create two `client`s with IDs `fclo-one` and `fclo-two`.
- Add a user `nginx-user` with the password `test`.

**Notes**:

- This guide has been tested with keycloak 26.4 and later. If you modify `keycloak.yaml` to use an older version,
Keycloak may not start correctly or the commands in this guide may not work as expected. The Keycloak OpenID
endpoints in `oidc-one.yaml` and `oidc-two.yaml` might also be different in older versions of Keycloak.
- if you changed the admin username and password for Keycloak in `keycloak.yaml`, modify the commands accordingly.

Steps:

1. Make sure that you can reach the Keycloak admin page by going to <https://keycloak.example.com>
2. Log in with the admin username and password that's in the `keycloak.yaml` file
3. Create the user `nginx-user` by clicking the Users menu on the left sidebar, and then the Add User button
1. Set "email verified" to be true, enter username as `nginx-user`, and click Create
2. After you created the user, click the Credentials tab (second from the left), and click Set Password button
3. Enter a password, and make sure the Temporary toggle is turned off. Click Save, then click the red Save Password prompt
4. Create the two clients. Start by clicking the Client menu option on the sidebar on the left
5. For each of the clients
1. Click the blue Create Client button
2. Enter a new Client ID: either `fclo-one` or `fclo-two`. These are important, as the yaml files refer to the clients by them
3. Enter a name so they show up on a logout page, this can be anything you choose, as long as it's not empty
4. Make sure the Always Display in UI toggle is turned on
5. Click Next
6. Set Client Authentication to be "On"
7. Click Next
8. For root and home urls, enter `https://fclo-one.example.com`. Adjust to `fclo-two` for the other one
9. As valid redirect URIs, enter `https://fclo-one.example.com:443/*`. Both the port and the asterisk are important. Adjust to `fclo-two` for the other one
10. Click Save
11. Scroll down to the bottom to the Front Channel Logout section
12. Enter the front channel logout url: `https://fclo-one.example.com/front_channel_logout`. Adjust to `fclo-two` for the other client
13. Click save
14. Click on the Credentials tab at the top, and copy the Client Secret
15. In your terminal, base64 encode that secret with the following command: `echo -n "<secret>" | base64`
16. Copy the result into the `client-secret-one.yaml` file or `client-secret-two.yaml` file
Binary file added examples/custom-resources/oidc-fclo/logout.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions examples/custom-resources/oidc-fclo/nginx-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
namespace: nginx-ingress
data:
zone-sync: "true"
resolver-addresses: kube-dns.kube-system.svc.cluster.local
resolver-valid: 5s
error-log-level: "debug"
14 changes: 14 additions & 0 deletions examples/custom-resources/oidc-fclo/oidc-one.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: k8s.nginx.org/v1
kind: Policy
metadata:
name: oidc-one-policy
spec:
oidc:
clientID: fclo-one
clientSecret: fclo-secret-one
authEndpoint: https://keycloak.example.com/realms/master/protocol/openid-connect/auth
tokenEndpoint: http://keycloak.nginx-ingress.svc.cluster.local:8080/realms/master/protocol/openid-connect/token
jwksURI: http://keycloak.nginx-ingress.svc.cluster.local:8080/realms/master/protocol/openid-connect/certs
endSessionEndpoint: https://keycloak.example.com/realms/master/protocol/openid-connect/logout
scope: openid+profile+email
accessTokenEnable: true
14 changes: 14 additions & 0 deletions examples/custom-resources/oidc-fclo/oidc-two.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: k8s.nginx.org/v1
kind: Policy
metadata:
name: oidc-two-policy
spec:
oidc:
clientID: fclo-two
clientSecret: fclo-secret-two
authEndpoint: https://keycloak.example.com/realms/master/protocol/openid-connect/auth
tokenEndpoint: http://keycloak.nginx-ingress.svc.cluster.local:8080/realms/master/protocol/openid-connect/token
jwksURI: http://keycloak.nginx-ingress.svc.cluster.local:8080/realms/master/protocol/openid-connect/certs
endSessionEndpoint: https://keycloak.example.com/realms/master/protocol/openid-connect/logout
scope: openid+profile+email
accessTokenEnable: true
1 change: 1 addition & 0 deletions examples/custom-resources/oidc-fclo/tls-secret.yaml
41 changes: 41 additions & 0 deletions examples/custom-resources/oidc-fclo/two-virtual-servers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: fclo-one
spec:
host: fclo-one.example.com
tls:
secret: tls-secret
redirect:
enable: true
upstreams:
- name: fclo-one
service: fclo-one-svc
port: 80
routes:
- path: /
policies:
- name: oidc-one-policy
action:
pass: fclo-one
---
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: fclo-two
spec:
host: fclo-two.example.com
tls:
secret: tls-secret
redirect:
enable: true
upstreams:
- name: fclo-two
service: fclo-two-svc
port: 80
routes:
- path: /
policies:
- name: oidc-two-policy
action:
pass: fclo-two
Loading
Loading