diff --git a/pom.xml b/pom.xml
index 53c904ec7218ac35a46a93b8500a34490a3f60ee..8f9a65e0d4fcfcacc3df215290cc81d683f37223 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
 	<parent>
 		<groupId>org.springframework.boot</groupId>
 		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>3.1.1</version>
+		<version>3.1.3</version>
 		<relativePath/>
 	</parent>
 
@@ -17,12 +17,16 @@
 	<description>OZG Cloud Operator</description>
 	
 	<properties>
-		<operator-sdk.version>5.0.0</operator-sdk.version>
 		<spring-boot.build-image.imageName>docker.ozg-sh.de/ozg-operator:build-latest</spring-boot.build-image.imageName>
+		
+		<operator-sdk.version>5.2.0</operator-sdk.version>
 		<mapstruct.version>1.5.5.Final</mapstruct.version>
 		<keycloak-adapter.version>20.0.5</keycloak-adapter.version>
+		<commons-beanutils.version>1.9.4</commons-beanutils.version>
+		<reflections.version>0.10.2</reflections.version>
+		<validation-api.version>2.0.1.Final</validation-api.version>
 	</properties>
-	
+		
 	<dependencies>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
@@ -46,7 +50,7 @@
 		<dependency>
 	    	<groupId>javax.validation</groupId>
 	    	<artifactId>validation-api</artifactId>
-	    	<version>2.0.1.Final</version>
+	    	<version>${validation-api.version}</version>
 		</dependency>
 		<dependency>
 		    <groupId>jakarta.xml.bind</groupId>
@@ -59,7 +63,12 @@
 		<dependency>
 		    <groupId>org.reflections</groupId>
 		    <artifactId>reflections</artifactId>
-		    <version>0.10.2</version>
+		    <version>${reflections.version}</version>
+		</dependency>		
+		<dependency>
+			<groupId>commons-beanutils</groupId>
+			<artifactId>commons-beanutils</artifactId>
+			<version>${commons-beanutils.version}</version>
 		</dependency>
 		
 		<dependency>
diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java
index fd1d383a7416816a832553b23b4bf82c4229c72b..4e1d2f02fbfb611f550e9682ef5b0dedd7224d66 100644
--- a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java
+++ b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java
@@ -24,13 +24,8 @@
 package de.ozgcloud.operator.keycloak.user;
 
 import java.util.Arrays;
-import java.util.Base64;
-import java.util.Objects;
 import java.util.Optional;
-import java.util.logging.Level;
 
-import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.keycloak.admin.client.CreatedResponseUtil;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.admin.client.resource.RealmResource;
@@ -43,28 +38,13 @@ import org.springframework.stereotype.Component;
 import de.ozgcloud.operator.keycloak.KeycloakException;
 import de.ozgcloud.operator.keycloak.KeycloakGenericRemoteService;
 import de.ozgcloud.operator.keycloak.KeycloakResultParser;
