diff --git a/Jenkinsfile b/Jenkinsfile
index 00a8373399d4d960f072d6bbff35d299c29e3020..8020f96671328714bfb5d6c57ceedf40accca013 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -206,7 +206,7 @@ Void testAndDeployElasticsearchHelmChart(String helmChartVersion){
 
 Void runHelmTests(){
     sh 'helm lint -f ../../test/helm/linter_values.yaml'
-    sh "helm unittest --helm3 -f '../../test/helm/*.yaml' -f '../../test/helm/*/*.yaml' ."
+    sh "helm unittest -f '../../test/helm/*/*.yaml' ."
     sh "helm package --version=${HELM_CHART_VERSION} ."
 }
 
diff --git a/ozgcloud-elasticsearch-operator/pom.xml b/ozgcloud-elasticsearch-operator/pom.xml
index 1814ae1d749e70488a71c85bb8a16eda4fc88c2f..23c8410368f60e39095575a515af48a6d2f325cf 100644
--- a/ozgcloud-elasticsearch-operator/pom.xml
+++ b/ozgcloud-elasticsearch-operator/pom.xml
@@ -1,12 +1,11 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 
 	<parent>
 		<groupId>de.ozgcloud</groupId>
 		<artifactId>ozgcloud-operator-parent</artifactId>
-		<version>2.1.0-SNAPSHOT</version>
+		<version>2.2.0-SNAPSHOT</version>
 		<relativePath>../</relativePath>
 	</parent>
 
@@ -76,4 +75,4 @@
 		</plugins>
 	</build>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/ozgcloud-elasticsearch-operator/run_helm_test.sh b/ozgcloud-elasticsearch-operator/run_helm_test.sh
index 8097a39a04ff100d5c9350e205d942100dd37894..e02dfa80a5c6d9a4e98cb6b5bff4e3b3e46df817 100755
--- a/ozgcloud-elasticsearch-operator/run_helm_test.sh
+++ b/ozgcloud-elasticsearch-operator/run_helm_test.sh
@@ -4,4 +4,4 @@ set -e
 
 helm template  ./src/main/helm/ -f src/test/helm/linter_values.yaml
 helm lint -f src/test/helm/linter_values.yaml ./src/main/helm/
-cd src/main/helm && helm unittest --helm3 -f '../../test/helm/*/*.yaml' -f '../../test/helm/*.yaml' .
+cd src/main/helm && helm unittest  -f '../../test/helm/*/*.yaml' .
diff --git a/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/ElasticsearchReconciler.java b/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/ElasticsearchReconciler.java
index 24899d8fd8ce95377de40d38e4d0c676b7e1226b..de9fa2f206e9b9f6d100297df12d17ec9ba58be4 100644
--- a/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/ElasticsearchReconciler.java
+++ b/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/ElasticsearchReconciler.java
@@ -50,7 +50,7 @@ public class ElasticsearchReconciler implements Reconciler<OzgCloudElasticsearch
 		try {
 			return new String(Base64.getDecoder().decode(encodedPassword));
 		} catch (Exception e) {
-			throw new RuntimeException("Could not decode password from secret.");
+			throw new RuntimeException("Could not decode password from secret.", e);
 		}
 	}
 
diff --git a/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/OzgCloudElasticsearchService.java b/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/OzgCloudElasticsearchService.java
index f823b17c2e75ecaa65274391cc45910f431828d6..3a915338a69f421ca3ab42fd6dcd088458c39f3d 100644
--- a/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/OzgCloudElasticsearchService.java
+++ b/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/OzgCloudElasticsearchService.java
@@ -58,7 +58,7 @@ public class OzgCloudElasticsearchService {
 	}
 
 	public void createSecurityRoleIfMissing(String roleName) throws Exception {
-		remoteService.createSecurityRole(buildPutRoleRequestData(roleName));
+		remoteService.createOrUpdateSecurityRole(buildPutRoleRequestData(roleName));
 	}
 
 	PutRoleRequestData buildPutRoleRequestData(String roleName) {
@@ -70,7 +70,7 @@ public class OzgCloudElasticsearchService {
 	}
 
 	public void createSecurityUserIfMissing(String namespace, String password) throws Exception {
-		remoteService.createSecurityUser(buildPutUserRequestData(namespace, password));
+		remoteService.createOrUpdateSecurityUser(buildPutUserRequestData(namespace, password));
 	}
 
 	PutUserRequestData buildPutUserRequestData(String namespace, String password) {
@@ -99,7 +99,7 @@ public class OzgCloudElasticsearchService {
 				createCredentialSecret(namespace, secretResource);
 			}
 		} catch (Exception e) {
-			throw new RuntimeException("Certificate secret creation failed " + namespace);
+			throw new RuntimeException("Certificate secret creation failed " + namespace, e);
 		}
 	}
 
