Step by Step - Using Keycloak Authentication in OpenShift
- - 11 min read
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.
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.).
Prerequisites
The following prerequisites are required to follow this article:
OpenShift 4.16 or higher with cluster-admin privileges
Installing Keycloak Operator
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.
Installing the Keycloak Operator via GitOps can be seen in this GitHub repository. By the time you read this article, this repository will install and configure a Keycloak instance automatically using a local EXAMPLE 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. |
Log in to the OpenShift Web Console as a user with cluster-admin privileges.
In the OpenShift Web Console, navigate to the Operators → OperatorHub.
In the OperatorHub, search for Red Hat build of Keycloak and select the Operator from the list.
Install the latest version of the Keycloak Operator.
You can keep the default settings for the installation, but I recommend using a specific namespace. In this example, I will use the namespace keycloak
for the installation.Press the Install 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 Installed Operators view.
Create a local example Postgres Database
Demo only! This is not production ready and should not be used in production. |
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.
First, let’s create a Secret for the database credentials. In OpenShift select the keycloak namespace and navigate to the Secrets view. Create a new Secret with the following test configuration:
kind: Secret apiVersion: v1 metadata: name: keycloak-db-secret namespace: keycloak stringData: password: thisisonly4testingNOT4prod (1) username: testuser type: Opaque
1 The password for the database. This is just a test password and should not be used in production. Next, we need to create a StatefulSet for the Postgres database, again in the keycloak namespace. Again, as I cannot mention that enough, this is just a test configuration and should not be used in production.
apiVersion: apps/v1 kind: StatefulSet metadata: name: postgresql-db namespace: keycloak spec: serviceName: postgresql-db-service selector: matchLabels: app: postgresql-db replicas: 1 (1) template: metadata: labels: app: postgresql-db spec: containers: - name: postgresql-db image: postgres:15 (2) volumeMounts: - mountPath: /data name: psql env: (3) - name: POSTGRES_USER value: testuser - name: POSTGRES_PASSWORD value: thisisonly4testingNOT4prod - name: PGDATA value: /data/pgdata - name: POSTGRES_DB value: keycloak volumeClaimTemplates: (4) - metadata: name: psql spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "gp3-csi" resources: requests: storage: 10Gi
1 The number of replicas for the database. In this example, we are using a single replica. 2 The image for the database, postgres version 15 in this example. 3 The environment variables for the database. The username and password are the same as in the Secret we created before, and clear text 4 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 gp3-csi
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.Finally, we need to create a Service for the database so that the Keycloak Operator can access the database. Again, in the keycloak namespace.
apiVersion: v1 kind: Service metadata: name: postgres-db namespace: keycloak spec: selector: app: postgresql-db (1) type: LoadBalancer ports: - port: 5432 targetPort: 5432
1 The selector for the Service. This must match the label of the StatefulSet we created before.
Creating a Keycloak Instance
Now that the Keycloak Operator is installed and our example database is running, we can create a Keycloak instance.
In the OpenShift Web Console, navigate to the Installed Operators view and select the Keycloak Operator. (Maybe you need to select the keycloak namespace first.)
In the Keycloak Operator view, create a new instance of Keycloak and switch to the YAML view.
The fun part here is that the YAML example the Operator provides is actually wrong and does not work. Something that kept me busy for a while. Replace the YAML with the following configuration:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: keycloak (1) namespace: keycloak labels: app: sso spec: db: (2) host: postgres-db passwordSecret: key: password name: keycloak-db-secret usernameSecret: key: username name: keycloak-db-secret vendor: postgres hostname: (3) hostname: sso.apps.ocp.aws.ispworld.at http: (4) tlsSecret: keycloak-certificate instances: 1 (5)
1 The name and the namespace of the Keycloak instance. 2 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. 3 Hostname of our Keycloak instance. 4 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 tlsSecret under spec, but it should be under http. 5 The number of instances of Keycloak. In this example, we are using a single instance.
What about the SSL Certificate?
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 keycloak-certificate
in the keycloak
namespace. This secret was created using the Cert Manager Operator. For example, you can use the following configuration to create a certificate for the Keycloak instance.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: keycloak-certificate
namespace: keycloak
spec:
dnsNames:
- sso.apps.ocp.aws.ispworld.at (1)
duration: 2160h0m0s
issuerRef:
kind: ClusterIssuer
name: letsencrypt-prod (2)
privateKey:
algorithm: RSA
encoding: PKCS1
rotationPolicy: Always
secretName: keycloak-certificate (3)
1 | The DNS name the Certificate is valid for. This should be the same as the hostname in the Keycloak instance. |
2 | The issuer for the certificate. In this example, we are using the LetsEncrypt ClusterIssuer. |
3 | The name of the secret where the certificate is stored. This should be the same as the TLS secret in the Keycloak instance. |
I strongly recommend using the Cert Manager Operator 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:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=test.keycloak.org/O=Test Keycloak./C=US"
oc create secret -n keycloak tls keycloak-certificate2 --cert=tls.crt --key=tls.key
Login in to Keycloak
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: https://sso.apps.ocp.aws.ispworld.at This is the hostname we configured in the keycloak instance.
To authenticate, you need to fetch the initial password for the admin user. This password is stored in a secret called keycloak-initial-admin
You can use the following command to fetch the password:
oc extract secret/keycloak-initial-admin -n keycloak --to=-
or you can use the OpenShift Web Console to view the secret.
Once authenticated, you should see the Keycloak Admin Console:

The first thing you should do is to change the password for the admin user. I trust you know how to do this :) |
Configure Keycloak to be used by OpenShift
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.
The full documentation for Keycloak can be found at Keycloak Documentation.
Create a new Realm and Client
In the Realm Dropdown (upper left corner) select Create new Realm
Create a new Realm called openshift (Enabled, of course) and press Create.
Now, inside the Realm openshift, select Clients and press the Create client button.
Create a new Client with the following configuration. Name it, for example, openshift.
Be sure the Client type is set to OpenID Connect
Enable Client authentication. The rest can be left as default.
Add the following redirect URL and Web origin and press Save.:
Redirect URL: https://oauth-openshift.apps.<your-cluster-name>/oauth2callback/* … redirecting everything under oauth2callback
Web origin: https://oauth-openshift.apps.<your-cluster-name>;
Create a new User and a Group
In the openshift Realm, select Groups, press the Create group button and create a group called, for example, openshift-users.
In the openshift Realm, select Users and press the Add user button. Be sure to join the group openshift-users.
No more configuration is needed for the (test) user at this point.
Set the password for the user. Select the user we have just created, select the Credentials tab and press Set password. Set the password to Temporary to force the user to change the password on the first login.
Configure a Group Mapper
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.
In the openshift Realm, select Clients scopes and select the profile scope:
Select the Mappers tab and Add a mapper By configuration:
Select the Group Membership mapper.
Configure the mapper with the following settings:
Mapper Type: Group Membership
Name: openshift-groups
Token Claim Name: groups → This is the name of the claim that will be used to map the groups from Keycloak to OpenShift.
Full group path: OFF
Add to ID token: ON
Add to access token: ON
Add to userinfo: ON
Disable the Full groupo path option, otherwise the group name will be prefixed with a /. Moreover, be sure that you set the Token Claim Name correctly to the claim we will configure in OpenShift (groups).
Configure OpenShift to use Keycloak as an IDP
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 openshift-config The secret will be used to authenticate OpenShift with Keycloak. When we created the keycloak client, we enabled the Client authentication option. This created a client secret we need to use in OpenShift.
In Keycloak, select the openshift client and select the Credentials tab and copy the Client secret.
Back in OpenShift, navigate to the openshift-config namespace and select the Secrets view. Create a new secret with the following configuration:
kind: Secret apiVersion: v1 metadata: name: openid-client-secret namespace: openshift-config stringData: clientSecret: <you client secret from Keycloak> (1) type: Opaque
1 The client secret we copied from Keycloak. This is the secret we will use to authenticate OpenShift with Keycloak. Now we need to create a new Identity Provider in OpenShift. In the OpenShift Web Console, navigate to the Administration → Cluster Settings → Configuration search for OAuth and select the YAML view. Here the following must be created or added to an existing OAuth configuration:
[...]
spec:
identityProviders:
- mappingMethod: claim
name: rhsso (1)
openID:
claims: (2)
email:
- email
groups:
- groups
name:
- name
preferredUsername:
- preferred_username
clientID: openshift (3)
clientSecret:
name: openid-client-secret (4)
extraScopes: []
issuer: 'https://sso.apps.ocp.aws.ispworld.at/realms/openshift' (5)
type: OpenID (6)
1 | The name of the Identity Provider. This is the name that will be displayed in the OpenShift login screen. |
2 | 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. |
3 | The client ID we created in Keycloak. This is the client ID that will be used to authenticate OpenShift with Keycloak. |
4 | The name of the secret we created in the openshift-config namespace. |
5 | The issuer URL for Keycloak. It is <hostname of keycloak>/realms/<realm name>. |
6 | The type of the Identity Provider. In this example, we are using OpenID Connect. |
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.

Test the configuration
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 rhsso.
If you have multiple IDPs configured, it is important to select the correct IDP. rhsso in this example. |
By selecting the rhsso Identity Provider, you should be redirected to the Keycloak login page.
If you selected Temporary for the password, you will now be asked to change the password on the first login. After a successful login, you should see the OpenShift Web Console, and you should be logged in as the user you created in Keycloak.
In OpenShift you will see the user created. In the Identities column you will see that it starts with rhsso, indicating that the user was authenticated using the rhsso Identity Provider.
And finally, if you navigate to User Management → Groups, you should see the group openshift-users that was created in Keycloak.
Conclusion
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.
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.
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.
References
Copyright © 2020 - 2025 Toni Schmidbauer & Thomas Jungbauer