-import de.ozgcloud.operator.keycloak.user.OzgKeycloakUserSpec.KeycloakUserSpecUser;
-import io.fabric8.kubernetes.api.model.ObjectMeta;
-import io.fabric8.kubernetes.api.model.Secret;
-import io.fabric8.kubernetes.api.model.SecretBuilder;
-import io.fabric8.kubernetes.client.dsl.Resource;
-import io.fabric8.kubernetes.client.extension.ResourceAdapter;
-import lombok.extern.java.Log;
-
-@Log
+
 @Component
 class KeycloakUserRemoteService {
 
-	private static final String SECRET_TYPE = "Opaque";
-	static final String SECRET_PASSWORD_FIELD = "password";
-	static final String SECRET_NAME_FIELD = "name";
-
-	private static final String USER_NAME_VALIDITY_REGEX = "[^a-zA-Z0-9]";
-
 	@Autowired
 	private Keycloak keycloak;
-	@Autowired
-	private KubernetesRemoteService kubernetesRemoteService;
+
 	@Autowired
 	private KeycloakGenericRemoteService keycloakGenericRemoteService;
 
@@ -119,73 +99,4 @@ class KeycloakUserRemoteService {
 	void addClientRoleToUser(RoleRepresentation clientRole, RealmResource realmResource, String userId, ClientRepresentation appClient) {
 		realmResource.users().get(userId).roles().clientLevel(appClient.getId()).add(Arrays.asList(clientRole));
 	}
-
-	public boolean existSecret(OzgKeycloakUserSpec userSpec, String namespace) {
-		return Objects.nonNull(getUserSecret(userSpec, namespace).get());
-	}
-
-	public void createSecret(OzgKeycloakUserSpec userSpec, String namespace) {
-		log.log(Level.INFO, "Create secret for user: " + userSpec.getKeycloakUser().getUsername());
-		var credentialsSecret = createUserSecret(userSpec.getKeycloakUser(), namespace);
-
-		var adapter = createResourceAdpater(getUserSecret(userSpec, namespace));
-		adapter.create(credentialsSecret);
-	}
-
-	ResourceAdapter<Secret> createResourceAdpater(Resource<Secret> secretResource) {
-		return new ResourceAdapter<>(secretResource);
-	}
-
-	Secret createUserSecret(KeycloakUserSpecUser userSpec, String namespace) {
-		return new SecretBuilder()
-				.withType(SECRET_TYPE)
-				.withMetadata(createMetaData(userSpec, namespace))
-				.addToStringData(SECRET_NAME_FIELD, userSpec.getUsername())
-				.addToStringData(SECRET_PASSWORD_FIELD, getPassword(userSpec.getPassword()))
-				.build();
-	}
-
-	private ObjectMeta createMetaData(KeycloakUserSpecUser userSpec, String namespace) {
-		var name = buildCredentialSecretName(userSpec);
-		var metadata = new ObjectMeta();
-		metadata.setName(name);
-		metadata.setNamespace(namespace);
-		return metadata;
-	}
-
-	String getPassword(String userPassword) {
-		return StringUtils.isEmpty(userPassword) ? generateRandomPasswordForKeycloak() : userPassword;
-	}
-
-	String generateRandomPasswordForKeycloak() {
-		log.log(Level.INFO, "Generate password...");
-		var upperCaseCharacter = RandomStringUtils.randomAlphabetic(1).toUpperCase();
-		var randomString = RandomStringUtils.randomAlphanumeric(7);
-		return upperCaseCharacter + randomString;
-	}
-
-	public String getPasswordFromSecret(OzgKeycloakUserSpec userSpec, String namespace) {
-		return getPasswordFromSecret(getUserSecret(userSpec, namespace));
-	}
-
-	public Resource<Secret> getUserSecret(OzgKeycloakUserSpec userSpec, String namespace) {
-		var secretName = buildCredentialSecretName(userSpec.getKeycloakUser());
-		return kubernetesRemoteService.getSecret(namespace, secretName);
-	}
-
-	private String buildCredentialSecretName(KeycloakUserSpecUser userSpec) {
-		return clarifyName(userSpec.getUsername().toLowerCase()) + "-credentials";
-	}
-
-	String clarifyName(String userName) {
-		return userName.replaceAll(USER_NAME_VALIDITY_REGEX, StringUtils.EMPTY);
-	}
-
-	private String getPasswordFromSecret(Resource<Secret> secret) {
-		return decodeBase64(secret.get().getData().get(SECRET_PASSWORD_FIELD));
-	}
-
-	private String decodeBase64(String base64String) {
-		return new String(Base64.getDecoder().decode(base64String));
-	}
 }
\ No newline at end of file
diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserService.java b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserService.java
index dc9223feebb4f52028f6538c3331746f5f416ee6..cbd0038e67fb69cedc2d9269677aab26b870dd05 100644
--- a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserService.java
+++ b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserService.java
@@ -38,20 +38,20 @@ class KeycloakUserService {
 	@Autowired
 	private KeycloakUserRemoteService remoteService;
 
+	@Autowired
+	private UserSecretService userSecretService;
+
 	@Autowired
 	private KeycloakUserMapper userMapper;
 
 	public void createOrUpdateUser(OzgKeycloakUserSpec userSpec, String namespace) {
-		log.log(Level.INFO, "createOrUpdateUser");
+		if (!userSecretService.exists(userSpec, namespace)) {
+			userSecretService.create(userSpec, namespace);
 
-		if (!remoteService.existSecret(userSpec, namespace)) {
-			log.log(Level.INFO, "Secret not exists -> create one");
-			remoteService.createSecret(userSpec, namespace);
+			log.log(Level.INFO, "Update password...");
+			var password = userSecretService.getPassword(userSpec, namespace);
+			userSpec.getKeycloakUser().setPassword(password);
 		}
-		log.log(Level.INFO, "Secret exists, set password");
-		var password = remoteService.getPasswordFromSecret(userSpec, namespace);
-		log.log(Level.INFO, "Update password to: " + password);
-		userSpec.getKeycloakUser().setPassword(password);
 
 		remoteService.getUserByName(userSpec.getKeycloakUser().getUsername(), namespace)
 				.ifPresentOrElse(existingUser -> remoteService.updateUser(userMapper.update(existingUser, userSpec), namespace),
diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteService.java b/src/main/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteService.java
index bcce1bb38811ef6cd0016a41e1d5d1e67913d39f..c865115328e08f8c576fe0337b20a8594fdd4a6f 100644
--- a/src/main/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteService.java
+++ b/src/main/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteService.java
@@ -1,7 +1,5 @@
 package de.ozgcloud.operator.keycloak.user;
 
-import java.util.logging.Level;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -18,7 +16,7 @@ class KubernetesRemoteService {
 	private KubernetesClient kubernetesClient;
 
 	public Resource<Secret> getSecret(String namespace, String name) {
-		log.log(Level.INFO, "Get " + name + " secret from " + namespace + " namespace.");
+		log.info(String.format("KubernetesClient: Get %s secret from %s namespace.", name, namespace));
 		return kubernetesClient.secrets().inNamespace(namespace).withName(name);
 	}
 }
diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/UserSecretService.java b/src/main/java/de/ozgcloud/operator/keycloak/user/UserSecretService.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b2543e269eef25c243c2455f55787d32f8a0a78
--- /dev/null
+++ b/src/main/java/de/ozgcloud/operator/keycloak/user/UserSecretService.java
@@ -0,0 +1,102 @@
+package de.ozgcloud.operator.keycloak.user;
+
+import java.util.Base64;
+import java.util.Objects;
+import java.util.logging.Level;
+
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.operator.keycloak.user.OzgKeycloakUserSpec.KeycloakUserSpecUser;
+import io.fabric8.kubernetes.api.model.ObjectMeta;
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.SecretBuilder;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.extension.ResourceAdapter;
+import lombok.extern.java.Log;
+
+@Log
+@Component
+class UserSecretService {
+
+	static final String SECRET_PASSWORD_FIELD = "password";
+	static final String SECRET_NAME_FIELD = "name";
+
+	private static final String SECRET_TYPE = "Opaque";
+	private static final String USER_NAME_VALIDITY_REGEX = "[^a-zA-Z0-9]";
+
+	@Autowired
+	private KubernetesRemoteService kubernetesRemoteService;
+
+	public boolean exists(OzgKeycloakUserSpec userSpec, String namespace) {
+		return Objects.nonNull(getUserSecret(userSpec, namespace).get());
+	}
+
+	public void create(OzgKeycloakUserSpec userSpec, String namespace) {
+		log.log(Level.INFO, "Create secret for user: " + userSpec.getKeycloakUser().getUsername());
+		var credentialsSecret = createUserSecret(userSpec.getKeycloakUser(), namespace);
+
+		var adapter = createResourceAdpater(getUserSecret(userSpec, namespace));
+		adapter.create(credentialsSecret);
+	}
+
+	ResourceAdapter<Secret> createResourceAdpater(Resource<Secret> secretResource) {
+		return new ResourceAdapter<>(secretResource);
+	}
+
+	Secret createUserSecret(KeycloakUserSpecUser userSpec, String namespace) {
+		return new SecretBuilder()
+				.withType(SECRET_TYPE)
+				.withMetadata(createMetaData(userSpec, namespace))
+				.addToStringData(SECRET_NAME_FIELD, userSpec.getUsername())
+				.addToStringData(SECRET_PASSWORD_FIELD, getPassword(userSpec.getPassword()))
+				.build();
+	}
+
+	private ObjectMeta createMetaData(KeycloakUserSpecUser userSpec, String namespace) {
+		var name = buildCredentialSecretName(userSpec);
+		var metadata = new ObjectMeta();
+		metadata.setName(name);
+		metadata.setNamespace(namespace);
+		return metadata;
+	}
+
+	String getPassword(String userPassword) {
+		return StringUtils.isEmpty(userPassword) ? generateRandomPasswordForKeycloak() : userPassword;
+	}
+
+	String generateRandomPasswordForKeycloak() {
+		log.log(Level.INFO, "Generate password...");
+		var upperCaseCharacter = RandomStringUtils.randomAlphabetic(1).toUpperCase();
+		var randomString = RandomStringUtils.randomAlphanumeric(7);
+		return upperCaseCharacter + randomString;
+	}
+
+	public String getPassword(OzgKeycloakUserSpec userSpec, String namespace) {
+		return getPassword(getUserSecret(userSpec, namespace));
+	}
+
+	Resource<Secret> getUserSecret(OzgKeycloakUserSpec userSpec, String namespace) {
+		var secretName = buildCredentialSecretName(userSpec.getKeycloakUser());
+		return kubernetesRemoteService.getSecret(namespace, secretName);
+	}
+
+	private String buildCredentialSecretName(KeycloakUserSpecUser userSpec) {
+		return clarifyName(userSpec.getUsername().toLowerCase()) + "-credentials";
+	}
+
+	String clarifyName(String userName) {
+		return userName.replaceAll(USER_NAME_VALIDITY_REGEX, StringUtils.EMPTY);
+	}
+
+	private String getPassword(Resource<Secret> secret) {
+		return decodeBase64(MapUtils.getString(secret.get().getData(), SECRET_PASSWORD_FIELD));
+	}
+
+	private String decodeBase64(String base64String) {
+		return new String(Base64.getDecoder().decode(base64String));
+	}
+}
diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/UserUpdateControlBuilder.java b/src/main/java/de/ozgcloud/operator/keycloak/user/UserUpdateControlBuilder.java
index abe685e6b509dda6ca6503a86fdf387df5fb0eb2..50af3159b3edf1dbccb0de8a036f7e7adfe963e0 100644
--- a/src/main/java/de/ozgcloud/operator/keycloak/user/UserUpdateControlBuilder.java
+++ b/src/main/java/de/ozgcloud/operator/keycloak/user/UserUpdateControlBuilder.java
@@ -42,7 +42,7 @@ class UserUpdateControlBuilder {
 
 	public UpdateControl<OzgKeycloakUser> build() {
 		resource.setStatus(buildOzgKeycloakUserStatus());
-
+		
 		return buildUpdateControl();
 	}
 
diff --git a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java
index 144aa0bde3a0e7734c3ed005c844970e208c89cf..70fd40079ca06c1e92fb78719b2a93322be950a5 100644
--- a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java
+++ b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java
@@ -28,20 +28,16 @@ import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
-import java.util.Base64;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
 import javax.ws.rs.core.Response;
 
-import org.apache.commons.lang3.StringUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.admin.client.resource.ClientsResource;
 import org.keycloak.admin.client.resource.RealmResource;
@@ -58,11 +54,6 @@ import org.mockito.Spy;
 
 import de.ozgcloud.operator.keycloak.KeycloakException;
 import de.ozgcloud.operator.keycloak.KeycloakGenericRemoteService;
-import de.ozgcloud.operator.keycloak.user.OzgKeycloakUserSpec.KeycloakUserSpecUser;
-import io.fabric8.kubernetes.api.model.Secret;
-import io.fabric8.kubernetes.api.model.SecretBuilder;
-import io.fabric8.kubernetes.client.dsl.Resource;
-import io.fabric8.kubernetes.client.extension.ResourceAdapter;
 
 class KeycloakUserRemoteServiceTest {
 
@@ -71,8 +62,6 @@ class KeycloakUserRemoteServiceTest {
 	private final static String USERID = "UserId";
 	private final static String CLIENT_ID = "ClientId";
 
-	private final static String NAMESPACE = "dummyNamespace";
-
 	@Spy
 	@InjectMocks
 	private KeycloakUserRemoteService userRemoteService;
@@ -283,254 +272,4 @@ class KeycloakUserRemoteServiceTest {
 			verify(usersResource).delete(USERID);
 		}
 	}
-
-	@DisplayName("Exists secret")
-	@Nested
-	class TestExistsSecret {
-
-		private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create();
-
-		@Mock
-		private Resource<Secret> resourceMock;
-
-		@BeforeEach
-		void mock() {
-			doReturn(resourceMock).when(userRemoteService).getUserSecret(any(), any());
-		}
-
-		@Test
-		void shouldGetUserSecret() {
-			when(resourceMock.get()).thenReturn(new Secret());
-
-			userRemoteService.existSecret(userSpec, NAMESPACE);
-
-			verify(userRemoteService).getUserSecret(userSpec, NAMESPACE);
-		}
-
-		@Test
-		void shouldReturnTrueIfExists() {
-			when(resourceMock.get()).thenReturn(new Secret());
-
-			var exists = userRemoteService.existSecret(userSpec, NAMESPACE);
-
-			assertThat(exists).isTrue();
-		}
-
-		@Test
-		void shouldReturnFalseIfNotExists() {
-			when(resourceMock.get()).thenReturn(null);
-
-			var exists = userRemoteService.existSecret(userSpec, NAMESPACE);
-
-			assertThat(exists).isFalse();
-		}
-	}
-
-	@DisplayName("Create Secret")
-	@Nested
-	class TestCreateSecret {
-
-		private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create();
-
-		@Mock
-		private Resource<Secret> secretResource;
-		@Mock
-		private Secret secret;
-		@Mock
-		private ResourceAdapter<Secret> resourceAdapter;
-
-		@BeforeEach
-		void mock() {
-			doReturn(secret).when(userRemoteService).createUserSecret(any(), any());
-			doReturn(secretResource).when(userRemoteService).getUserSecret(any(), any());
-			doReturn(resourceAdapter).when(userRemoteService).createResourceAdpater(any());
-		}
-
-		@Test
-		void shouldBuildUserSecret() {
-			userRemoteService.createSecret(userSpec, NAMESPACE);
-
-			verify(userRemoteService).createUserSecret(userSpec.getKeycloakUser(), NAMESPACE);
-		}
-
-		@Test
-		void shouldGetUserSecret() {
-			userRemoteService.createSecret(userSpec, NAMESPACE);
-
-			verify(userRemoteService).getUserSecret(userSpec, NAMESPACE);
-		}
-
-		@Test
-		void shouldCreateResourcAdpater() {
-			userRemoteService.createSecret(userSpec, NAMESPACE);
-
-			verify(userRemoteService).createResourceAdpater(secretResource);
-		}
-
-		@Test
-		void shouldCreateSecret() {
-			userRemoteService.createSecret(userSpec, NAMESPACE);
-
-			verify(resourceAdapter).create(secret);
-		}
-	}
-
-	@DisplayName("Create user secret")
-	@Nested
-	class TestCreateUserSecret {
-
-		private final KeycloakUserSpecUser userSpec = KeycloakUserSpecUserTestFactory.create();
-
-		@Test
-		void shouldHaveType() {
-			var secret = userRemoteService.createUserSecret(userSpec, NAMESPACE);
-
-			assertThat(secret.getType()).isEqualTo("Opaque");
-		}
-
-		@Test
-		void shouldHaveUserName() {
-			var secret = userRemoteService.createUserSecret(userSpec, NAMESPACE);
-
-			assertThat(secret.getStringData()).containsEntry(KeycloakUserRemoteService.SECRET_NAME_FIELD, KeycloakUserSpecUserTestFactory.USERNAME);
-		}
-
-		@Test
-		void shouldHavePassword() {
-			doReturn(KeycloakUserSpecUserTestFactory.PASSWORD).when(userRemoteService).getPassword(any());
-
-			var secret = userRemoteService.createUserSecret(userSpec, NAMESPACE);
-
-			assertThat(secret.getStringData()).containsEntry(KeycloakUserRemoteService.SECRET_PASSWORD_FIELD,
-					KeycloakUserSpecUserTestFactory.PASSWORD);
-		}
-
-		@DisplayName("metadata")
-		@Nested
-		class TestMetaData {
-
-			@Test
-			void shouldHaveName() {
-				var secret = userRemoteService.createUserSecret(userSpec, NAMESPACE);
-
-				assertThat(secret.getMetadata().getName()).isEqualTo(userSpec.getUsername() + "-credentials");
-			}
-
-			@Test
-			void shouldHaveNamespace() {
-				var secret = userRemoteService.createUserSecret(userSpec, NAMESPACE);
-
-				assertThat(secret.getMetadata().getNamespace()).isEqualTo(NAMESPACE);
-			}
-		}
-	}
-
-	@DisplayName("Get password")
-	@Nested
-	class TestGetPassword {
-
-		@Test
-		void shouldReturnPasswordIfExists() {
-			var password = userRemoteService.getPassword(KeycloakUserSpecUserTestFactory.PASSWORD);
-
-			assertThat(password).isEqualTo(KeycloakUserSpecUserTestFactory.PASSWORD);
-		}
-
-		@Test
-		void shouldGeneratePasswordIfNotExists() {
-			userRemoteService.getPassword(StringUtils.EMPTY);
-
-			verify(userRemoteService).generateRandomPasswordForKeycloak();
-		}
-
-		@DisplayName("generate random password for keycloak")
-		@Nested
-		class TestGenerateRandomPasswordForKeycloak {
-
-			@Test
-			void shouldHaveSize() {
-				var password = userRemoteService.getPassword(StringUtils.EMPTY);
-
-				assertThat(password).hasSize(8);
-			}
-
-			@Test
-			void shouldHaveUpperCaseLetterAtFirst() {
-				var password = userRemoteService.getPassword(StringUtils.EMPTY);
-
-				assertThat(StringUtils.substring(password, 0, 1)).isUpperCase();
-			}
-
-			@Test
-			void shouldContainsAlphanumericOnly() {
-				var password = userRemoteService.getPassword(StringUtils.EMPTY);
-
-				assertThat(password).isAlphanumeric();
-			}
-		}
-	}
-
-	@DisplayName("Get password from secret")
-	@Nested
-	class TestGetPasswordFromSecret {
-
-		@Mock
-		private Resource<Secret> resource;
-		private OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create();
-		private Secret secret = new SecretBuilder()
-				.addToData(KeycloakUserRemoteService.SECRET_PASSWORD_FIELD, Base64.getEncoder().encodeToString("dummyPassword".getBytes()))
-				.build();
-
-		@Test
-		void shouldGetUserSecret() {
-			doReturn(resource).when(userRemoteService).getUserSecret(any(), any());
-			when(resource.get()).thenReturn(secret);
-
-			userRemoteService.getPasswordFromSecret(userSpec, NAMESPACE);
-
-			verify(userRemoteService).getUserSecret(userSpec, NAMESPACE);
-		}
-
-		@Test
-		void shouldReturnDecodedPassword() {
-			doReturn(resource).when(userRemoteService).getUserSecret(any(), any());
-			when(resource.get()).thenReturn(secret);
-
-			var password = userRemoteService.getPasswordFromSecret(userSpec, NAMESPACE);
-
-			assertThat(password).isEqualTo("dummyPassword");
-		}
-	}
-
-	@DisplayName("Get user secret")
-	@Nested
-	class TestGetUserSecret {
-
-		@Test
-		void shouldGetSecret() {
-			userRemoteService.getUserSecret(OzgKeycloakUserSpecTestFactory.create(), NAMESPACE);
-
-			verify(kubernetesRemoteService).getSecret(NAMESPACE, KeycloakUserSpecUserTestFactory.USERNAME + "-credentials");
-		}
-
-		@Test
-		void shouldClarifyUserName() {
-			userRemoteService.getUserSecret(OzgKeycloakUserSpecTestFactory.create(), NAMESPACE);
-
-			verify(userRemoteService).clarifyName(KeycloakUserSpecUserTestFactory.USERNAME.toLowerCase());
-		}
-	}
-
-	@DisplayName("Clarify name")
-	@Nested
-	class TestClarifyName {
-
-		@ValueSource(strings = { "_user_name_", ".user.name.", "-user-name-" })
-		@ParameterizedTest
-		void shouldReplaceForbiddenCharacter(String userName) {
-			var clarifiedName = userRemoteService.clarifyName(userName);
-
-			assertThat(clarifiedName).isEqualTo("username");
-		}
-	}
 }
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserServiceTest.java b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserServiceTest.java
index 4bef75990e14e41b6a5076baad07032c525a5950..aa3585c71f3fe6ef7913d589afcf265b93cd4e17 100644
--- a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserServiceTest.java
+++ b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserServiceTest.java
@@ -58,6 +58,9 @@ class KeycloakUserServiceTest {
 	@Mock
 	private KeycloakUserRemoteService remoteService;
 
+	@Mock
+	private UserSecretService userSecretService;
+
 	@Mock
 	private KeycloakUserMapper userMapper;
 
@@ -72,43 +75,47 @@ class KeycloakUserServiceTest {
 
 		private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create();
 
-		@BeforeEach
-		void mock() {
-			when(remoteService.getPasswordFromSecret(any(), any())).thenReturn(PASSWORD);
-		}
+		@DisplayName("on missing secret")
+		@Nested
+		class TestOnMissingSecret {
 
-		@Test
-		void shouldVerifiySecretExists() {
-			service.createOrUpdateUser(userSpec, TEST_NAMESPACE);
+			@BeforeEach
+			void mock() {
+				when(userSecretService.getPassword(any(), any())).thenReturn(PASSWORD);
+				when(userSecretService.exists(any(), any())).thenReturn(false);
+			}
 
-			verify(remoteService).existSecret(userSpec, TEST_NAMESPACE);
-		}
+			@Test
+			void shouldCreateSecretIfNotExists() {
+				service.createOrUpdateUser(userSpec, TEST_NAMESPACE);
 
-		@Test
-		void shouldCreateSecretIfNotExists() {
-			when(remoteService.existSecret(any(), any())).thenReturn(false);
+				verify(userSecretService).create(userSpec, TEST_NAMESPACE);
+			}
 
-			service.createOrUpdateUser(userSpec, TEST_NAMESPACE);
+			@Test
+			void shouldGetPasswordFromSecret() {
+				service.createOrUpdateUser(userSpec, TEST_NAMESPACE);
 
-			verify(remoteService).createSecret(userSpec, TEST_NAMESPACE);
-		}
+				verify(userSecretService).getPassword(userSpec, TEST_NAMESPACE);
+			}
 
-		@Test
-		void shouldGetPasswordFromSecret() {
-			service.createOrUpdateUser(userSpec, TEST_NAMESPACE);
+			@Test
+			void shouldSetPasswortFromSecret() {
+				var userWithoutPassword = OzgKeycloakUserSpecTestFactory.createBuilder()
+						.keycloakUser(KeycloakUserSpecUserTestFactory.createBuiler().password(StringUtils.EMPTY).build()).build();
 
-			verify(remoteService).getPasswordFromSecret(userSpec, TEST_NAMESPACE);
+				service.createOrUpdateUser(userWithoutPassword, TEST_NAMESPACE);
+
+				verify(userMapper).map(ozgKeycloakUserSpecCaptor.capture());
+				assertThat(ozgKeycloakUserSpecCaptor.getValue().getKeycloakUser().getPassword()).isEqualTo(PASSWORD);
+			}
 		}
 
 		@Test
-		void shouldSetPasswortFromSecret() {
-			var userWithoutPassword = OzgKeycloakUserSpecTestFactory.createBuilder()
-					.keycloakUser(KeycloakUserSpecUserTestFactory.createBuiler().password(StringUtils.EMPTY).build()).build();
-
-			service.createOrUpdateUser(userWithoutPassword, TEST_NAMESPACE);
+		void shouldVerifiySecretExists() {
+			service.createOrUpdateUser(userSpec, TEST_NAMESPACE);
 
-			verify(userMapper).map(ozgKeycloakUserSpecCaptor.capture());
-			assertThat(ozgKeycloakUserSpecCaptor.getValue().getKeycloakUser().getPassword()).isEqualTo(PASSWORD);
+			verify(userSecretService).exists(userSpec, TEST_NAMESPACE);
 		}
 
 		@Test
diff --git a/src/test/java/de/ozgcloud/operator/keycloak/user/UserSecretServiceTest.java b/src/test/java/de/ozgcloud/operator/keycloak/user/UserSecretServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..48014e1f90fb6195106d81d8294f7c89bce266ee
--- /dev/null
+++ b/src/test/java/de/ozgcloud/operator/keycloak/user/UserSecretServiceTest.java
@@ -0,0 +1,285 @@
+package de.ozgcloud.operator.keycloak.user;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Base64;
+
+import org.apache.commons.lang3.StringUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+
+import de.ozgcloud.operator.keycloak.user.OzgKeycloakUserSpec.KeycloakUserSpecUser;
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.SecretBuilder;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.extension.ResourceAdapter;
+
+class UserSecretServiceTest {
+
+	private final static String NAMESPACE = "dummyNamespace";
+
+	@Spy
+	@InjectMocks
+	private UserSecretService userSecretService;
+	@Mock
+	private KubernetesRemoteService kubernetesRemoteService;
+
+	@DisplayName("Exists secret")
+	@Nested
+	class TestExistsSecret {
+
+		private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create();
+
+		@Mock
+		private Resource<Secret> resourceMock;
+
+		@BeforeEach
+		void mock() {
+			doReturn(resourceMock).when(userSecretService).getUserSecret(any(), any());
+		}
+
+		@Test
+		void shouldGetUserSecret() {
+			when(resourceMock.get()).thenReturn(new Secret());
+
+			userSecretService.exists(userSpec, NAMESPACE);
+
+			verify(userSecretService).getUserSecret(userSpec, NAMESPACE);
+		}
+
+		@Test
+		void shouldReturnTrueIfExists() {
+			when(resourceMock.get()).thenReturn(new Secret());
+
+			var exists = userSecretService.exists(userSpec, NAMESPACE);
+
+			assertThat(exists).isTrue();
+		}
+
+		@Test
+		void shouldReturnFalseIfNotExists() {
+			when(resourceMock.get()).thenReturn(null);
+
+			var exists = userSecretService.exists(userSpec, NAMESPACE);
+
+			assertThat(exists).isFalse();
+		}
+	}
+
+	@DisplayName("Create Secret")
+	@Nested
+	class TestCreateSecret {
+
+		private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create();
+
+		@Mock
+		private Resource<Secret> secretResource;
+		@Mock
+		private Secret secret;
+		@Mock
+		private ResourceAdapter<Secret> resourceAdapter;
+
+		@BeforeEach
+		void mock() {
+			doReturn(secret).when(userSecretService).createUserSecret(any(), any());
+			doReturn(secretResource).when(userSecretService).getUserSecret(any(), any());
+			doReturn(resourceAdapter).when(userSecretService).createResourceAdpater(any());
+		}
+
+		@Test
+		void shouldBuildUserSecret() {
+			userSecretService.create(userSpec, NAMESPACE);
+
+			verify(userSecretService).createUserSecret(userSpec.getKeycloakUser(), NAMESPACE);
+		}
+
+		@Test
+		void shouldGetUserSecret() {
+			userSecretService.create(userSpec, NAMESPACE);
+
+			verify(userSecretService).getUserSecret(userSpec, NAMESPACE);
+		}
+
+		@Test
+		void shouldCreateResourcAdpater() {
+			userSecretService.create(userSpec, NAMESPACE);
+
+			verify(userSecretService).createResourceAdpater(secretResource);
+		}
+
+		@Test
+		void shouldCreateSecret() {
+			userSecretService.create(userSpec, NAMESPACE);
+
+			verify(resourceAdapter).create(secret);
+		}
+	}
+
+	@DisplayName("Create user secret")
+	@Nested
+	class TestCreateUserSecret {
+
+		private final KeycloakUserSpecUser userSpec = KeycloakUserSpecUserTestFactory.create();
+
+		@Test
+		void shouldHaveType() {
+			var secret = userSecretService.createUserSecret(userSpec, NAMESPACE);
+
+			assertThat(secret.getType()).isEqualTo("Opaque");
+		}
+
+		@Test
+		void shouldHaveUserName() {
+			var secret = userSecretService.createUserSecret(userSpec, NAMESPACE);
+
+			assertThat(secret.getStringData()).containsEntry(UserSecretService.SECRET_NAME_FIELD, KeycloakUserSpecUserTestFactory.USERNAME);
+		}
+
+		@Test
+		void shouldHavePassword() {
+			doReturn(KeycloakUserSpecUserTestFactory.PASSWORD).when(userSecretService).getPassword(any());
+
+			var secret = userSecretService.createUserSecret(userSpec, NAMESPACE);
+
+			assertThat(secret.getStringData()).containsEntry(UserSecretService.SECRET_PASSWORD_FIELD,
+					KeycloakUserSpecUserTestFactory.PASSWORD);
+		}
+
+		@DisplayName("metadata")
+		@Nested
+		class TestMetaData {
+
+			@Test
+			void shouldHaveName() {
+				var secret = userSecretService.createUserSecret(userSpec, NAMESPACE);
+
+				assertThat(secret.getMetadata().getName()).isEqualTo(userSpec.getUsername() + "-credentials");
+			}
+
+			@Test
+			void shouldHaveNamespace() {
+				var secret = userSecretService.createUserSecret(userSpec, NAMESPACE);
+
+				assertThat(secret.getMetadata().getNamespace()).isEqualTo(NAMESPACE);
+			}
+		}
+	}
+
+	@DisplayName("Get password")
+	@Nested
+	class TestGetPassword {
+
+		@Test
+		void shouldReturnPasswordIfExists() {
+			var password = userSecretService.getPassword(KeycloakUserSpecUserTestFactory.PASSWORD);
+
+			assertThat(password).isEqualTo(KeycloakUserSpecUserTestFactory.PASSWORD);
+		}
+
+		@Test
+		void shouldGeneratePasswordIfNotExists() {
+			userSecretService.getPassword(StringUtils.EMPTY);
+
+			verify(userSecretService).generateRandomPasswordForKeycloak();
+		}
+
+		@DisplayName("generate random password for keycloak")
+		@Nested
+		class TestGenerateRandomPasswordForKeycloak {
+
+			@Test
+			void shouldHaveSize() {
+				var password = userSecretService.getPassword(StringUtils.EMPTY);
+
+				assertThat(password).hasSize(8);
+			}
+
+			@Test
+			void shouldHaveUpperCaseLetterAtFirst() {
+				var password = userSecretService.getPassword(StringUtils.EMPTY);
+
+				assertThat(StringUtils.substring(password, 0, 1)).isUpperCase();
+			}
+
+			@Test
+			void shouldContainsAlphanumericOnly() {
+				var password = userSecretService.getPassword(StringUtils.EMPTY);
+
+				assertThat(password).isAlphanumeric();
+			}
+		}
+	}
+
+	@DisplayName("Get password from secret")
+	@Nested
+	class TestGetPasswordFromSecret {
+
+		@Mock
+		private Resource<Secret> resource;
+		private OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create();
+		private Secret secret = new SecretBuilder()
+				.addToData(UserSecretService.SECRET_PASSWORD_FIELD, Base64.getEncoder().encodeToString("dummyPassword".getBytes()))
+				.build();
+
+		@Test
+		void shouldGetUserSecret() {
+			doReturn(resource).when(userSecretService).getUserSecret(any(), any());
+			when(resource.get()).thenReturn(secret);
+
+			userSecretService.getPassword(userSpec, NAMESPACE);
+
+			verify(userSecretService).getUserSecret(userSpec, NAMESPACE);
+		}
+
+		@Test
+		void shouldReturnDecodedPassword() {
+			doReturn(resource).when(userSecretService).getUserSecret(any(), any());
+			when(resource.get()).thenReturn(secret);
+
+			var password = userSecretService.getPassword(userSpec, NAMESPACE);
+
+			assertThat(password).isEqualTo("dummyPassword");
+		}
+	}
+
+	@DisplayName("Get user secret")
+	@Nested
+	class TestGetUserSecret {
+
+		@Test
+		void shouldGetSecret() {
+			userSecretService.getUserSecret(OzgKeycloakUserSpecTestFactory.create(), NAMESPACE);
+
+			verify(kubernetesRemoteService).getSecret(NAMESPACE, KeycloakUserSpecUserTestFactory.USERNAME + "-credentials");
+		}
+
+		@Test
+		void shouldClarifyUserName() {
+			userSecretService.getUserSecret(OzgKeycloakUserSpecTestFactory.create(), NAMESPACE);
+
+			verify(userSecretService).clarifyName(KeycloakUserSpecUserTestFactory.USERNAME.toLowerCase());
+		}
+	}
+
+	@DisplayName("Clarify name")
+	@Nested
+	class TestClarifyName {
+
+		@ValueSource(strings = { "_user_name_", ".user.name.", "-user-name-" })
+		@ParameterizedTest
+		void shouldReplaceForbiddenCharacter(String userName) {
+			var clarifiedName = userSecretService.clarifyName(userName);
+
+			assertThat(clarifiedName).isEqualTo("username");
+		}
+	}
+}