diff --git a/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/common/elasticsearch/ElasticsearchRemoteService.java b/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/common/elasticsearch/ElasticsearchRemoteService.java
index ace393085d14c37b8ca6691078da1b7d8e12ac77..e401f95bcdbb683d3ebaf193d5280bb923d105d9 100644
--- a/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/common/elasticsearch/ElasticsearchRemoteService.java
+++ b/ozgcloud-elasticsearch-operator/src/main/java/de/ozgcloud/operator/common/elasticsearch/ElasticsearchRemoteService.java
@@ -28,7 +28,11 @@ public class ElasticsearchRemoteService {
 		}
 	}
 
-	public void createSecurityRole(PutRoleRequestData requestData) throws Exception {
+	public boolean existsSecurityRole(String roleName) throws Exception {
+		return !client.security().getRole(builder -> builder.name(roleName)).result().isEmpty();
+	}
+
+	public void createOrUpdateSecurityRole(PutRoleRequestData requestData) throws Exception {
 		try {
 			LOG.info("{}: Create or update elasticsearch role ", requestData.getName());
 			client.security().putRole(createPutRoleRequest(requestData));
@@ -56,7 +60,11 @@ public class ElasticsearchRemoteService {
 		return builder;
 	}
 
-	public void createSecurityUser(PutUserRequestData requestData) throws Exception {
+	public boolean existsSecurityUser(String userName) throws Exception {
+		return !client.security().getUser(builder -> builder.username(userName)).result().isEmpty();
+	}
+
+	public void createOrUpdateSecurityUser(PutUserRequestData requestData) throws Exception {
 		try {
 			LOG.info("{}: Create or update elasticsearch user", requestData.getUsername());
 			client.security().putUser(createPutUserRequest(requestData));
diff --git a/ozgcloud-elasticsearch-operator/src/test/helm/rbac/ozgcloud_elasticsearch_operator_edit_role_test.yaml b/ozgcloud-elasticsearch-operator/src/test/helm/rbac/ozgcloud_elasticsearch_operator_edit_role_test.yaml
index 078cf0a0cf2fd7498271d63ca3fb6e686b85e71a..6bc79960ebe16d221cbc2fd8ba9d842e47c280cd 100644
--- a/ozgcloud-elasticsearch-operator/src/test/helm/rbac/ozgcloud_elasticsearch_operator_edit_role_test.yaml
+++ b/ozgcloud-elasticsearch-operator/src/test/helm/rbac/ozgcloud_elasticsearch_operator_edit_role_test.yaml
@@ -22,17 +22,17 @@ tests:
   - it: should have metadata labels name
     asserts: 
       - equal:
-          path: metadata.labels.[app.kubernetes.io/name]
+          path: metadata.labels["app.kubernetes.io/name"]
           value: release-name
   - it: should have metadata labels instance
     asserts: 
       - equal:
-          path: metadata.labels.[app.kubernetes.io/instance]
+          path: metadata.labels["app.kubernetes.io/instance"]
           value: release-name
   - it: should have metadata labels component
     asserts: 
       - equal:
-          path: metadata.labels.[app.kubernetes.io/component]
+          path: metadata.labels["app.kubernetes.io/component"]
           value: ozgcloud-elasticsearch-operator
 
   - it: should have rules for ozgcloudelasticsearchs resource
diff --git a/ozgcloud-elasticsearch-operator/src/test/helm/rbac/ozgcloud_elasticsearch_operator_view_role_test.yaml b/ozgcloud-elasticsearch-operator/src/test/helm/rbac/ozgcloud_elasticsearch_operator_view_role_test.yaml
index 5112d901aaeeaa0ca71735fcc76417364cbaafac..536103410fc720d9ed8c7fa6800c8d922d5d0952 100644
--- a/ozgcloud-elasticsearch-operator/src/test/helm/rbac/ozgcloud_elasticsearch_operator_view_role_test.yaml
+++ b/ozgcloud-elasticsearch-operator/src/test/helm/rbac/ozgcloud_elasticsearch_operator_view_role_test.yaml
@@ -22,17 +22,17 @@ tests:
   - it: should have metadata labels name
     asserts: 
       - equal:
-          path: metadata.labels.[app.kubernetes.io/name]
+          path: metadata.labels["app.kubernetes.io/name"]
           value: release-name
   - it: should have metadata labels instance
     asserts: 
       - equal:
-          path: metadata.labels.[app.kubernetes.io/instance]
+          path: metadata.labels["app.kubernetes.io/instance"]
           value: release-name
   - it: should have metadata labels component
     asserts: 
       - equal:
-          path: metadata.labels.[app.kubernetes.io/component]
+          path: metadata.labels["app.kubernetes.io/component"]
           value: ozgcloud-elasticsearch-operator
 
   - it: should have rules for ozgcloudelasticsearchs resource
diff --git a/ozgcloud-elasticsearch-operator/src/test/java/de/ozgcloud/operator/OzgCloudElasticsearchServiceTest.java b/ozgcloud-elasticsearch-operator/src/test/java/de/ozgcloud/operator/OzgCloudElasticsearchServiceTest.java
index f591a335d88d3a85b338592c9cd8064670c8d6a4..5175eed82d7655fd315ad22d58879aa73812dc26 100644
--- a/ozgcloud-elasticsearch-operator/src/test/java/de/ozgcloud/operator/OzgCloudElasticsearchServiceTest.java
+++ b/ozgcloud-elasticsearch-operator/src/test/java/de/ozgcloud/operator/OzgCloudElasticsearchServiceTest.java
@@ -136,7 +136,7 @@ class OzgCloudElasticsearchServiceTest {
 
 			service.createSecurityRoleIfMissing(NAMESPACE);
 
-			verify(remoteService).createSecurityRole(putRoleRequest);
+			verify(remoteService).createOrUpdateSecurityRole(putRoleRequest);
 		}
 
 		@DisplayName("create put role request data")
@@ -188,7 +188,7 @@ class OzgCloudElasticsearchServiceTest {
 
 			service.createSecurityUserIfMissing(NAMESPACE, PutUserRequestDataTestFactory.PASSWORD);
 
-			verify(remoteService).createSecurityUser(putUserRequestData);
+			verify(remoteService).createOrUpdateSecurityUser(putUserRequestData);
 		}
 
 		@DisplayName("create put user request data")
diff --git a/ozgcloud-elasticsearch-operator/src/test/java/de/ozgcloud/operator/common/elasticsearch/ElasticsearchRemoteServiceITCase.java b/ozgcloud-elasticsearch-operator/src/test/java/de/ozgcloud/operator/common/elasticsearch/ElasticsearchRemoteServiceITCase.java
index 329e3fcb59e055bc7e568d3f69c4f3bb58a3658e..2c850dad36cc8563fbe4024004f32cb76fc07a9a 100644
--- a/ozgcloud-elasticsearch-operator/src/test/java/de/ozgcloud/operator/common/elasticsearch/ElasticsearchRemoteServiceITCase.java
+++ b/ozgcloud-elasticsearch-operator/src/test/java/de/ozgcloud/operator/common/elasticsearch/ElasticsearchRemoteServiceITCase.java
@@ -110,8 +110,8 @@ class ElasticsearchRemoteServiceITCase {
 		@SneakyThrows
 		@Test
 		void shouldCreateSecurityRole() {
-			service.createSecurityRole(PutRoleRequestDataTestFactory.create());
-
+			service.createOrUpdateSecurityRole(PutRoleRequestDataTestFactory.create());
+			
 			assertThat(existsSecurityRole()).isTrue();
 		}
 
@@ -166,8 +166,8 @@ class ElasticsearchRemoteServiceITCase {
 		@SneakyThrows
 		@Test
 		void shouldCreateSecurityUser() {
-			service.createSecurityUser(PutUserRequestDataTestFactory.create());
-
+			service.createOrUpdateSecurityUser(PutUserRequestDataTestFactory.create());
+			
 			assertThat(existsSecurityUser()).isTrue();
 		}
 
diff --git a/ozgcloud-keycloak-operator/pom.xml b/ozgcloud-keycloak-operator/pom.xml
index cb36f4172e4fe6b8e5838866e9c5c36b6b8f9e13..6c4a4eeb28c84fbef3f2285a2cf16e577fe2f105 100644
--- a/ozgcloud-keycloak-operator/pom.xml
+++ b/ozgcloud-keycloak-operator/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>de.ozgcloud</groupId>
 		<artifactId>ozgcloud-operator-parent</artifactId>
-		<version>2.1.0-SNAPSHOT</version>
+		<version>2.2.0-SNAPSHOT</version>
 		<relativePath>../</relativePath>
 	</parent>
 
diff --git a/ozgcloud-keycloak-operator/run_helm_test.sh b/ozgcloud-keycloak-operator/run_helm_test.sh
index 8097a39a04ff100d5c9350e205d942100dd37894..44b6c307143f31f5a3fcfe4e41f30063089c59e5 100755
--- a/ozgcloud-keycloak-operator/run_helm_test.sh
+++ b/ozgcloud-keycloak-operator/run_helm_test.sh
@@ -4,4 +4,4 @@ set -e
 
 helm template  ./src/main/helm/ -f src/test/helm/linter_values.yaml
 helm lint -f src/test/helm/linter_values.yaml ./src/main/helm/
-cd src/main/helm && helm unittest --helm3 -f '../../test/helm/*/*.yaml' -f '../../test/helm/*.yaml' .
+cd src/main/helm && helm unittest -f '../../test/helm/*/*.yaml'  .
diff --git a/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/KeycloakResultParser.java b/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/KeycloakResultParser.java
index 28e044c19a17e877843f687c1bdcfd2a6e212f71..0d92fac40b9276fe19cf3bf81506bddc865d129d 100644
--- a/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/KeycloakResultParser.java
+++ b/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/KeycloakResultParser.java
@@ -27,7 +27,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 
-import javax.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
diff --git a/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java b/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java
index b38218f6504b5dc1c0d26f17109151f56695f0c5..2d8faf3a74bc794c4fd229a53a5f7424d7d752bd 100644
--- a/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java
+++ b/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java
@@ -24,7 +24,10 @@
 package de.ozgcloud.operator.keycloak.user;
 
 import java.util.Arrays;
+import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Stream;
 
 import org.keycloak.admin.client.CreatedResponseUtil;
 import org.keycloak.admin.client.Keycloak;
@@ -79,16 +82,25 @@ class KeycloakUserRemoteService {
 	}
 
 	void addClientRoles(String userId, RealmResource realmResource, String namespace, UserRepresentation user) {
-		user.getClientRoles().keySet().forEach(clientId -> {
+		getClientNamesOfUser(user).forEach(clientId -> {
+
 			var realmClient = getRealmClient(realmResource, clientId);
 			user.getClientRoles().get(clientId).stream()
-					.map(clientRoleName -> keycloakGenericRemoteService.getClientRole(clientRoleName, realmClient.getId(), namespace)
-							.orElseThrow(() -> new KeycloakException(
-									"Role " + clientRoleName + " not found for client with clientId " + clientId + " in realm " + namespace)))
+					.map(clientRoleName -> getClientRole(namespace, clientId, realmClient, clientRoleName))
 					.forEach(clientRole -> addClientRoleToUser(clientRole, realmResource, userId, realmClient));
 		});
 	}
 
+	Stream<String> getClientNamesOfUser(UserRepresentation user) {
+		return Optional.ofNullable(user.getClientRoles()).map(Map::keySet).map(Set::stream).orElse(Stream.empty());
+	}
+
+	RoleRepresentation getClientRole(String namespace, String clientId, ClientRepresentation realmClient, String clientRoleName) {
+		return keycloakGenericRemoteService.getClientRole(clientRoleName, realmClient.getId(), namespace)
+				.orElseThrow(() -> new KeycloakException(
+						"Role " + clientRoleName + " not found for client with clientId " + clientId + " in realm " + namespace));
+	}
+
 	ClientRepresentation getRealmClient(RealmResource realmResource, String clientId) {
 		return realmResource.clients()
 				.findByClientId(clientId).stream().findFirst()
diff --git a/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/client/KeycloakClientRemoteServiceTest.java b/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/client/KeycloakClientRemoteServiceTest.java
index 56b8a2c18128483b414bcafa8f87d9cb0e501447..2a2337e196e5316e74f6d856a06bf8f243d3fd0e 100644
--- a/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/client/KeycloakClientRemoteServiceTest.java
+++ b/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/client/KeycloakClientRemoteServiceTest.java
@@ -26,7 +26,7 @@ package de.ozgcloud.operator.keycloak.client;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
-import javax.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
diff --git a/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/group/KeycloakGroupRemoteServiceTest.java b/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/group/KeycloakGroupRemoteServiceTest.java
index 1303467ed34a87703ea569e4f7547c3590930b55..1bb10c9e0b8169c4409ed987c19f2f4dbb204b14 100644
--- a/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/group/KeycloakGroupRemoteServiceTest.java
+++ b/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/group/KeycloakGroupRemoteServiceTest.java
@@ -30,7 +30,7 @@ import static org.mockito.Mockito.*;
 import java.util.Collections;
 import java.util.List;
 
-import javax.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
diff --git a/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java b/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java
index 70fd40079ca06c1e92fb78719b2a93322be950a5..67693d1cd2b589a37f2872e316f404ae17806c5a 100644
--- a/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java
+++ b/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java
@@ -32,7 +32,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
-import javax.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -61,6 +61,7 @@ class KeycloakUserRemoteServiceTest {
 	private final static String REALM = "TestRealm";
 	private final static String USERID = "UserId";
 	private final static String CLIENT_ID = "ClientId";
+	private final static String CLIENT_ROLE_NAME = "ClientRoleName";
 
 	@Spy
 	@InjectMocks
@@ -173,7 +174,6 @@ class KeycloakUserRemoteServiceTest {
 		@Test
 		void shouldThrowOnMissingClientRole() {
 			var user = UserRepresentationTestFactory.create();
-			userRemoteService.addClientRoles(USERID, realmResource, REALM, userRepresentation);
 			when(genericRemoteService.getClientRole(any(), any(), any())).thenReturn(Optional.empty());
 
 			assertThrows(KeycloakException.class,
@@ -181,6 +181,69 @@ class KeycloakUserRemoteServiceTest {
 		}
 	}
 
+	@Nested
+	class TestAddClientRolesUserWithoutRoles {
+
+		@Test
+		void shouldNotThrowOnUserWithoutRoles() {
+			UserRepresentation user = createUserWithNullRoles();
+
+			assertDoesNotThrow(() -> userRemoteService.addClientRoles(USERID, realmResource, REALM, user));
+		}
+
+		private UserRepresentation createUserWithNullRoles() {
+			UserRepresentation user = UserRepresentationTestFactory.create();
+			user.setClientRoles(null);
+			return user;
+		}
+	}
+
+	@Nested
+	class TestGetRealmClientNamesOfUser {
+
+		@Test
+		void shouldReturnClientNames() {
+			UserRepresentation user = UserRepresentationTestFactory.create();
+
+			List<String> clientNames = userRemoteService.getClientNamesOfUser(user).toList();
+
+			assertThat(clientNames).contains(UserRepresentationTestFactory.CLIENT_NAME);
+		}
+	}
+
+	@Nested
+	class TestGetClientRole {
+
+		@Spy
+		@InjectMocks
+		private KeycloakUserRemoteService userRemoteService;
+
+		@Mock
+		private KeycloakGenericRemoteService keycloakGenericRemoteService;
+
+		@BeforeEach
+		void init() {
+			when(clientRepresentation.getId()).thenReturn(CLIENT_ID);
+		}
+
+		@Test
+		void shouldReturnClientRole() {
+			when(keycloakGenericRemoteService.getClientRole(CLIENT_ROLE_NAME, CLIENT_ID, REALM)).thenReturn(Optional.of(roleRepresentation));
+
+			RoleRepresentation role = userRemoteService.getClientRole(REALM, CLIENT_ID, clientRepresentation, CLIENT_ROLE_NAME);
+
+			assertThat(role).isEqualTo(roleRepresentation);
+		}
+
+		@Test
+		void shouldThrowOnMissingRole() {
+			when(keycloakGenericRemoteService.getClientRole(CLIENT_ROLE_NAME, CLIENT_ID, REALM)).thenReturn(Optional.empty());
+
+			assertThrows(KeycloakException.class,
+					() -> userRemoteService.getClientRole(REALM, CLIENT_ID, clientRepresentation, CLIENT_ROLE_NAME));
+		}
+	}
+
 	@Nested
 	class TestAddClientRoleToUser {
 
diff --git a/pom.xml b/pom.xml
index fbd13b21d2fbfebd615c1c634643b77410110777..2530e98130809565f17672891a813ccd9be53e49 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,18 +1,17 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 
 	<parent>
 		<groupId>org.springframework.boot</groupId>
 		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>3.1.3</version>
-		<relativePath />
+		<version>3.1.7</version>
+		<relativePath/>
 	</parent>
 
 	<groupId>de.ozgcloud</groupId>
 	<artifactId>ozgcloud-operator-parent</artifactId>
-	<version>2.1.0-SNAPSHOT</version>
+	<version>2.2.0-SNAPSHOT</version>
 	<packaging>pom</packaging>
 
 	<name>OzgCloud Operator Parent</name>
@@ -24,14 +23,14 @@
 	</modules>
 
 	<properties>
-		<spring-boot.version>3.1.3</spring-boot.version>
+		<spring-boot.version>3.1.7</spring-boot.version>
 		<operator-sdk.version>5.4.1</operator-sdk.version>
 
 		<!-- tools -->
 		<commons-beanutils.version>1.9.4</commons-beanutils.version>
 		<lombok.version>1.18.28</lombok.version>
 		<mapstruct.version>1.5.5.Final</mapstruct.version>
-		<keycloak-adapter.version>20.0.5</keycloak-adapter.version>
+		<keycloak-adapter.version>23.0.5</keycloak-adapter.version>
 		<reflections.version>0.10.2</reflections.version>
 		<validation-api.version>2.0.1.Final</validation-api.version>
 		<lorem.version>2.2</lorem.version>
@@ -247,4 +246,4 @@
 		</snapshotRepository>
 	</distributionManagement>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/release-startdev.sh b/release-startdev.sh
index 4fc6aa98500e450dfdd07d026a46772accdb514e..8b647ae9e5470481711267cf94de8de119149873 100755
--- a/release-startdev.sh
+++ b/release-startdev.sh
@@ -16,6 +16,8 @@ echo
 # projectname/pom.xml:parent,main -> project.parent.version und project.version setzen
 #
 PROJECTS="pom.xml:main 
+        ozgcloud-keycloak-operator/pom.xml:parent
+        ozgcloud-elasticsearch-operator/pom.xml:parent
         "
 
 for PROJECT in $PROJECTS;