<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Authentication on TechBlog about OpenShift/Ansible/Satellite and much more</title><link>https://blog.stderr.at/categories/authentication/</link><description>TechBlog about OpenShift/Ansible/Satellite and much more</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Toni Schmidbauer &amp; Thomas Jungbauer</copyright><lastBuildDate>Thu, 22 May 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.stderr.at/categories/authentication/index.xml" rel="self" type="application/rss+xml"/><item><title>Single log out from Keycloak and OpenShift</title><link>https://blog.stderr.at/openshift-platform/security/authentication/2025-05-22-keycloak-openshift-singlelogout/</link><pubDate>Thu, 22 May 2025 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/security/authentication/2025-05-22-keycloak-openshift-singlelogout/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;The following 1-minute article is a follow-up to my &lt;a href="https://blog.stderr.at/openshift/2025/05/step-by-step-using-keycloak-authentication-in-openshift/"&gt;previous article&lt;/a&gt; about how to use Keycloak as an authentication provider for OpenShift. In this article, I will show you how to configure Keycloak and OpenShift for Single Log Out (SLO). This means that when you log out from Keycloak, you will also be logged out from OpenShift automatically. This requires some additional configuration in Keycloak and OpenShift, but it is not too complicated.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The following prerequisites are required to follow this article:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;OpenShift 4.16 or higher with cluster-admin privileges&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keycloak installed and configured, as described in the &lt;a href="https://blog.stderr.at/openshift/2025/05/step-by-step-using-keycloak-authentication-in-openshift/"&gt;Step by Step - Using Keycloak Authentication in OpenShift&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_keycloak_configuration"&gt;Keycloak Configuration&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Configure the logout URL in Keycloak. This is done by adding a new &lt;strong&gt;Valid post logout redirect URIs&lt;/strong&gt; to the Keycloak client configuration. In this case, we want to call the OpenShift logout URL.
Which is: &lt;strong&gt;&lt;a href="https://oauth-openshift.apps.&amp;lt;your-cluster-name&amp;gt;/logout" class="bare"&gt;https://oauth-openshift.apps.&amp;lt;your-cluster-name&amp;gt;/logout&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This is done in the client settings:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/set-logout-url.png" alt="Set Logout URL"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_openshift_configuration"&gt;OpenShift Configuration&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now we need to configure OpenShift to use the logout URL. This is done by adding a new &lt;strong&gt;Post Logout Redirect URI&lt;/strong&gt; to the OpenShift Console configuration.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Modify the existing Console resource named cluster and add the logoutRedirect parameter to the authentication section.
The important pieces of the logout URL are the &lt;strong&gt;client_id&lt;/strong&gt; and the &lt;strong&gt;post_logout_redirect_uri&lt;/strong&gt;. The client ID must be the same as the Keycloak client ID, and the post logout redirect URI must be the OpenShift logout URL.
(Also change the &amp;lt;keycloakURL&amp;gt; and &amp;lt;realm&amp;gt; to your Keycloak URL and realm name.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock caution"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-caution" title="Caution"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Actually, instead of &lt;strong&gt;client_id&lt;/strong&gt;, the &lt;strong&gt;id_token_hint&lt;/strong&gt; should be used. But OpenShift does not store the token, so we are using the client ID instead.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: config.openshift.io/v1
kind: Console
metadata:
name: cluster
spec:
authentication:
logoutRedirect: &amp;#39;https://&amp;lt;keycloakURL&amp;gt;/realms/&amp;lt;realm&amp;gt;/protocol/openid-connect/logout?client_id=&amp;lt;realm&amp;gt;&amp;amp;post_logout_redirect_uri=https://console-openshift-console.apps.ocp.aws.ispworld.at&amp;#39; &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The logout URL for OpenShift. This is the URL that will be called when you log out from Keycloak. The URL must contain the client ID and the post logout redirect URI (console of OpenShift).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Wait a few moments until the OpenShift Console Operator applies the new configuration.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_testing_the_configuration"&gt;Testing the configuration&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now that the configuration is done, we can test the Single Log Out functionality.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;We are logged into OpenShift already as user &lt;strong&gt;testuser&lt;/strong&gt;&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/logged-in.png" alt="Logged in to OpenShift"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now we log out from OpenShift using the &lt;strong&gt;Log out&lt;/strong&gt; button in the upper right corner.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/logging-out.png" alt="Log out from OpenShift"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This will redirect us to the Keycloak logout page where we need to confirm the logout.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/keycloak-logout.png?width=420" alt="Keycloak Logout"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This will log us out from Keycloak and redirect us back to the OpenShift logout page.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/logged-out.png?width=420" alt="Logged out from OpenShift"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This is it. You are now logged out from both Keycloak and OpenShift. You can also check the Sessions in Keycloak to see that the session for the user is terminated.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As promised, this was a short article about how to configure Keycloak and OpenShift for Single Log Out. This is a beneficial feature if you want to ensure that users are logged out from all applications when they log out from Keycloak. It is also a good security practice to ensure that users are logged out from all applications when they are done using them.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Step by Step - Using Keycloak Authentication in OpenShift</title><link>https://blog.stderr.at/openshift-platform/security/authentication/2025-05-17-step-by-step-keycloak-and-openshift/</link><pubDate>Sat, 17 May 2025 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/security/authentication/2025-05-17-step-by-step-keycloak-and-openshift/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;I was recently asked about how to use Keycloak as an authentication provider for OpenShift. How to install Keycloak using the Operator and how to configure Keycloak and OpenShift so that users can log in to OpenShift using OpenID.
I have to admit that the exact steps are not easy to find, so I decided to write a blog post about it, describing each step in detail.
This time I will not use GitOps, but the OpenShift and Keycloak Web Console to show the steps, because before we put it into GitOps, we need to understand what is actually happening.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This article tries to explain every step required so that a user can authenticate to OpenShift using Keycloak as an Identity Provider (IDP) and that Groups from Keycloak are imported into OpenShift. This article does not cover a production grade installation of Keycloak, but only a test installation, so you can see how it works. For production, you might want to consider a proper database (maybe external, but at least with a backup), high availability, etc.).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The following prerequisites are required to follow this article:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;OpenShift 4.16 or higher with cluster-admin privileges&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_installing_keycloak_operator"&gt;Installing Keycloak Operator&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The very first step is to install the Keycloak Operator. This can be done using the OpenShift Web Console or the CLI or GitOps. I will show the steps using the OpenShift Web Console.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Installing the Keycloak Operator via GitOps can be seen in this &lt;a href="https://github.com/tjungbauer/openshift-clusterconfig-gitops/tree/main/clusters/management-cluster/setup-rh-build-of-keycloak" target="_blank" rel="noopener"&gt;GitHub repository&lt;/a&gt;. By the time you read this article, this repository will install and configure a Keycloak instance automatically using a local &lt;strong&gt;EXAMPLE&lt;/strong&gt; Postgres database. It does not yet import any Realm or additional configuration, but I will try to add this in the future when time allows. Oh, and it is just a demo and not production ready, so please do not use it in production.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Log in to the OpenShift Web Console as a user with cluster-admin privileges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the OpenShift Web Console, navigate to the Operators → OperatorHub.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the OperatorHub, search for &lt;strong&gt;Red Hat build of Keycloak&lt;/strong&gt; and select the Operator from the list.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/search-operator.png?width=320" alt="Search Keycloak Operator"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the latest version of the Keycloak Operator.&lt;/p&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
You can keep the default settings for the installation, but I recommend using a specific namespace. In this example, I will use the namespace &lt;code&gt;keycloak&lt;/code&gt; for the installation.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/install-operator.png?width=840" alt="Install Keycloak Operator"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Press the &lt;strong&gt;Install&lt;/strong&gt; button to install the Keycloak Operator. After a few minutes, the Keycloak Operator should be installed and running in the OpenShift cluster. You can check the status of the Operator in the &lt;strong&gt;Installed Operators&lt;/strong&gt; view.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/installed-operator.png" alt="Installed Keycloak Operator"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_create_a_local_example_postgres_database"&gt;Create a local example Postgres Database&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="admonitionblock caution"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-caution" title="Caution"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Demo only! This is not production ready and should not be used in production.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As a next step, we need to create a local Postgres database for Keycloak. Secrets are used to store the database credentials, and a simple StatefulSet is used to create the database. The database will be created in the same namespace as the Keycloak Operator.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;First, let’s create a Secret for the database credentials. In OpenShift select the &lt;strong&gt;keycloak&lt;/strong&gt; namespace and navigate to the &lt;strong&gt;Secrets&lt;/strong&gt; view. Create a new Secret with the following test configuration:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;kind: Secret
apiVersion: v1
metadata:
name: keycloak-db-secret
namespace: keycloak
stringData:
password: thisisonly4testingNOT4prod &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
username: testuser
type: Opaque&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The password for the database. This is just a test password and should not be used in production.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next, we need to create a StatefulSet for the Postgres database, again in the &lt;strong&gt;keycloak&lt;/strong&gt; namespace.
Again, as I cannot mention that enough, this is just a test configuration and should not be used in production.&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql-db
namespace: keycloak
spec:
serviceName: postgresql-db-service
selector:
matchLabels:
app: postgresql-db
replicas: 1 &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
template:
metadata:
labels:
app: postgresql-db
spec:
containers:
- name: postgresql-db
image: postgres:15 &lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
volumeMounts:
- mountPath: /data
name: psql
env: &lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
- name: POSTGRES_USER
value: testuser
- name: POSTGRES_PASSWORD
value: thisisonly4testingNOT4prod
- name: PGDATA
value: /data/pgdata
- name: POSTGRES_DB
value: keycloak
volumeClaimTemplates: &lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;
- metadata:
name: psql
spec:
accessModes: [ &amp;#34;ReadWriteOnce&amp;#34; ]
storageClassName: &amp;#34;gp3-csi&amp;#34;
resources:
requests:
storage: 10Gi&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The number of replicas for the database. In this example, we are using a single replica.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The image for the database, postgres version 15 in this example.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The environment variables for the database. The username and password are the same as in the Secret we created before, and &lt;strong&gt;clear text&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The volume for the database. In this example, the StatefulSet uses a volume claim template to create a volume with the size of 10 GB for the database. The volume is created using the &lt;code&gt;gp3-csi&lt;/code&gt; storage class. You can use any other storage class that is available in your OpenShift cluster or even remove this line and use the default class instead.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, we need to create a Service for the database so that the Keycloak Operator can access the database. Again, in the &lt;strong&gt;keycloak&lt;/strong&gt; namespace.&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: v1
kind: Service
metadata:
name: postgres-db
namespace: keycloak
spec:
selector:
app: postgresql-db &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
type: LoadBalancer
ports:
- port: 5432
targetPort: 5432&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The selector for the Service. This must match the label of the StatefulSet we created before.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_creating_a_keycloak_instance"&gt;Creating a Keycloak Instance&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now that the Keycloak Operator is installed and our example database is running, we can create a Keycloak instance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;In the OpenShift Web Console, navigate to the &lt;strong&gt;Installed Operators&lt;/strong&gt; view and select the Keycloak Operator. (Maybe you need to select the keycloak namespace first.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the Keycloak Operator view, create a new instance of &lt;strong&gt;Keycloak&lt;/strong&gt; and switch to the &lt;strong&gt;YAML&lt;/strong&gt; view.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/create-keycloak-instance.png?width=550" alt="Create Keycloak Instance"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock caution"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-caution" title="Caution"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
The fun part here is that the YAML example the Operator provides is actually &lt;strong&gt;wrong and does not work&lt;/strong&gt;. Something that kept me busy for a while.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace the YAML with the following configuration:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: keycloak &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
namespace: keycloak
labels:
app: sso
spec:
db: &lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
host: postgres-db
passwordSecret:
key: password
name: keycloak-db-secret
usernameSecret:
key: username
name: keycloak-db-secret
vendor: postgres
hostname: &lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
hostname: sso.apps.ocp.aws.ispworld.at
http: &lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;
tlsSecret: keycloak-certificate
instances: 1 &lt;i class="conum" data-value="5"&gt;&lt;/i&gt;&lt;b&gt;(5)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The name and the namespace of the Keycloak instance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The database configuration. In this example, we are using a local Postgres database. You can also use an external database, but you need to configure the connection string accordingly.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Hostname of our Keycloak instance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The TLS secret for the Keycloak instance. You need to create a TLS secret with the certificate and key for the hostname. This is where the example YAML is wrong. It tries to put &lt;em&gt;tlsSecret&lt;/em&gt; under &lt;em&gt;spec&lt;/em&gt;, but it should be under &lt;em&gt;http&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="5"&gt;&lt;/i&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The number of instances of Keycloak. In this example, we are using a single instance.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_what_about_the_ssl_certificate"&gt;What about the SSL Certificate?&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The Keycloak Operator does not create a certificate for the Keycloak instance. You need to create a certificate manually and store it in a secret. The Operator will use this secret to create the TLS certificate for the Keycloak instance.
In the example above we are referencing a secret called &lt;code&gt;keycloak-certificate&lt;/code&gt; in the &lt;code&gt;keycloak&lt;/code&gt; namespace. This secret was created using the &lt;strong&gt;Cert Manager Operator&lt;/strong&gt;. For example, you can use the following configuration to create a certificate for the Keycloak instance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: keycloak-certificate
namespace: keycloak
spec:
dnsNames:
- sso.apps.ocp.aws.ispworld.at &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
duration: 2160h0m0s
issuerRef:
kind: ClusterIssuer
name: letsencrypt-prod &lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
privateKey:
algorithm: RSA
encoding: PKCS1
rotationPolicy: Always
secretName: keycloak-certificate &lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The DNS name the Certificate is valid for. This should be the same as the hostname in the Keycloak instance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The issuer for the certificate. In this example, we are using the &lt;strong&gt;LetsEncrypt&lt;/strong&gt; ClusterIssuer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The name of the secret where the certificate is stored. This should be the same as the TLS secret in the Keycloak instance.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;I strongly recommend using the &lt;strong&gt;Cert Manager Operator&lt;/strong&gt; to automatically request and approve the certificate. However, if you do not have this automation in place, you can use a self-signed certificate. This certificate must be created manually and stored as a secret.
For example, you can use the following command to create a self-signed certificate and store it in a secret:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj &amp;#34;/CN=test.keycloak.org/O=Test Keycloak./C=US&amp;#34;
oc create secret -n keycloak tls keycloak-certificate2 --cert=tls.crt --key=tls.key&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_login_in_to_keycloak"&gt;Login in to Keycloak&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Once the Keycloak instance is created and all Pods (1) are running, you can log in to the Keycloak Admin Console using the following URL: &lt;a href="https://sso.apps.ocp.aws.ispworld.at" class="bare"&gt;https://sso.apps.ocp.aws.ispworld.at&lt;/a&gt;
This is the hostname we configured in the keycloak instance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To authenticate, you need to fetch the initial password for the admin user. This password is stored in a secret called &lt;strong&gt;keycloak-initial-admin&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;You can use the following command to fetch the password:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oc extract secret/keycloak-initial-admin -n keycloak --to=-&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;or you can use the OpenShift Web Console to view the secret.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Once authenticated, you should see the Keycloak Admin Console:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/keycloak-initial-login.png" alt="Keycloak Admin Console"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
The first thing you should do is to change the password for the admin user. I trust you know how to do this :)
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_configure_keycloak_to_be_used_by_openshift"&gt;Configure Keycloak to be used by OpenShift&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The next steps are to configure Keycloak to be used as an Identity Provider (IDP) for OpenShift. This is done by creating a new Realm and a new Client in Keycloak. The following steps will show you the minimum configuration required to use Keycloak as an IDP for OpenShift. It does not cover all the options and features of Keycloak (and there are a lot), but it should be enough to get you started.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The full documentation for Keycloak can be found at &lt;a href="https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/" target="_blank" rel="noopener"&gt;Keycloak Documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_create_a_new_realm_and_client"&gt;Create a new Realm and Client&lt;/h3&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;In the Realm Dropdown (upper left corner) select &lt;strong&gt;Create new Realm&lt;/strong&gt;&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/create-new-realm.png?width=420" alt="Create new Realm"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new Realm called &lt;strong&gt;openshift&lt;/strong&gt; (Enabled, of course) and press &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/create-new-realm-openshift.png?width=1024" alt="Create new Realm OpenShift"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now, inside the Realm &lt;strong&gt;openshift&lt;/strong&gt;, select &lt;strong&gt;Clients&lt;/strong&gt; and press the &lt;strong&gt;Create client&lt;/strong&gt; button.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/create-new-client.png?width=1024" alt="Create new Client"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new Client with the following configuration. Name it, for example, &lt;strong&gt;openshift&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Be sure the &lt;strong&gt;Client type&lt;/strong&gt; is set to &lt;strong&gt;OpenID Connect&lt;/strong&gt;&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/new-client-screen-1.png?width=1024" alt="Create new Client"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enable &lt;strong&gt;Client authentication&lt;/strong&gt;. The rest can be left as default.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/new-client-screen-2.png?width=1024" alt="Create new Client"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following redirect URL and Web origin and press &lt;strong&gt;Save&lt;/strong&gt;.:&lt;/p&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Redirect URL: &lt;a href="https://oauth-openshift.apps.&amp;lt;your-cluster-name&amp;gt;/oauth2callback/*" class="bare"&gt;https://oauth-openshift.apps.&amp;lt;your-cluster-name&amp;gt;/oauth2callback/*&lt;/a&gt; …​ redirecting everything under oauth2callback&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Web origin: &lt;a href="https://oauth-openshift.apps.&amp;lt;your-cluster-name&amp;gt;" class="bare"&gt;https://oauth-openshift.apps.&amp;lt;your-cluster-name&amp;gt;&lt;/a&gt;;&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/new-client-screen-3.png?width=1024" alt="Create new Client"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_create_a_new_user_and_a_group"&gt;Create a new User and a Group&lt;/h3&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;openshift&lt;/strong&gt; Realm, select &lt;strong&gt;Groups&lt;/strong&gt;, press the &lt;strong&gt;Create group&lt;/strong&gt; button and create a group called, for example, &lt;strong&gt;openshift-users&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;openshift&lt;/strong&gt; Realm, select &lt;strong&gt;Users&lt;/strong&gt; and press the &lt;strong&gt;Add user&lt;/strong&gt; button. Be sure to join the group &lt;strong&gt;openshift-users&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/new-user.png?width=1024" alt="Create new User"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;No more configuration is needed for the (test) user at this point.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set the password for the user. Select the user we have just created, select the &lt;strong&gt;Credentials&lt;/strong&gt; tab and press &lt;strong&gt;Set password&lt;/strong&gt;. Set the password to &lt;strong&gt;Temporary&lt;/strong&gt; to force the user to change the password on the first login.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/new-user-password.png?width=1024" alt="Set password for new User"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_configure_a_group_mapper"&gt;Configure a Group Mapper&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The above configuration is enough to log in to OpenShift using Keycloak as an IDP (except that we need to configure OpenShift itself). However, we also want to import the groups from Keycloak into OpenShift. This configuration was not easy to find, and is done by creating a Group Mapper in Keycloak.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;openshift&lt;/strong&gt; Realm, select &lt;strong&gt;Clients scopes&lt;/strong&gt; and select the &lt;strong&gt;profile&lt;/strong&gt; scope:&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/client-scopes.png?width=1024" alt="Client Scopes"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the &lt;strong&gt;Mappers&lt;/strong&gt; tab and Add a mapper &lt;strong&gt;By configuration&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/client-scopes-mappers.png?width=1024" alt="Client Scopes Mappers"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the &lt;strong&gt;Group Membership&lt;/strong&gt; mapper.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/client-scopes-new-mapper.png?width=1024" alt="Client Scopes Create Group Membership Mapper"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure the mapper with the following settings:&lt;/p&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Mapper Type: &lt;strong&gt;Group Membership&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Name: &lt;strong&gt;openshift-groups&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Token Claim Name: &lt;strong&gt;groups&lt;/strong&gt; → This is the name of the claim that will be used to map the groups from Keycloak to OpenShift.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Full group path: &lt;strong&gt;OFF&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add to ID token: &lt;strong&gt;ON&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add to access token: &lt;strong&gt;ON&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add to userinfo: &lt;strong&gt;ON&lt;/strong&gt;&lt;/p&gt;
&lt;div class="admonitionblock caution"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-caution" title="Caution"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Disable the &lt;strong&gt;Full groupo path&lt;/strong&gt; option, otherwise the group name will be prefixed with a &lt;strong&gt;/&lt;/strong&gt;. Moreover, be sure that you set the &lt;strong&gt;Token Claim Name&lt;/strong&gt; correctly to the claim we will configure in OpenShift (groups).
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/client-scopes-new-mapper-2.png?width=1024" alt="Client Scopes Create Group Membership Mapper"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_configure_openshift_to_use_keycloak_as_an_idp"&gt;Configure OpenShift to use Keycloak as an IDP&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now that Keycloak is configured, we need to configure OpenShift to use Keycloak as an IDP. This is done by creating a new Identity Provider in OpenShift.
Before we do this, we need to create a new OAuth client secret for OpenShift in the Namespace &lt;strong&gt;openshift-config&lt;/strong&gt; The secret will be used to authenticate OpenShift with Keycloak.
When we created the keycloak client, we enabled the &lt;strong&gt;Client authentication&lt;/strong&gt; option. This created a client secret we need to use in OpenShift.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;In Keycloak, select the &lt;strong&gt;openshift&lt;/strong&gt; client and select the &lt;strong&gt;Credentials&lt;/strong&gt; tab and copy the &lt;strong&gt;Client secret&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/keycloak-client-secret.png?width=1024" alt="Keycloak Client Secret"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Back in OpenShift, navigate to the &lt;strong&gt;openshift-config&lt;/strong&gt; namespace and select the &lt;strong&gt;Secrets&lt;/strong&gt; view. Create a new secret with the following configuration:&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;kind: Secret
apiVersion: v1
metadata:
name: openid-client-secret
namespace: openshift-config
stringData:
clientSecret: &amp;lt;you client secret from Keycloak&amp;gt; &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
type: Opaque&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The client secret we copied from Keycloak. This is the secret we will use to authenticate OpenShift with Keycloak.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now we need to create a new Identity Provider in OpenShift. In the OpenShift Web Console, navigate to the &lt;strong&gt;Administration&lt;/strong&gt; → &lt;strong&gt;Cluster Settings&lt;/strong&gt; → &lt;strong&gt;Configuration&lt;/strong&gt; search for &lt;strong&gt;OAuth&lt;/strong&gt; and select the YAML view.
Here the following must be created or added to an existing OAuth configuration:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-yaml hljs" data-lang="yaml"&gt;[...]
spec:
identityProviders:
- mappingMethod: claim
name: rhsso &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
openID:
claims: &lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
email:
- email
groups:
- groups
name:
- name
preferredUsername:
- preferred_username
clientID: openshift &lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
clientSecret:
name: openid-client-secret &lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;
extraScopes: []
issuer: &amp;#39;https://sso.apps.ocp.aws.ispworld.at/realms/openshift&amp;#39; &lt;i class="conum" data-value="5"&gt;&lt;/i&gt;&lt;b&gt;(5)&lt;/b&gt;
type: OpenID &lt;i class="conum" data-value="6"&gt;&lt;/i&gt;&lt;b&gt;(6)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The name of the Identity Provider. This is the name that will be displayed in the OpenShift login screen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The claims that will be used to map the user to OpenShift. In this example, we are using the email, groups, name and preferred_username claims from Keycloak.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The client ID we created in Keycloak. This is the client ID that will be used to authenticate OpenShift with Keycloak.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="4"&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The name of the secret we created in the &lt;strong&gt;openshift-config&lt;/strong&gt; namespace.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="5"&gt;&lt;/i&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The issuer URL for Keycloak. It is &amp;lt;hostname of keycloak&amp;gt;/realms/&amp;lt;realm name&amp;gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="6"&gt;&lt;/i&gt;&lt;b&gt;6&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The type of the Identity Provider. In this example, we are using OpenID Connect.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The above configuration will trigger a restart of the authentication Pods in OpenShift. Wait until all Pods have been restarted and the Operator is running again.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/restart-oauth.png" alt="OpenShift OAuth Restart"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_test_the_configuration"&gt;Test the configuration&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now it is time to test the configuration. Open a new browser window (or incognito window), navigate to the OpenShift login page and try to log in using Keycloak as an IDP &lt;strong&gt;rhsso&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
If you have multiple IDPs configured, it is important to select the correct IDP. &lt;strong&gt;rhsso&lt;/strong&gt; in this example.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;By selecting the &lt;strong&gt;rhsso&lt;/strong&gt; Identity Provider, you should be redirected to the Keycloak login page.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/openshift-keycloak-login.png?width=1024" alt="OpenShift Login Page"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
If you selected &lt;strong&gt;Temporary&lt;/strong&gt; for the password, you will now be asked to change the password on the first login.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After a successful login, you should see the OpenShift Web Console, and you should be logged in as the user you created in Keycloak.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/openshift-web-console.png?width=1024" alt="OpenShift Web Console"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In OpenShift you will see the user created. In the Identities column you will see that it starts with &lt;strong&gt;rhsso&lt;/strong&gt;, indicating that the user was authenticated using the &lt;strong&gt;rhsso&lt;/strong&gt; Identity Provider.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/openshift-user.png" alt="OpenShift User"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And finally, if you navigate to &lt;strong&gt;User Management&lt;/strong&gt; → &lt;strong&gt;Groups&lt;/strong&gt;, you should see the group &lt;strong&gt;openshift-users&lt;/strong&gt; that was created in Keycloak.&lt;/p&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/security/authentication/images/keycloak/openshift-groups.png" alt="OpenShift Group"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In this article, I have shown how to install and configure Keycloak in OpenShift for authentication. I have also shown how to configure Keycloak to be used as an Identity Provider for OpenShift and how to import groups from Keycloak into OpenShift.
The biggest two challenges were to find the correct callback URL and to configure the Group Mapper in Keycloak. The rest was pretty straightforward.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;What’s next? With the groups now mapped into OpenShift, you can now create RoleBindings and ClusterRoleBindings to assign the appropriate roles to the users in Keycloak. This is quite nice, as I do not need to create Users manually in OpenShift anymore (previously used HTPasswd) but instead use Keycloak as the single source of truth for users and groups. All I need to configure is the RoleBindings and ClusterRoleBindings in OpenShift.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;I hope this article was helpful and you learned something new. Remember, this is just a test configuration. In production you should use a proper database and keycloak setup (high Availability, backup, etc.).
If you have any questions or comments, please feel free to reach out to me on LinkedIn, Email or via GitHub issues.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_references"&gt;References&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/" target="_blank" rel="noopener"&gt;Keycloak Documentation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://blog.badgerops.net/keycloak-open-shift/" target="_blank" rel="noopener"&gt;Keycloak &amp;amp; Open Shift&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/tjungbauer/openshift-clusterconfig-gitops/tree/main/clusters/management-cluster/setup-rh-build-of-keycloak" target="_blank" rel="noopener"&gt;Set up Keycloak using GitOps (No Realm/Client configuration yet)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item></channel></rss>