Repository: SAP/cloud-security-xsuaa-integration
Pull request #667 (2021-09-17 12:14:27)

K8s Extension


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index abc29927..8339166f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
 All notable changes to this project will be documented in this file.
 
 ## 2.11.0
+:mega: Client Libraries support Kubernetes/Kyma environment
+- [samples/java-security-usage] enabled for Kyma/Kubernetes environment
+- [samples/spring-security-basic-auth] enabled for Kyma/Kubernetes environment
+- [samples/spring-security-hybrid-usage] enabled for Kyma/Kubernetes environment
+- SECAUTH-1483: Local scope check doesn't work for Service Broker Plan. Workaround is explained [here](https://github.com/SAP/cloud-security-xsuaa-integration/pull/640)
 - [env] extended with Kubernetes/Kyma environment support
 
 #### Dependency upgrades
@@ -15,6 +20,7 @@ All notable changes to this project will be documented in this file.
 - org.springframework.boot:spring-boot 2.5.3 to 2.5.4 
 - org.mockito:mockito-core 3.11.2 --> 3.12.4
 
+
 ## 2.10.5
 - [token-client]
   - new method `SSLContextFactory.createKeyStore(ClientIdentity)`
diff --git a/env/pom.xml b/env/pom.xml
index d29bfd28..ad614a3b 100644
--- a/env/pom.xml
+++ b/env/pom.xml
@@ -23,19 +23,18 @@
             <artifactId>java-api</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <!-- Required only in case of multiple xsuaa bindings -->
         <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
+            <groupId>com.sap.cloud.security.xsuaa</groupId>
+            <artifactId>token-client</artifactId>
+            <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
+        <!-- Required only in case of multiple xsuaa bindings -->
         <dependency>
-            <groupId>org.json</groupId>
-            <artifactId>json</artifactId>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <scope>provided</scope>
         </dependency>
 
         <!-- test utilities -->
@@ -64,12 +63,35 @@
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.github.tomakehurst</groupId>
+            <artifactId>wiremock-jre8</artifactId>
+            <version>2.29.1</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>com.github.stefanbirkner</groupId>
             <artifactId>system-rules</artifactId>
             <version>1.19.0</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>uk.org.webcompere</groupId>
+            <artifactId>system-stubs-jupiter</artifactId>
+            <version>1.2.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.github.hakky54</groupId>
+            <artifactId>logcaptor</artifactId>
+            <version>2.7.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/env/src/main/java/com/sap/cloud/security/config/Environments.java b/env/src/main/java/com/sap/cloud/security/config/Environments.java
index f176e69c..eccdc0f1 100644
--- a/env/src/main/java/com/sap/cloud/security/config/Environments.java
+++ b/env/src/main/java/com/sap/cloud/security/config/Environments.java
@@ -6,17 +6,26 @@
 package com.sap.cloud.security.config;
 
 import com.sap.cloud.security.config.cf.CFEnvironment;
+import com.sap.cloud.security.config.k8s.K8sEnvironment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.InputStream;
 import java.util.Scanner;
 
+import static com.sap.cloud.security.config.k8s.K8sConstants.KUBERNETES_SERVICE_HOST;
+
 /**
  * Central entry point to access the current SAP Cloud Platform
  * {@link Environment}.
  */
 public class Environments {
 
-	private static final Environment cfEnvironment = CFEnvironment.getInstance(); // singleton
+	private static final Logger LOGGER = LoggerFactory.getLogger(Environments.class);
+
+	private static Environment cfEnvironment; // singleton
+	private static Environment k8sEnvironment; // singleton
+	private static Boolean isK8sEnv;
 
 	private Environments() {
 		// use factoryMethods instead
@@ -28,13 +37,33 @@ public class Environments {
 	 * @return the current environment
 	 */
 	public static Environment getCurrent() {
-		// TODO Kubernetes: probe in which environment it runs currently: CF or
+		if (isK8sEnv()) {
+			LOGGER.debug("K8s environment detected");
+			return getK8sEnvironment();
+		} else {
+			LOGGER.debug("CF environment detected");
+			return getCfEnvironment();
+		}
+	}
+
+	private static Environment getCfEnvironment() {
+		if (cfEnvironment == null) {
+			cfEnvironment = CFEnvironment.getInstance();
+		}
 		return cfEnvironment;
 	}
 
+	private static Environment getK8sEnvironment() {
+		if (k8sEnvironment == null) {
+			k8sEnvironment = K8sEnvironment.getInstance();
+		}
+		return k8sEnvironment;
+	}
+
 	/**
 	 * Reads {@link Environment} not from system environment but from
-	 * {@link InputStream}.
+	 * {@link InputStream}. Is applicable only to CF environment and expects the
+	 * input to be in VCAP services format.
 	 * 
 	 * @param input
 	 *            e.g. from file
@@ -49,4 +78,11 @@ public class Environments {
 		return CFEnvironment.getInstance(str -> vcapServices.toString(), str -> null);
 	}
 
+	private static boolean isK8sEnv() {
+		if (isK8sEnv == null) {
+			isK8sEnv = System.getenv().get(KUBERNETES_SERVICE_HOST) != null;
+		}
+		return isK8sEnv;
+	}
+
 }
diff --git a/env/src/main/java/com/sap/cloud/security/config/k8s/DefaultServiceManagerService.java b/env/src/main/java/com/sap/cloud/security/config/k8s/DefaultServiceManagerService.java
new file mode 100644
index 00000000..0496c41a
--- /dev/null
+++ b/env/src/main/java/com/sap/cloud/security/config/k8s/DefaultServiceManagerService.java
@@ -0,0 +1,144 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import com.sap.cloud.security.client.HttpClientFactory;
+import com.sap.cloud.security.config.OAuth2ServiceConfiguration;
+import com.sap.cloud.security.xsuaa.client.DefaultOAuth2TokenService;
+import com.sap.cloud.security.xsuaa.client.OAuth2ServiceException;
+import com.sap.cloud.security.xsuaa.client.OAuth2TokenResponse;
+import com.sap.cloud.security.xsuaa.client.OAuth2TokenService;
+import com.sap.cloud.security.xsuaa.util.HttpClientUtil;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.methods.RequestBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The DefaultServiceManagerService fetches information about service instances
+ * and service instance plans.
+ */
+class DefaultServiceManagerService {
+	private static final Logger LOGGER = LoggerFactory.getLogger(DefaultServiceManagerService.class);
+	private static final String SERVICE_PLANS = "/v1/service_plans";
+	private static final String SERVICE_INSTANCES = "/v1/service_instances";
+
+	private final CloseableHttpClient httpClient;
+	private final OAuth2ServiceConfiguration smConfiguration;
+	private final OAuth2TokenService defaultOAuth2TokenService;
+
+	DefaultServiceManagerService(OAuth2ServiceConfiguration smConfiguration) {
+		this(smConfiguration, HttpClientFactory.create(smConfiguration.getClientIdentity()));
+	}
+
+	DefaultServiceManagerService(OAuth2ServiceConfiguration smConfiguration, CloseableHttpClient httpClient) {
+		this.smConfiguration = smConfiguration;
+		this.httpClient = httpClient;
+		this.defaultOAuth2TokenService = new DefaultOAuth2TokenService(this.httpClient);
+	}
+
+	Map<String, String> getServiceInstancePlans() {
+		Map<String, String> servicePlans = getServicePlans();
+		Map<String, String> serviceInstances = getServiceInstances();
+		if (serviceInstances.isEmpty() || servicePlans.isEmpty()) {
+			LOGGER.warn("Couldn't fetch plans or instances from service-manager");
+			return Collections.emptyMap();
+		}
+		serviceInstances.keySet().forEach(k -> serviceInstances.put(k, servicePlans.get(serviceInstances.get(k))));
+		LOGGER.debug("Service Instances with plan names: {}", serviceInstances);
+		return serviceInstances;
+	}
+
+	// TODO make private, adjust tests
+	Map<String, String> getServicePlans() {
+		HttpUriRequest request = RequestBuilder.create("GET")
+				.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + retrieveAccessToken())
+				.setUri(smConfiguration.getProperty("sm_url") + SERVICE_PLANS)
+				.build();
+		Map<String, String> servicePlanMap = new HashMap<>();
+		try {
+			JSONArray responseArray = executeRequest(request);
+			responseArray.forEach(plan -> servicePlanMap.put((String) ((JSONObject) plan).get("id"),
+					(String) ((JSONObject) plan).get("name")));
+		} catch (OAuth2ServiceException e) {
+			LOGGER.warn("Unexpected error occurred: {}", e.getMessage());
+		}
+		LOGGER.debug("Service plans: {}", servicePlanMap);
+		return servicePlanMap;
+	}
+
+	// TODO make private, adjust tests
+	Map<String, String> getServiceInstances() {
+		HttpUriRequest request = RequestBuilder.create("GET")
+				.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + retrieveAccessToken())
+				.setUri(smConfiguration.getProperty("sm_url") + SERVICE_INSTANCES)
+				.build();
+		Map<String, String> serviceInstanceMap = new HashMap<>();
+		try {
+			JSONArray responseArray = executeRequest(request);
+			responseArray.forEach(plan -> serviceInstanceMap.put((String) ((JSONObject) plan).get("name"),
+					(String) ((JSONObject) plan).get("service_plan_id")));
+		} catch (OAuth2ServiceException e) {
+			LOGGER.warn("Unexpected error occurred: {}", e.getMessage());
+		}
+		LOGGER.debug("Service instances: {}", serviceInstanceMap);
+		return serviceInstanceMap;
+	}
+
+	private JSONArray executeRequest(HttpUriRequest httpRequest) throws OAuth2ServiceException {
+		LOGGER.debug("Executing Http request to {} with headers {}", httpRequest.getURI(),
+				httpRequest.getAllHeaders());
+		try (CloseableHttpResponse response = httpClient.execute(httpRequest)) {
+			int statusCode = response.getStatusLine().getStatusCode();
+			LOGGER.debug("Received statusCode {} from {}", statusCode, httpRequest.getURI());
+			if (statusCode == HttpStatus.SC_OK) {
+				return handleResponse(response);
+			} else {
+				String responseBodyAsString = HttpClientUtil.extractResponseBodyAsString(response);
+				LOGGER.debug("Received response body: {}", responseBodyAsString);
+				throw OAuth2ServiceException.builder("Error accessing service-manager endpoint")
+						.withStatusCode(statusCode)
+						.withUri(httpRequest.getURI())
+						.withResponseBody(responseBodyAsString)
+						.build();
+			}
+		} catch (IOException e) {
+			throw new OAuth2ServiceException(String.format("Unexpected error accessing service-manager endpoint %s: %s",
+					httpRequest.getURI(), e.getMessage()));
+		}
+	}
+
+	private JSONArray handleResponse(HttpResponse response) throws IOException {
+		String responseBody = HttpClientUtil.extractResponseBodyAsString(response);
+		return new JSONObject(responseBody).getJSONArray("items");
+	}
+
+	@Nullable
+	private String retrieveAccessToken() {
+		try {
+			OAuth2TokenResponse oAuth2TokenResponse = defaultOAuth2TokenService
+					.retrieveAccessTokenViaClientCredentialsGrant(smConfiguration.getUrl().resolve("/oauth/token"),
+							smConfiguration.getClientIdentity(), null, null, null, false);
+			return oAuth2TokenResponse.getAccessToken();
+		} catch (OAuth2ServiceException e) {
+			LOGGER.warn("Couldn't retrieve access token for service manager.", e);
+			return null;
+		}
+	}
+}
diff --git a/env/src/main/java/com/sap/cloud/security/config/k8s/K8sEnvironment.java b/env/src/main/java/com/sap/cloud/security/config/k8s/K8sEnvironment.java
new file mode 100644
index 00000000..4b044e00
--- /dev/null
+++ b/env/src/main/java/com/sap/cloud/security/config/k8s/K8sEnvironment.java
@@ -0,0 +1,89 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import com.sap.cloud.security.config.Environment;
+import com.sap.cloud.security.config.OAuth2ServiceConfiguration;
+import com.sap.cloud.security.config.Service;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.sap.cloud.security.config.k8s.K8sConstants.Plan;
+
+/**
+ * Loads the OAuth configuration ({@link OAuth2ServiceConfiguration}) of a
+ * supported identity {@link Service} in the Kubernetes Environment by accessing
+ * defaults service secrets paths "/etc/secrets/sapbtp/xsuaa" for Xsuaa service
+ * or "/etc/secrets/sapbtp/identity" for IAS service.
+ */
+public class K8sEnvironment implements Environment {
+	private static final Logger LOGGER = LoggerFactory.getLogger(K8sEnvironment.class);
+
+	private static K8sEnvironment instance;
+	private final Map<Service, Map<String, OAuth2ServiceConfiguration>> k8sServiceConfigurations;
+
+	private K8sEnvironment() {
+		k8sServiceConfigurations = new K8sServiceConfigurationProvider().getServiceConfigurations();
+	}
+
+	public static K8sEnvironment getInstance() {
+		if (instance == null) {
+			instance = new K8sEnvironment();
+		}
+		return instance;
+	}
+
+	@Nonnull
+	@Override
+	public Type getType() {
+		return Type.KUBERNETES;
+	}
+
+	@Nullable
+	@Override
+	public OAuth2ServiceConfiguration getXsuaaConfiguration() {
+		Map<String, OAuth2ServiceConfiguration> xsuaaPlans = k8sServiceConfigurations.get(Service.XSUAA);
+
+		return Optional.ofNullable(xsuaaPlans.get(Plan.APPLICATION.name()))
+				.orElse(Optional.ofNullable(xsuaaPlans.get(Plan.BROKER.name()))
+						.orElse(Optional.ofNullable(xsuaaPlans.get(Plan.SPACE.name()))
+								.orElse(Optional.ofNullable(xsuaaPlans.get(Plan.DEFAULT.name()))
+										.orElse(null))));
+
+	}
+
+	@Nullable
+	@Override
+	public OAuth2ServiceConfiguration getXsuaaConfigurationForTokenExchange() {
+		if (getNumberOfXsuaaConfigurations() > 1) {
+			return k8sServiceConfigurations.get(Service.XSUAA).get(Plan.BROKER.name());
+		}
+		return getXsuaaConfiguration();
+	}
+
+	@Nullable
+	@Override
+	public OAuth2ServiceConfiguration getIasConfiguration() {
+		Set<Map.Entry<String, OAuth2ServiceConfiguration>> iasConfigEntries = k8sServiceConfigurations
+				.get(Service.IAS).entrySet();
+		if (iasConfigEntries.size() > 1) {
+			LOGGER.warn("{} IAS bindings found. Using the first one from the list", iasConfigEntries.size());
+		}
+		return iasConfigEntries.stream().findFirst().map(Map.Entry::getValue).orElse(null);
+	}
+
+	@Override
+	public int getNumberOfXsuaaConfigurations() {
+		return k8sServiceConfigurations.get(Service.XSUAA).size();
+	}
+
+}
diff --git a/env/src/main/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationProvider.java b/env/src/main/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationProvider.java
new file mode 100644
index 00000000..4588dfde
--- /dev/null
+++ b/env/src/main/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationProvider.java
@@ -0,0 +1,96 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import com.sap.cloud.security.config.OAuth2ServiceConfiguration;
+import com.sap.cloud.security.config.Service;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The K8sServiceConfigurationProvider provides the information of all bound
+ * service configurations.
+ */
+class K8sServiceConfigurationProvider {
+	private static final Logger LOGGER = LoggerFactory.getLogger(K8sServiceConfigurationProvider.class);
+	private static final String APPLICATION = "APPLICATION";
+
+	private DefaultServiceManagerService serviceManagerClient;
+	private final K8sServiceConfigurationResolver serviceConfigurationResolver;
+
+	K8sServiceConfigurationProvider() {
+		this.serviceConfigurationResolver = new K8sServiceConfigurationResolver();
+		if (serviceConfigurationResolver
+				.loadOauth2ServiceConfig(Service.XSUAA).size() > 1
+				&& serviceConfigurationResolver.loadServiceManagerConfig() != null) {
+			this.serviceManagerClient = new DefaultServiceManagerService(
+					serviceConfigurationResolver.loadServiceManagerConfig());
+		}
+	}
+
+	void setServiceManagerClient(DefaultServiceManagerService serviceManagerClient) {
+		this.serviceManagerClient = serviceManagerClient;
+	}
+
+	/**
+	 * Gets all service configurations from the mounted file volumes.
+	 *
+	 * @return the service configurations map of IAS and XSUAA services with their
+	 *         corresponding OAuth2ServiceConfigurations. For Xsuaa Map key is the
+	 *         service plan name, for IAS key is the service instance name.
+	 */
+	EnumMap<Service, Map<String, OAuth2ServiceConfiguration>> getServiceConfigurations() {
+		EnumMap<Service, Map<String, OAuth2ServiceConfiguration>> serviceConfigurations = new EnumMap<>(Service.class);
+
+		serviceConfigurations.put(Service.XSUAA, mapXsuaaServicePlans(serviceConfigurationResolver
+				.loadOauth2ServiceConfig(Service.XSUAA)));
+		serviceConfigurations.put(Service.IAS, serviceConfigurationResolver
+				.loadOauth2ServiceConfig(Service.IAS));
+
+		return serviceConfigurations;
+	}
+
+	private Map<String, OAuth2ServiceConfiguration> mapXsuaaServicePlans(
+			Map<String, OAuth2ServiceConfiguration> allXsuaaServices) {
+		Map<String, OAuth2ServiceConfiguration> allXsuaaServicesWithPlans = new HashMap<>();// <planName, config>
+
+		if (!allXsuaaServices.isEmpty() && allXsuaaServices.size() > 1) {
+			if (serviceManagerClient == null) {
+				return getSingleXsuaaConfigWithApplicationPlan(allXsuaaServices, "No service-manager client available");
+			}
+			Map<String, String> serviceInstancePlans = serviceManagerClient.getServiceInstancePlans();// <xsuaaName,planName>
+			if (serviceInstancePlans.isEmpty()) {
+				return getSingleXsuaaConfigWithApplicationPlan(allXsuaaServices,
+						"No plans or instances were fetched from service manager");
+			}
+			allXsuaaServices.keySet().forEach(
+					k -> allXsuaaServicesWithPlans.put(serviceInstancePlans.get(k).toUpperCase(),
+							allXsuaaServices.get(k)));
+		} else if (allXsuaaServices.size() == 1) {
+			return getSingleXsuaaConfigWithApplicationPlan(allXsuaaServices, null);
+		}
+		return allXsuaaServicesWithPlans;
+	}
+
+	private Map<String, OAuth2ServiceConfiguration> getSingleXsuaaConfigWithApplicationPlan(
+			Map<String, OAuth2ServiceConfiguration> allXsuaaServices, @Nullable String warningMessage) {
+		Map.Entry<String, OAuth2ServiceConfiguration> xsuaaServiceEntrySet = allXsuaaServices.entrySet().iterator()
+				.next();
+		if (warningMessage != null) {
+			LOGGER.warn("{}, taking first Xsuaa service instance '{}' and assigning 'application' plan", warningMessage,
+					xsuaaServiceEntrySet.getKey());
+		} else {
+			LOGGER.info("Assigning 'application' plan to '{}' service", xsuaaServiceEntrySet.getKey());
+		}
+		return Collections.singletonMap(APPLICATION, xsuaaServiceEntrySet.getValue());
+	}
+}
diff --git a/env/src/main/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationResolver.java b/env/src/main/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationResolver.java
new file mode 100644
index 00000000..099716a1
--- /dev/null
+++ b/env/src/main/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationResolver.java
@@ -0,0 +1,169 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import com.sap.cloud.security.config.OAuth2ServiceConfiguration;
+import com.sap.cloud.security.config.OAuth2ServiceConfigurationBuilder;
+import com.sap.cloud.security.config.Service;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.sap.cloud.security.config.k8s.K8sConstants.*;
+
+/**
+ * The K8sServiceConfigurationResolver manages the service secret access from
+ * the file system.
+ */
+class K8sServiceConfigurationResolver {
+	private static final Logger LOGGER = LoggerFactory.getLogger(K8sServiceConfigurationResolver.class);
+
+	private String xsuaaPath;
+	private String iasPath;
+	private String serviceManagerPath;
+
+	K8sServiceConfigurationResolver() {
+		resolveServiceConfigurationPaths();
+	}
+
+	/**
+	 * Loads Service manager OAuth2 service configuration.
+	 *
+	 * @return OAuth2 service configuration
+	 */
+	@Nullable
+	OAuth2ServiceConfiguration loadServiceManagerConfig() {
+		File[] serviceBindings = new File(serviceManagerPath).listFiles();
+		if (serviceBindings == null || serviceBindings.length == 0) {
+			LOGGER.warn("No service-manager binding was found in {}", serviceManagerPath);
+			return null;
+		}
+		Map<String, String> smPropertiesMap = getServiceProperties(serviceBindings[0]);
+		return OAuth2ServiceConfigurationBuilder.forService(Service.XSUAA).withProperties(smPropertiesMap).build();
+	}
+
+	/**
+	 * Loads XSUAA or IAS OAuth2 service configuration.
+	 *
+	 * @param service
+	 *            IAS or XSUAA service
+	 * @return the map of service instance name and it's OAuth2 service
+	 *         configurations
+	 */
+	Map<String, OAuth2ServiceConfiguration> loadOauth2ServiceConfig(Service service) {
+		Map<String, OAuth2ServiceConfiguration> allServices = new HashMap<>();
+		File[] serviceBindings = getServiceBindings(service);
+		if (serviceBindings == null || serviceBindings.length == 0) {
+			LOGGER.warn("No service bindings for {} service were found", service);
+		} else {
+			LOGGER.info("Found {} {} service binding/s", serviceBindings.length, service);
+			for (File binding : serviceBindings) {
+				Map<String, String> servicePropertiesMap = getServiceProperties(binding);
+				if (!servicePropertiesMap.isEmpty()) {
+					OAuth2ServiceConfiguration config;
+					if (servicePropertiesMap.containsKey("domains")){
+						config = OAuth2ServiceConfigurationBuilder.forService(service)
+								.withProperties(servicePropertiesMap)
+								.withDomains(servicePropertiesMap.get("domains").replaceAll("[\\[\"\\s\\]]+", "").split(","))
+								.build();
+					}else{
+						config = OAuth2ServiceConfigurationBuilder.forService(service)
+								.withProperties(servicePropertiesMap)
+								.build();
+					}
+					allServices.put(binding.getName(), config);
+				}
+			}
+		}
+		return allServices;
+	}
+
+	@Nullable
+	private File[] getServiceBindings(Service service) {
+		String path = service == Service.XSUAA ? xsuaaPath : iasPath;
+		LOGGER.debug("Retrieving {} service bindings from K8s secret file {}", service, path);
+		File[] bindings = new File(path).listFiles();
+		if (bindings != null) {
+			return Arrays.stream(bindings).filter(File::isDirectory).toArray(File[]::new);
+		}
+		return null;
+	}
+
+	private List<File> getBindingFiles(@Nonnull File binding) {
+		File[] bindingFiles = new File(binding.getPath()).listFiles();
+		if (bindingFiles == null || bindingFiles.length == 0) {
+			LOGGER.warn("No service binding files were found for {}", binding.getName());
+			return Collections.emptyList();
+		}
+		return Arrays.stream(bindingFiles).filter(File::isFile)
+				.collect(Collectors.toList());
+	}
+
+	private Map<String, String> getServiceProperties(File binding) {
+		List<File> serviceBindingFiles = getBindingFiles(binding);
+		if (serviceBindingFiles.isEmpty()) {
+			return Collections.emptyMap();
+		}
+		return mapServiceProperties(serviceBindingFiles);
+	}
+
+	private Map<String, String> mapServiceProperties(List<File> servicePropertiesList) {
+		final Map<String, String> serviceProperties = new HashMap<>();
+		for (final File property : servicePropertiesList) {
+			try {
+				final List<String> lines = readLinesFromFile(property);
+				if (!lines.isEmpty()) {
+					serviceProperties.put(property.getName(), String.join("\\n", lines));
+				} else {
+					LOGGER.warn("{} value is empty", property.getName());
+				}
+			} catch (IOException ex) {
+				LOGGER.error("Failed to read content of service configuration property files", ex);
+				return serviceProperties;
+			}
+		}
+		LOGGER.debug("{} attributes: {}", servicePropertiesList.get(0).getParentFile().getName(), serviceProperties);
+		return serviceProperties;
+	}
+
+	@Nonnull
+	private static List<String> readLinesFromFile(File property) throws IOException {
+		return Files.readAllLines(Paths.get(property.getAbsolutePath()));
+	}
+
+	private void resolveServiceConfigurationPaths() {
+		this.xsuaaPath = getUserDefinedConfigurationPath(XSUAA_CONFIG_PATH);
+		this.iasPath = getUserDefinedConfigurationPath(IAS_CONFIG_PATH);
+		this.serviceManagerPath = getUserDefinedConfigurationPath(SM_CONFIG_PATH);
+		if (this.xsuaaPath == null) {
+			this.xsuaaPath = XSUAA_CONFIG_PATH_DEFAULT;
+		}
+		if (this.iasPath == null) {
+			this.iasPath = IAS_CONFIG_PATH_DEFAULT;
+		}
+		if (this.serviceManagerPath == null) {
+			this.serviceManagerPath = SERVICE_MANAGER_CONFIG_PATH_DEFAULT;
+		}
+	}
+
+	@Nullable
+	private String getUserDefinedConfigurationPath(String xsuaaConfigPath) {
+		// Resolves also empty string as null
+		if (System.getenv(xsuaaConfigPath) == null || System.getenv(xsuaaConfigPath).isEmpty()) {
+			return null;
+		}
+		return System.getenv(xsuaaConfigPath);
+	}
+}
diff --git a/java-api/src/main/java/com/sap/cloud/security/config/Environment.java b/java-api/src/main/java/com/sap/cloud/security/config/Environment.java
index 461a7ae6..0e1fb6b0 100644
--- a/java-api/src/main/java/com/sap/cloud/security/config/Environment.java
+++ b/java-api/src/main/java/com/sap/cloud/security/config/Environment.java
@@ -18,7 +18,7 @@ public interface Environment {
 	 * Represents a supported SAP CP environment.
 	 */
 	enum Type {
-		CF /* , KUBERNETES */;
+		CF, KUBERNETES;
 
 		public static Type from(String typeAsString) {
 			return Type.valueOf(typeAsString.toUpperCase());
diff --git a/java-api/src/main/java/com/sap/cloud/security/config/k8s/K8sConstants.java b/java-api/src/main/java/com/sap/cloud/security/config/k8s/K8sConstants.java
new file mode 100644
index 00000000..9c4d2c8a
--- /dev/null
+++ b/java-api/src/main/java/com/sap/cloud/security/config/k8s/K8sConstants.java
@@ -0,0 +1,48 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import com.sap.cloud.security.config.cf.CFConstants;
+
+/**
+ * Constants that simplifies access to service configuration properties in the
+ * Kubernetes environment.
+ */
+public class K8sConstants {
+	public static final String KUBERNETES_SERVICE_HOST = "KUBERNETES_SERVICE_HOST";
+	static final String XSUAA_CONFIG_PATH_DEFAULT = "/etc/secrets/sapbtp/xsuaa";
+	static final String IAS_CONFIG_PATH_DEFAULT = "/etc/secrets/sapbtp/identity";
+	static final String SERVICE_MANAGER_CONFIG_PATH_DEFAULT = "/etc/secrets/sapbtp/service-manager";
+
+	/**
+	 * System variable name for user defined Xsuaa configuration path
+	 */
+	static final String XSUAA_CONFIG_PATH = "XSUAA_CONFIG_PATH";
+	/**
+	 * System variable name for user defined IAS configuration path
+	 */
+	static final String IAS_CONFIG_PATH = "IAS_CONFIG_PATH";
+	/**
+	 * System variable name for user defined Service manager configuration path
+	 */
+	static final String SM_CONFIG_PATH = "SM_CONFIG_PATH";
+
+	private K8sConstants() {
+	}
+
+	/**
+	 * Represents the service plans available in Kyma Service Catalog. The various
+	 * plans are considered in {@code K8sEnvironment}
+	 */
+	public enum Plan {
+		DEFAULT, BROKER, APPLICATION, SPACE, APIACCESS, SYSTEM;
+
+		public static CFConstants.Plan from(String planAsString) {
+			return CFConstants.Plan.valueOf(planAsString.toUpperCase());
+		}
+
+	}
+}
diff --git a/java-security/README.md b/java-security/README.md
index ebd8e151..c3291800 100644
--- a/java-security/README.md
+++ b/java-security/README.md
@@ -2,7 +2,7 @@
 
 Token Validation for Java applications.
 
-- Loads Identity Service Configuration from `VCAP_SERVICES` environment. The [`Environments`](src/main/java/com/sap/cloud/security/config/Environments.java) serves as central entry point to get or parse the  [`OAuth2ServiceConfiguration`](src/main/java/com/sap/cloud/security/config/OAuth2ServiceConfiguration.java) within SAP Cloud Platform.
+- Loads Identity Service Configuration from `VCAP_SERVICES` in Cloud Foundry or from secrets in Kubernetes environment. The [`Environments`](src/main/java/com/sap/cloud/security/config/Environments.java) serves as central entry point to get or parse the  [`OAuth2ServiceConfiguration`](src/main/java/com/sap/cloud/security/config/OAuth2ServiceConfiguration.java) within SAP Business Technology Platform.
 - Decodes and parses encoded JSON Web Tokens ([`Token`](/java-api/src/main/java/com/sap/cloud/security/token/Token.java)) and provides convenient access to token header parameters and claims. A Java implementation of JSON Web Token (JWT) - [RFC 7519](https://tools.ietf.org/html/rfc7519). 
 - Validates the decoded token. The [`JwtValidatorBuilder`](src/main/java/com/sap/cloud/security/token/validation/validators/JwtValidatorBuilder.java) comprises the following mandatory checks:
   - Is the JWT used before the `exp` (expiration) time and eventually is it used after the `nbf` (not before) time ([`JwtTimestampValidator`](
@@ -26,7 +26,7 @@ In case of XSUAA does the JWT provide a valid `jku` token header parameter that
 
 ## Supported Environments
 - Cloud Foundry
-- Planned: Kubernetes
+- Kubernetes/Kyma
 
 ## Supported Identity Services
 - XSUAA
@@ -77,7 +77,7 @@ logger options.
 ```java
 OAuth2ServiceConfiguration serviceConfig = Environments.getCurrent().getXsuaaConfiguration();
 ```
-> Note: By default `Environments` auto-detects the environment: Cloud Foundry or Kubernetes.
+> Note: By default `Environments` auto-detects the environment: Cloud Foundry or Kubernetes. 
 
 Alternatively you can also specify the Service Configuration by your own:
 ```java
@@ -91,6 +91,17 @@ OAuth2ServiceConfiguration serviceConfig = OAuth2ServiceConfigurationBuilder.for
 ```
 :bulb: `OAuth2ServiceConfiguration.getClientIdentity()` is a convenience method that with `OAuth2ServiceConfigurationBuilder` implementation will resolve `ClientCredentials` or `ClientCertificate` implementations of `ClientIdentity` interface based on the `credential-type` from the Xsuaa service binding. Therefore, providing the correct implementation for the configured authentication type e.g. X.509 or client secret based.
 
+#### :mega: Service configuration in Kubernetes/Kyma environment 
+To access service instance configurations from the application, Kubernetes secrets need to be provided as files in a volume mounted on application's container. 
+Library will look up the configuration files in the following paths:
+- XSUAA: `/etc/secrets/sapbtp/xsuaa/<YOUR XSUAA INSTANCE NAME>`
+- IAS: `/etc/secrets/sapbtp/identity/<YOUR IAS INSTANCE NAME>`
+- Service-manager: `/etc/secrets/sapbtp/service-manager/<YOUR SERVICE-MANAGER NAME>`
+
+:exclamation: service-manager binding is mandatory to resolve multiple Xsuaa bindings! If it is not provided the first Xsuaa binding from a list is used and treated as instance with `application` plan.
+
+Detailed information on how to use ``java-security`` library in Kubernetes/Kyma environment can be found in [java-security-usage](/samples/java-security-usage/README.md#deployment-on-kymakubernetes) sample README.
+
 ### Setup Step 2: Setup Validators
 Now configure the `JwtValidatorBuilder` once with the service configuration from the previous step.
 ```java
diff --git a/samples/README.md b/samples/README.md
index e688394c..836c6b15 100644
--- a/samples/README.md
+++ b/samples/README.md
@@ -5,18 +5,23 @@
 [sap-java-buildpack-api-usage](./sap-java-buildpack-api-usage): Sample demonstrating how to leverage SAP java buildpack to secure a Java J2EE web application.
 
 ## Java
-[java-security-usage](./java-security-usage): Sample demonstrating how to leverage ``java-security`` library to perform authentication and authorization checks within a Java application when bound to a xsuaa service. Furthermore it documents how to implement JUnit Tests using `java-security-test` library.
+[java-security-usage](./java-security-usage): Sample demonstrating how to leverage ``java-security`` library to perform authentication and authorization checks within a Java application when bound to a xsuaa service. Furthermore, it documents how to implement JUnit Tests using `java-security-test` library.
+</br>:heavy_check_mark: enabled for Kubernetes/Kyma environment<br/>
 
-[java-security-usage-ias](./java-security-usage-ias): Sample demonstrating how to leverage ``java-security`` library to perform authentication checks within a Java application when bound to a ias identity service. Furthermore it documents how to implement JUnit Tests using `java-security-test` library.
+[java-security-usage-ias](./java-security-usage-ias): Sample demonstrating how to leverage ``java-security`` library to perform authentication checks within a Java application when bound to a ias identity service. Furthermore, it documents how to implement JUnit Tests using `java-security-test` library.
 
 [java-tokenclient-usage](./java-tokenclient-usage): Java application demonstrating how to use xsuaa [token-client](/token-client) library for token exchange.
 
 ## Spring Boot 2.1 and later
 [spring-security-basic-auth](./spring-security-basic-auth): Spring Boot web application demonstrating how a user can access Rest API via basic authentication (user/password).
+</br>:heavy_check_mark: enabled for Kubernetes/Kyma environment
 
-[spring-security-xsuaa-usage](./spring-security-xsuaa-usage): Sample demonstrating how to leverage xsuaa and spring security library to secure a Spring Boot web application including token exchange (user, client-credentials, refresh, ...).
+[spring-security-xsuaa-usage](./spring-security-xsuaa-usage): Sample demonstrating how to leverage ``spring-xsuaa`` library to secure a Spring Boot web application including token exchange (user, client-credentials, refresh, ...).
 Furthermore it documents how to implement SpringWebMvcTests using `java-security-test` library.
 
+[spring-security-hybrid-usage](./spring-security-hybrid-usage): Sample demonstrating how to leverage ```spring-security``` client library to validate jwt tokens issued by ```xsuaa``` service or by ```identity ``` service.
+</br>:heavy_check_mark: enabled for Kubernetes/Kyma environment
+
 [spring-webflux-security-xsuaa-usage](./spring-webflux-security-xsuaa-usage): Sample demonstrating how to leverage xsuaa and spring security library to secure a Spring Boot web application.
 
 ## Other Samples
diff --git a/samples/java-security-usage/Dockerfile b/samples/java-security-usage/Dockerfile
new file mode 100644
index 00000000..9f1e7157
--- /dev/null
+++ b/samples/java-security-usage/Dockerfile
@@ -0,0 +1,5 @@
+FROM tomcat:8-jre8-slim
+
+ADD target/java-security-usage.war /usr/local/tomcat/webapps/
+
+EXPOSE 8080
\ No newline at end of file
diff --git a/samples/java-security-usage/README.md b/samples/java-security-usage/README.md
index eb37914e..eddfbc12 100644
--- a/samples/java-security-usage/README.md
+++ b/samples/java-security-usage/README.md
@@ -1,7 +1,83 @@
 # Description
-This sample is a Java back-end application running on the Cloud Foundry. On incoming requests it checks whether the user is authorized using the 
+This sample is a Java back-end application running on SAP Cloud Business Technology Platform. On incoming requests it checks whether the user is authorized using the 
 [`XsuaaTokenAuthenticator`](/java-security/src/main/java/com/sap/cloud/security/servlet/XsuaaTokenAuthenticator.java) which is defined in the [Java Security](../../java-security/) library.
 
+Follow the deployment steps for [Kyma/Kubernetes](#Deployment-on-Kyma/Kubernetes) or [Cloud Foundry](#Deployment-on-Cloud-Foundry).
+
+
+# Deployment on Kyma/Kubernetes
+<details>
+<summary>Expand this to follow the deployment steps</summary>
+
+- Compile the Java application
+- Build docker image and push to repository
+- Configure the deployment.yml
+- Deploy the application
+- Assign Role Collection to your user
+- Access the application
+
+## Compile the Java application
+Run maven to package the application
+```shell
+mvn clean package
+```
+## Build docker image and push to repository
+```shell script
+docker build -t <repositoryName>/<imageName> -f ./Dockerfile . 
+docker push <repositoryName>/<imageName>
+```
+
+## Configure the deployment.yml
+In deployment.yml replace the image repository placeholder `<YOUR IMAGE REPOSITORY>` with the one created in the previous step.
+
+## Deploy the application
+Deploy the application using [kubectl cli](https://kubernetes.io/docs/reference/kubectl/)
+```shell script
+kubectl apply -f ./k8s/deployment.yml -n <YOUR NAMESPACE>
+```
+
+## Cockpit administration tasks: Assign Role Collection to your user
+Finally, as part of your Identity Provider, e.g. SAP ID Service, assign the deployed Role Collection `JAVA_SECURITY_SAMPLE_Viewer` to your user as depicted in the screenshot below and as documented [here](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/9e1bf57130ef466e8017eab298b40e5e.html).
+
+![](../images/SAP_CP_Cockpit_AssignRoleCollectionToUser.png)
+
+Further up-to-date information you can get on sap.help.com:
+- [Maintain Role Collections](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/d5f1612d8230448bb6c02a7d9c8ac0d1.html)
+- [Maintain Roles for Applications](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/7596a0bdab4649ac8a6f6721dc72db19.html).
+
+## Access the application
+- Get an access token via `curl`. You can get the information to fill the placeholders from the service binding secret:
+```shell script
+kubectl get secret "xsuaa-service-binding" -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}' -n <YOUR NAMESPACE>
+```
+
+```
+curl -X POST \
+  <<url>>/oauth/token \
+  -H 'Content-Type: application/x-www-form-urlencoded' \
+  -d 'client_id=<<clientid>>&client_secret=<<clientsecret>>&grant_type=password&username=<<your username>>&password=<<your password>>'
+```
+
+Copy the `access_token` to your clipboard.
+
+- Access the app via `curl`. Don't forget to fill the placeholders.
+```
+curl -X GET \
+  https://java-security-api.<<K8S DOMAIN>>/java-security-usage/hello-java-security \
+  -H 'Authorization: Bearer <<your access_token>>'
+```
+
+You should see something like this:
+```
+You ('<your user>') can access the application with the following scopes: '<your scopes>'.
+```
+## Cleanup
+Finally, delete your application and your service instances using the following commands:
+```shell script
+ kubectl delete -f ./k8s/deployment.yml -n <YOUR NAMESPACE>
+```
+</details>
+  
 # Deployment on Cloud Foundry
 To deploy the application, the following steps are required:
 - Compile the Java application
@@ -68,7 +144,7 @@ You ('<your user>') can access the application with the following scopes: '<your
 ```
 
 ## Clean-Up
-Finally delete your application and your service instances using the following commands:
+Finally, delete your application and your service instances using the following commands:
 ```
 cf delete -f java-security-usage
 cf delete-service -f xsuaa-java-security
diff --git a/samples/java-security-usage/k8s/deployment.yml b/samples/java-security-usage/k8s/deployment.yml
new file mode 100644
index 00000000..6c391e2a
--- /dev/null
+++ b/samples/java-security-usage/k8s/deployment.yml
@@ -0,0 +1,205 @@
+---
+###  SERVICE INSTANCE CONFIGURATION  ###
+# Xsuaa instance
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceInstance
+metadata:
+  name: xsuaa-java-security
+spec:
+  clusterServiceClassExternalName: xsuaa
+  clusterServicePlanExternalName: application
+  parameters:
+    xsappname: xsuaa-java-security
+    tenant-mode: dedicated
+    scopes:
+      - name: "$XSAPPNAME.Read"
+        description: "Read Permissions."
+    role-templates:
+      - name: Viewer
+        description: View Data
+        scope-references:
+          - "$XSAPPNAME.Read"
+    role-collections:
+      - name: JAVA_SECURITY_SAMPLE_Viewer
+        description: Viewer (read)
+        role-template-references:
+          - "$XSAPPNAME.Viewer"
+---
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceBinding
+metadata:
+  name: xsuaa-service-binding
+spec:
+  instanceRef:
+    name: xsuaa-java-security
+---
+apiVersion: servicecatalog.kyma-project.io/v1alpha1
+kind: ServiceBindingUsage
+metadata:
+  name: xsuaa-service-binding-usage
+spec:
+  parameters:
+    envPrefix:
+      name: xsuaa_
+  serviceBindingRef:
+    name: xsuaa-service-binding
+  usedBy:
+    kind: deployment
+    name: java-security-usage
+---
+# Xsuaa broker instance
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceInstance
+metadata:
+  name: xsuaa-broker
+spec:
+  clusterServiceClassExternalName: xsuaa
+  clusterServicePlanExternalName: broker
+  parameters:
+    xsappname: xsuaa-broker
+    tenant-mode: dedicated
+---
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceBinding
+metadata:
+  name: xsuaa-broker-binding
+spec:
+  instanceRef:
+    name: xsuaa-broker
+---
+apiVersion: servicecatalog.kyma-project.io/v1alpha1
+kind: ServiceBindingUsage
+metadata:
+  name: xsuaa-broker-binding-usage
+spec:
+  parameters:
+    envPrefix:
+      name: xsuaa_
+  serviceBindingRef:
+    name: xsuaa-broker-binding
+  usedBy:
+    kind: deployment
+    name: java-security-usage
+---
+# Service manager instance
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceInstance
+metadata:
+  name: service-manager
+spec:
+  clusterServiceClassExternalName: service-manager
+  clusterServicePlanExternalName: subaccount-admin
+  parameters:
+---
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceBinding
+metadata:
+  name: service-manager-binding
+spec:
+  instanceRef:
+    name: service-manager
+---
+apiVersion: servicecatalog.kyma-project.io/v1alpha1
+kind: ServiceBindingUsage
+metadata:
+  name: service-manager-binding-usage
+spec:
+  parameters:
+    envPrefix:
+      name: sm_
+  serviceBindingRef:
+    name: service-manager-binding
+  usedBy:
+    kind: deployment
+    name: java-security-usage
+---
+###  APPLICATION CONFIGURATION  ###
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app: java-security-usage
+    kyma-grafana: enabled
+  name: java-security-usage
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: java-security-usage
+  template:
+    metadata:
+      labels:
+        app: java-security-usage
+        kyma-grafana: enabled
+    spec:
+      imagePullSecrets:
+        - name: sap-repo-registry
+      containers:
+        - image: <YOUR IMAGE REPOSITORY>
+          imagePullPolicy: Always
+          name: java-security-usage
+          ports:
+            - name: http
+              containerPort: 8080
+          volumeMounts:
+            - name: xsuaa
+              mountPath: "/etc/secrets/sapbtp/xsuaa/xsuaa-java-security"
+              readOnly: true
+            - name: xsuaa-broker
+              mountPath: "/etc/secrets/sapbtp/xsuaa/xsuaa-broker"
+              readOnly: true
+            - name: service-manager
+              mountPath: "/etc/secrets/sapbtp/service-manager/sm"
+              readOnly: true
+
+      volumes:
+        - name: xsuaa
+          secret:
+              secretName: xsuaa-service-binding
+        - name: xsuaa-broker
+          secret:
+              secretName: xsuaa-broker-binding
+        - name: service-manager
+          secret:
+              secretName: service-manager-binding
+---
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    app: java-security-usage
+  name: java-security-usage
+spec:
+  ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 8080
+  selector:
+    app: java-security-usage
+
+---
+apiVersion: gateway.kyma-project.io/v1alpha1
+kind: APIRule
+metadata:
+  name: java-security-api
+  labels:
+    app: java-security-usage
+spec:
+  gateway: kyma-gateway.kyma-system.svc.cluster.local
+  rules:
+    - accessStrategies:
+        - config: {}
+          handler: allow
+      methods:
+        - GET
+        - POST
+        - PUT
+        - PATCH
+        - DELETE
+        - HEAD
+      path: /.*
+  service:
+    host: java-security-api
+    name: java-security-usage
+    port: 80
\ No newline at end of file
diff --git a/samples/spring-security-basic-auth/README.md b/samples/spring-security-basic-auth/README.md
index 20dad08f..4063aafc 100644
--- a/samples/spring-security-basic-auth/README.md
+++ b/samples/spring-security-basic-auth/README.md
@@ -10,6 +10,71 @@ This is done by means of the class `BasicAuthenticationEntryPoint` in the Securi
 # Coding
 This sample is using the spring-security project. As of version 5 of spring-security, this includes the OAuth resource-server functionality. It enables caching using [`Caffeine`](https://github.com/ben-manes/caffeine) to avoid requesting new tokens from XSUAA for every incoming request.
 
+Follow the deployment steps for [Kyma/Kubernetes](#Deployment-on-Kyma/Kubernetes) or [Cloud Foundry](#Deployment-on-Cloud-Foundry).
+
+ 
+# Deployment on Kyma/Kubernetes
+<details>
+<summary>Expand this to follow the deployment steps</summary>
+  
+- Build docker image and push to repository
+- Configure the deployment.yml
+- Deploy the application
+- Assign Role Collection to your user
+- Access the application
+
+## Build docker image and push to repository
+```shell script
+mvn spring-boot:build-image -Dspring-boot.build-image.imageName=<repositoryName>/<imageName>
+docker push <repositoryName>/<imageName>
+```
+
+## Configure the deployment.yml
+In deployment.yml replace the image repository placeholder `<YOUR IMAGE REPOSITORY>` with the one created in the previous step.
+
+## Deploy the application
+Deploy the application using [kubectl cli](https://kubernetes.io/docs/reference/kubectl/)
+```shell script
+kubectl apply -f ./k8s/deployment.yml -n <YOUR NAMESPACE>
+```
+
+## Cockpit administration tasks: Assign Role Collection to your user
+Finally, as part of your Identity Provider, e.g. SAP ID Service, assign the deployed Role Collection `BASIC_AUTH_API_Viewer` to your user as depicted in the screenshot below and as documented [here](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/9e1bf57130ef466e8017eab298b40e5e.html).
+
+![](../images/SAP_CP_Cockpit_AssignRoleCollectionToUser.png)
+
+Further up-to-date information you can get on sap.help.com:
+- [Maintain Role Collections](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/d5f1612d8230448bb6c02a7d9c8ac0d1.html)
+- [Maintain Roles for Applications](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/7596a0bdab4649ac8a6f6721dc72db19.html).
+
+## Access the application
+After deployment, the spring service can be called with basic authentication.
+```shell
+curl -i --user "<SAP ID Service User>:<SAP ID Service Password>" https://spring-security-basic-auth-api.<K8s DOMAIN>/hello-token
+```
+
+You will get a response like:
+```
+{
+  "client id": "sb-spring-security-xsuaa-usage!t291",
+  "family name": "Jones",
+  "given name": "Bob",
+  "subaccount id": "2f047cc0-4364-4d8b-ae70-b8bd39d15bf0",
+  "logon name": "bob.jones@example.com",
+  "email": "bob.jones@example.com",
+  "grant type": "password",
+  "authorities": "[openid, spring-security-basic-auth!t19435.Display]",
+  "scopes": "[openid, spring-security-basic-auth!t19435.Display]"
+}
+```
+
+## Cleanup
+Finally, delete your application and your service instances using the following commands:
+```shell script
+ kubectl delete -f ./k8s/deployment.yml -n <YOUR NAMESPACE>
+```
+</details>
+
 # Deployment on Cloud Foundry
 To deploy the application, the following steps are required:
 - Compile the Java application
diff --git a/samples/spring-security-basic-auth/k8s/deployment.yml b/samples/spring-security-basic-auth/k8s/deployment.yml
new file mode 100644
index 00000000..11055983
--- /dev/null
+++ b/samples/spring-security-basic-auth/k8s/deployment.yml
@@ -0,0 +1,133 @@
+---
+###  SERVICE INSTANCE CONFIGURATION  ###
+# Xsuaa instance
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceInstance
+metadata:
+  name: xsuaa-basic
+spec:
+  clusterServiceClassExternalName: xsuaa
+  clusterServicePlanExternalName: application
+  parameters:
+    xsappname: spring-security-basic-auth
+    tenant-mode: dedicated
+    oauth2-configuration:
+      credential-types:
+        - x509
+    scopes:
+      - name: "$XSAPPNAME.Display"
+        description: With this scope, information can be read
+    role-templates:
+      - name: AccessRole
+        description: Role to call the spring-security-basic-auth service
+        scope-references:
+          - "$XSAPPNAME.Display"
+    role-collections:
+      - name: BASIC_AUTH_API_Viewer
+        description: Viewer (read)
+        role-template-references:
+          - "$XSAPPNAME.AccessRole"
+---
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceBinding
+metadata:
+  name: xsuaa-basic-binding
+spec:
+  instanceRef:
+    name: xsuaa-basic
+---
+apiVersion: servicecatalog.kyma-project.io/v1alpha1
+kind: ServiceBindingUsage
+metadata:
+  name: xsuaa-basic-binding-usage
+spec:
+  parameters:
+    envPrefix:
+      name: xsuaa_
+  serviceBindingRef:
+    name: xsuaa-basic-binding
+  usedBy:
+    kind: deployment
+    name: spring-security-basic-auth
+---
+###  APPLICATION CONFIGURATION  ###
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app: spring-security-basic-auth
+    kyma-grafana: enabled
+  name: spring-security-basic-auth
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: spring-security-basic-auth
+  template:
+    metadata:
+      labels:
+        app: spring-security-basic-auth
+        kyma-grafana: enabled
+    spec:
+      containers:
+        - image: <YOUR IMAGE REPOSITORY>
+          imagePullPolicy: Always
+          name: spring-security-basic-auth
+          ports:
+            - name: http
+              containerPort: 8080
+          volumeMounts:
+            - name: xsuaa
+              mountPath: "/etc/secrets/sapbtp/xsuaa/xsuaa-basic"
+              readOnly: true
+            - name: service-manager
+              mountPath: "/etc/secrets/sapbtp/service-manager/sm"
+              readOnly: true
+
+      volumes:
+        - name: xsuaa
+          secret:
+              secretName: xsuaa-basic-binding
+        - name: service-manager
+          secret:
+              secretName: service-manager-binding
+---
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    app: spring-security-basic-auth
+  name: spring-security-basic-auth
+spec:
+  ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 8080
+  selector:
+    app: spring-security-basic-auth
+---
+apiVersion: gateway.kyma-project.io/v1alpha1
+kind: APIRule
+metadata:
+  name: spring-security-basic-auth-api
+  labels:
+    app: spring-security-basic-auth
+spec:
+  gateway: kyma-gateway.kyma-system.svc.cluster.local
+  rules:
+    - accessStrategies:
+        - config: {}
+          handler: allow
+      methods:
+        - GET
+        - POST
+        - PUT
+        - PATCH
+        - DELETE
+        - HEAD
+      path: /.*
+  service:
+    host: spring-security-basic-auth-api
+    name: spring-security-basic-auth
+    port: 80
\ No newline at end of file
diff --git a/samples/spring-security-basic-auth/src/main/java/sample/spring/xsuaa/SecurityConfiguration.java b/samples/spring-security-basic-auth/src/main/java/sample/spring/xsuaa/SecurityConfiguration.java
index 8845b24b..e71f9da8 100644
--- a/samples/spring-security-basic-auth/src/main/java/sample/spring/xsuaa/SecurityConfiguration.java
+++ b/samples/spring-security-basic-auth/src/main/java/sample/spring/xsuaa/SecurityConfiguration.java
@@ -48,7 +48,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 		// @formatter:off
 		http.authorizeRequests()
 				.antMatchers("/hello-token").hasAuthority("Display")
-				.anyRequest().authenticated()
+				.antMatchers("/health").permitAll()
+				.anyRequest().denyAll()
 			.and()
 				.sessionManagement()
 				.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
@@ -79,5 +80,4 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 		converter.setLocalScopeAsAuthorities(true);
 		return converter;
 	}
-
 }
diff --git a/samples/spring-security-basic-auth/src/main/resources/application.yml b/samples/spring-security-basic-auth/src/main/resources/application.yml
index 5f9c42b8..68296345 100644
--- a/samples/spring-security-basic-auth/src/main/resources/application.yml
+++ b/samples/spring-security-basic-auth/src/main/resources/application.yml
@@ -2,5 +2,5 @@
 # SPDX-License-Identifier: Apache-2.0
 ---
 server:
-  port: 9999
+  port: 8080
 debug: true
\ No newline at end of file
diff --git a/samples/spring-security-hybrid-usage/Dockerfile b/samples/spring-security-hybrid-usage/Dockerfile
new file mode 100644
index 00000000..69d5d0ba
--- /dev/null
+++ b/samples/spring-security-hybrid-usage/Dockerfile
@@ -0,0 +1,6 @@
+FROM alpine:3.7
+RUN apk add --no-cache openjdk8-jre
+COPY target/spring-security-hybrid-usage.jar /app.jar
+ENTRYPOINT ["java",  "-jar", "/app.jar"]
+EXPOSE 8080
+
diff --git a/samples/spring-security-hybrid-usage/README.md b/samples/spring-security-hybrid-usage/README.md
index 7f9895c6..1495ab2c 100644
--- a/samples/spring-security-hybrid-usage/README.md
+++ b/samples/spring-security-hybrid-usage/README.md
@@ -2,10 +2,84 @@
 This spring boot application sample uses ```spring-security``` client library to validate jwt tokens issued by ```xsuaa``` service or by ```identity ``` service. On the one hand ```xsuaa``` service issues an access token and on the other hand ```identity``` service issues an oidc token. The tokens vary with regard to the information provided via token claims. In both cases the validated token is available of type [```Token```](https://github.com/SAP/cloud-security-xsuaa-integration/blob/master/java-api/src/main/java/com/sap/cloud/security/token/Token.java) via the ```SecurityContextHolder```.
 
 # Coding
-This sample is using the [`spring-security`](/spring-security/) library which bases on [Spring's Security](https://github.com/spring-projects/spring-security) project. It integrates with [Spring Security OAuth 2.0 Resource Server](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2resourceserver). The security configuration needs to configure jwt for authentication.
+This sample is using the [`spring-security`](/spring-security/) library, which is based on [Spring's Security](https://github.com/spring-projects/spring-security) project and runs on SAP Cloud Business Technology Platform. It integrates with [Spring Security OAuth 2.0 Resource Server](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2resourceserver). The security configuration needs to configure jwt for authentication.
 
 
-# Deployment To Cloud Foundry
+Follow the deployment steps for [Kyma/Kubernetes](#Deployment-on-Kyma/Kubernetes) or [Cloud Foundry](#Deployment-on-Cloud-Foundry).
+
+# Deployment on Kyma/Kubernetes
+<details>
+<summary>Expand this to follow the deployment steps</summary>
+
+- Build docker image and push to repository
+- Configure the deployment.yml
+- Deploy the application
+- Admin: Assign Role Collection to your XSUAA user
+- Admin: Assign Group to your IAS user
+- Access the application
+
+## Build docker image and push to repository
+```shell script
+mvn spring-boot:build-image -Dspring-boot.build-image.imageName=<repositoryName>/<imageName>
+docker push <repositoryName>/<imageName>
+```
+> This makes use of `Dockerfile`.
+
+## Configure the deployment.yml
+In deployment.yml replace the image repository placeholder `<YOUR IMAGE REPOSITORY>` with the one created in the previous step.
+
+## Deploy the application
+Deploy the application using [kubectl cli](https://kubernetes.io/docs/reference/kubectl/)
+```shell script
+kubectl apply -f ./k8s/deployment.yml -n <YOUR NAMESPACE>
+```
+
+## Cockpit administration task: Assign Xsuaa Role Collection to your User
+Finally, as part of your Identity Provider, e.g. SAP ID Service, assign the deployed Role Collection `XSUAA-Viewer` to your user as depicted in the screenshot below and as documented [here](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/9e1bf57130ef466e8017eab298b40e5e.html).
+
+![](../images/SAP_CP_Cockpit_AssignRoleCollectionToUser.png)
+
+Further up-to-date information you can get on sap.help.com:
+- [Maintain Role Collections](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/d5f1612d8230448bb6c02a7d9c8ac0d1.html)
+- [Maintain Roles for Applications](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/7596a0bdab4649ac8a6f6721dc72db19.html).
+
+## IAS User administration task: Assign Group to your User
+You need administrator permissions to create a Groups "Read" in IAS and assign it to your user.
+
+## Access the application
+- get an IAS oidc token via ``password`` grant token flow. For that call the ``/oauth2/token`` endpoint of your identity service. You can get the ``url`` and the ``clientid`` and ``clientsecret`` for the Basic Authorization header from the `ias-service-binding` secret.
+    ```shell script
+      kubectl get secret "ias-service-binding" -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}' -n <YOUR NAMESPACE>
+    ```
+- get a XSUAA access token via ``client-certificate`` token flow. For that, call the ``<cert_url>/oauth/token`` endpoint of your xsuaa service. <br>You can get the ``cert_url``, the ``client_id``, the ``certificate`` and ``key`` for the request from the `xsuaa-service-binding` secret.
+    ```shell script
+      kubectl get secret "xsuaa-service-binding" -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}' -n <YOUR NAMESPACE>
+    ```
+  <br> You can use Postman to retrieve the token over mTLS. To setup SSL connection:
+  
+  1. Store the certificate and key into separate files in `PEM` format.
+      <br>❗ In case you experience invalid PEM file errors, \\n characters might have to be replaced by newlines \n to have the PEM in the correct format.
+      ```shell script
+         awk '{gsub(/\\n/,"\n")}1' <file>.pem
+      ```
+  2. In Postman navigate to Settings -> Certificates, click on "Add Certificate" and provide the certificate and key `PEM` files and host name.
+          ![](../images/postman-ssl.png)
+
+In the Kyma Console, go to `<YOUR_NAMESPACE>` - `Discovery and Network` - `API Rules`. Choose the host entry for the `spring-security-hybrid-api` api rule to access the application in the browser which will produce **401** error.
+ 
+Call the following endpoints with ```Authorization``` header = "Bearer <your IAS/XSUAA token>"
+* `<HOST of spring-security-hybrid-api>/sayHello` - GET request that provides token details, but only if token provides expected read permission (scope/groups).
+* `<HOST of spring-security-hybrid-api>/method` - GET request executes a method secured with Spring Global Method Security, user requires read permission (scope/groups).
+
+
+## Cleanup
+Finally, delete your application and your service instances using the following command:
+```shell script
+ kubectl delete -f ./k8s/deployment.yml -n <YOUR NAMESPACE>
+```
+ </details>
+
+# Deployment on Cloud Foundry
 To deploy the application, the following steps are required:
 - Create a XSUAA service instance
 - Create an Identity service instance
@@ -56,7 +130,7 @@ You need administrator permissions to create a Groups "Read" in IAS and assign i
 - create an IAS oidc token via ``password`` grant token flow. For that call the ``oauth2/token`` endpoint of your identity service. You can get the ``url`` and the ``clientid`` and ``clientsecret`` for the Basic Authorization header from ``VCAP_SERVICES``.`identity`.
 - create an XSUAA access token via client-certificate token flow. For that, call the ``<cert_url>/oauth/token`` endpoint of your xsuaa service. <br>You can get the ``cert_url``, the ``client_id``, the ``certificate`` and ``key`` for the request from ``VCAP_SERVICES``.`xsuaa`.
 <br> You can use Postman to retrieve the token over mTLS. To setup SSL connection:
-    1. Store the certificate and key into seperate files in `PEM` format.
+    1. Store the certificate and key into separate files in `PEM` format.
     <br>❗ In case you experience invalid PEM file errors, \\n characters might have to be replaced by newlines \n to have the PEM in the correct format.
         ```shell script
         awk '{gsub(/\\n/,"\n")}1' <file>.pem
diff --git a/samples/spring-security-hybrid-usage/k8s/deployment.yml b/samples/spring-security-hybrid-usage/k8s/deployment.yml
new file mode 100644
index 00000000..b2cbd034
--- /dev/null
+++ b/samples/spring-security-hybrid-usage/k8s/deployment.yml
@@ -0,0 +1,166 @@
+---
+###  SERVICE INSTANCE CONFIGURATION  ###
+# Xsuaa instance
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceInstance
+metadata:
+  name: xsuaa-authn
+spec:
+  clusterServiceClassExternalName: xsuaa
+  clusterServicePlanExternalName: application
+  parameters:
+    xsappname: spring-security-hybrid-usage
+    tenant-mode: dedicated
+    oauth2-configuration:
+      credential-types:
+        - x509
+    scopes:
+      - name: "$XSAPPNAME.Read"
+        description: "Read Permissions."
+    role-templates:
+      - name: Viewer
+        description: View Data
+        scope-references:
+          - "$XSAPPNAME.Read"
+    role-collections:
+      - name: XSUAA-Viewer
+        description: Viewer (read)
+        role-template-references:
+          - "$XSAPPNAME.Viewer"
+---
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceBinding
+metadata:
+  name: xsuaa-service-binding
+spec:
+  instanceRef:
+    name: xsuaa-authn
+---
+apiVersion: servicecatalog.kyma-project.io/v1alpha1
+kind: ServiceBindingUsage
+metadata:
+  name: xsuaa-service-binding-usage
+spec:
+  parameters:
+    envPrefix:
+      name: xsuaa_
+  serviceBindingRef:
+    name: xsuaa-service-binding
+  usedBy:
+    kind: deployment
+    name: spring-security-hybrid-usage
+---
+# IAS instance
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceInstance
+metadata:
+  name: ias-authn
+spec:
+  clusterServiceClassExternalName: identity
+  clusterServicePlanExternalName: application
+---
+apiVersion: servicecatalog.k8s.io/v1beta1
+kind: ServiceBinding
+metadata:
+  name: ias-service-binding
+spec:
+  instanceRef:
+    name: ias-authn
+---
+apiVersion: servicecatalog.kyma-project.io/v1alpha1
+kind: ServiceBindingUsage
+metadata:
+  name: ias-service-binding-usage
+spec:
+  parameters:
+    envPrefix:
+      name: ias_
+  serviceBindingRef:
+    name: ias-service-binding
+  usedBy:
+    kind: deployment
+    name: spring-security-hybrid-usage
+---
+###  APPLICATION CONFIGURATION  ###
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app: spring-security-hybrid-usage
+    kyma-grafana: enabled
+  name: spring-security-hybrid-usage
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: spring-security-hybrid-usage
+  template:
+    metadata:
+      labels:
+        app: spring-security-hybrid-usage
+        kyma-grafana: enabled
+    spec:
+      containers:
+        - image: <YOUR IMAGE REPOSITORY>
+          imagePullPolicy: Always
+          name: spring-security-hybrid-usage
+          ports:
+            - name: http
+              containerPort: 8080
+          volumeMounts:
+            - name: xsuaa
+              mountPath: "/etc/secrets/sapbtp/xsuaa/xsuaa-authn"
+              readOnly: true
+            - name: ias-authn
+              mountPath: "/etc/secrets/sapbtp/identity/ias-authn"
+              readOnly: true
+
+      volumes:
+        - name: xsuaa
+          secret:
+            secretName: xsuaa-service-binding
+        - name: ias-authn
+          secret:
+            secretName: ias-service-binding
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    app: spring-security-hybrid-usage
+  name: spring-security-hybrid-usage
+spec:
+  ports:
+    - name: http
+      port: 80
+      protocol: TCP
+      targetPort: 8080
+  selector:
+    app: spring-security-hybrid-usage
+
+---
+apiVersion: gateway.kyma-project.io/v1alpha1
+kind: APIRule
+metadata:
+  name: spring-security-hybrid-api
+  labels:
+    app: spring-security-hybrid-usage
+spec:
+  gateway: kyma-gateway.kyma-system.svc.cluster.local
+  rules:
+    - accessStrategies:
+        - config: {}
+          handler: allow
+      methods:
+        - GET
+        - POST
+        - PUT
+        - PATCH
+        - DELETE
+        - HEAD
+      path: /.*
+  service:
+    host: spring-security-hybrid-api
+    name: spring-security-hybrid-usage
+    port: 80
diff --git a/samples/spring-security-hybrid-usage/src/main/java/sample/spring/security/SecurityConfiguration.java b/samples/spring-security-hybrid-usage/src/main/java/sample/spring/security/SecurityConfiguration.java
index d7ff657f..7a940090 100644
--- a/samples/spring-security-hybrid-usage/src/main/java/sample/spring/security/SecurityConfiguration.java
+++ b/samples/spring-security-hybrid-usage/src/main/java/sample/spring/security/SecurityConfiguration.java
@@ -60,7 +60,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 	class MyCustomTokenAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
 
 		public AbstractAuthenticationToken convert(Jwt jwt) {
-			if(jwt.containsClaim(TokenClaims.XSUAA.EXTERNAL_ATTRIBUTE)) {
+			if(jwt.hasClaim(TokenClaims.XSUAA.EXTERNAL_ATTRIBUTE)) {
 				return authConverter.convert(jwt);
 			}
 			return new AuthenticationToken(jwt, deriveAuthoritiesFromGroup(jwt));
@@ -68,7 +68,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
 		private Collection<GrantedAuthority> deriveAuthoritiesFromGroup(Jwt jwt) {
 			Collection<GrantedAuthority> groupAuthorities = new ArrayList<>();
-			if (jwt.containsClaim(TokenClaims.GROUPS)) {
+			if (jwt.hasClaim(TokenClaims.GROUPS)) {
 				List<String> groups = jwt.getClaimAsStringList(TokenClaims.GROUPS);
 				for (String group: groups) {
 					groupAuthorities.add(new SimpleGrantedAuthority(group.replace("IASAUTHZ_", "")));
diff --git a/spring-security/README.md b/spring-security/README.md
index 3ff6227a..f5cb98e6 100644
--- a/spring-security/README.md
+++ b/spring-security/README.md
@@ -1,6 +1,6 @@
-# SAP CP Spring Security Client Library
+# SAP BTP Spring Security Client Library
 
-Token Validation for Spring Boot applications. It integrates [```java-security```](/java-security) to Spring Security Framework to support validations for tokens issued by these SAP Cloud Platform identity services: `xsuaa` and `identity`.
+Token Validation for Spring Boot applications. It integrates [```java-security```](/java-security) to Spring Security Framework to support validations for tokens issued by these SAP Business Technology Platform identity services: `xsuaa` and `identity`.
 
 It fully integrates with [Spring Security OAuth 2.0 Resource Server](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2resourceserver).
 - The credentials from the identity services can be configured as configuration properties.
@@ -9,7 +9,7 @@ It fully integrates with [Spring Security OAuth 2.0 Resource Server](https://doc
 
 ## Supported Environments
 - Cloud Foundry
-- Planned: Kubernetes
+- Kubernetes/Kyma
 
 ## Supported Identity Services
 - XSUAA
@@ -24,6 +24,17 @@ It fully integrates with [Spring Security OAuth 2.0 Resource Server](https://doc
 
 ## Configuration
 
+### :mega: Service configuration in Kubernetes/Kyma environment 
+To access service instance configurations from the application, Kubernetes secrets need to be provided as files in a volume mounted on application's container. 
+Library will look up the configuration files in the following paths:
+- XSUAA: `/etc/secrets/sapbtp/xsuaa/<YOUR XSUAA INSTANCE NAME>`
+- IAS: `/etc/secrets/sapbtp/identity/<YOUR IAS INSTANCE NAME>`
+- Service-manager: `/etc/secrets/sapbtp/service-manager/<YOUR SERVICE-MANAGER NAME>`
+
+:exclamation: service-manager binding is mandatory to resolve multiple Xsuaa bindings! If it is not provided the first Xsuaa binding from a list is used and treated as instance with `application` plan.
+
+Detailed information on how to use ``spring-security`` library in Kubernetes/Kyma environment can be found in [spring-security-hybrid-usage](/samples/spring-security-hybrid-usage/README.md#deployment-on-kymakubernetes) sample README.
+
 ### Maven Dependencies
 These (spring) dependencies needs to be provided:
 ```xml
diff --git a/spring-security/src/main/java/com/sap/cloud/security/spring/autoconfig/SpringHttpClient.java b/spring-security/src/main/java/com/sap/cloud/security/spring/autoconfig/SpringHttpClient.java
index 6f3a0d0f..c21c3a9d 100644
--- a/spring-security/src/main/java/com/sap/cloud/security/spring/autoconfig/SpringHttpClient.java
+++ b/spring-security/src/main/java/com/sap/cloud/security/spring/autoconfig/SpringHttpClient.java
@@ -2,8 +2,6 @@ package com.sap.cloud.security.spring.autoconfig;
 
 import com.sap.cloud.security.client.HttpClientFactory;
 import com.sap.cloud.security.config.ClientIdentity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
 import org.springframework.web.client.RestTemplate;
 
@@ -15,8 +13,6 @@ import javax.annotation.Nullable;
  */
 class SpringHttpClient {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(SpringHttpClient.class);
-
 	private SpringHttpClient() {
 	}
 
diff --git a/spring-security/src/main/java/com/sap/cloud/security/spring/config/IdentityServicesPropertySourceFactory.java b/spring-security/src/main/java/com/sap/cloud/security/spring/config/IdentityServicesPropertySourceFactory.java
index 5eec7e1b..bfb4504c 100644
--- a/spring-security/src/main/java/com/sap/cloud/security/spring/config/IdentityServicesPropertySourceFactory.java
+++ b/spring-security/src/main/java/com/sap/cloud/security/spring/config/IdentityServicesPropertySourceFactory.java
@@ -7,7 +7,6 @@ package com.sap.cloud.security.spring.config;
 
 import com.sap.cloud.security.config.Environment;
 import com.sap.cloud.security.config.Environments;
-import com.sap.cloud.security.config.cf.CFEnvironment;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.core.env.PropertiesPropertySource;
@@ -60,7 +59,7 @@ public class IdentityServicesPropertySourceFactory implements PropertySourceFact
 	@Override
 	@SuppressWarnings("squid:S2259") // false positive
 	public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
-		Environment environment = CFEnvironment.getInstance();
+		Environment environment = Environments.getCurrent();
 		if (resource != null
 				&& resource.getResource().getFilename() != null && !resource.getResource().getFilename().isEmpty()) {
 			environment = Environments.readFromInput(resource.getResource().getInputStream());
diff --git a/spring-xsuaa/README.md b/spring-xsuaa/README.md
index 917b93af..54090a8b 100644
--- a/spring-xsuaa/README.md
+++ b/spring-xsuaa/README.md
@@ -6,9 +6,19 @@ This library enhances the [spring-security](https://github.com/spring-projects/s
 
 ## Configuration
 
-These (spring) dependencies needs to be provided:
+### :mega: Service configuration in Kubernetes/Kyma environment 
+To access service instance configurations from the application, Kubernetes secrets need to be provided as files in a volume mounted on application's container. 
+Library will look up the configuration files in the following paths:
+- XSUAA: `/etc/secrets/sapbtp/xsuaa/<YOUR XSUAA INSTANCE NAME>`
+- IAS: `/etc/secrets/sapbtp/identity/<YOUR IAS INSTANCE NAME>`
+- Service-manager: `/etc/secrets/sapbtp/service-manager/<YOUR SERVICE-MANAGER NAME>`
+
+:exclamation: service-manager binding is mandatory to resolve multiple Xsuaa bindings! If it is not provided the first Xsuaa binding from a list is used and treated as instance with `application` plan.
+
+Detailed information on how to use ``spring-xsuaa`` library in Kubernetes/Kyma environment can be found in [spring-security-basic-auth](/samples/spring-security-basic-auth/README.md#deployment-on-kymakubernetes) sample README.
 
 ### Maven Dependencies
+These (spring) dependencies needs to be provided:
 ```xml
 <dependency> <!-- includes spring-security-oauth2 -->
     <groupId>org.springframework.security</groupId>


Test patch:
diff --git a/env/src/test/java/com/sap/cloud/security/config/EnvironmentsK8sTest.java b/env/src/test/java/com/sap/cloud/security/config/EnvironmentsK8sTest.java
new file mode 100644
index 00000000..3960462c
--- /dev/null
+++ b/env/src/test/java/com/sap/cloud/security/config/EnvironmentsK8sTest.java
@@ -0,0 +1,39 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
+import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
+
+import static com.sap.cloud.security.config.k8s.K8sConstants.KUBERNETES_SERVICE_HOST;
+
+@ExtendWith(SystemStubsExtension.class)
+class EnvironmentsK8sTest {
+
+	private static final String K8S_HOST_VALUE = "0.0.0.0";
+
+	@Test
+	void getCurrent_returnsOnlySingleK8sInstance(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(KUBERNETES_SERVICE_HOST, K8S_HOST_VALUE);
+
+		Environment firstEnvironment = Environments.getCurrent();
+		Environment secondEnvironment = Environments.getCurrent();
+
+		Assertions.assertThat(firstEnvironment).isSameAs(secondEnvironment);
+		Assertions.assertThat(firstEnvironment.getType()).isSameAs(Environment.Type.KUBERNETES);
+	}
+
+	@Test
+	void getCurrent_returnsK8s(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(KUBERNETES_SERVICE_HOST, K8S_HOST_VALUE);
+		Environment cut = Environments.getCurrent();
+		Assertions.assertThat(cut.getType()).isEqualTo(Environment.Type.KUBERNETES);
+	}
+
+}
diff --git a/env/src/test/java/com/sap/cloud/security/config/k8s/DefaultServiceManagerServiceTest.java b/env/src/test/java/com/sap/cloud/security/config/k8s/DefaultServiceManagerServiceTest.java
new file mode 100644
index 00000000..fe202dfd
--- /dev/null
+++ b/env/src/test/java/com/sap/cloud/security/config/k8s/DefaultServiceManagerServiceTest.java
@@ -0,0 +1,46 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class DefaultServiceManagerServiceTest {
+	static DefaultServiceManagerService cut;
+
+	@BeforeAll
+	static void beforeAll() {
+		Map<String, String> serviceInstanceMap = new HashMap<>();
+		serviceInstanceMap.put("xsuaa-application", "037e7df6-5843-4174-9cb4-69a1f9a4da7e");
+		serviceInstanceMap.put("xsuaa-broker", "bb769fcb-c8b9-4612-beac-18be9743a3b7");
+
+		Map<String, String> servicePlanMap = new HashMap<>();
+		servicePlanMap.put("bb769fcb-c8b9-4612-beac-18be9743a3b7", "broker");
+		servicePlanMap.put("037e7df6-5843-4174-9cb4-69a1f9a4da7e", "application");
+		servicePlanMap.put("12345678-1234-1234-abcd-123456789123", "another-plan");
+
+		cut = mock(DefaultServiceManagerService.class);
+		when(cut.getServicePlans()).thenReturn(servicePlanMap);
+		when(cut.getServiceInstances()).thenReturn(serviceInstanceMap);
+		when(cut.getServiceInstancePlans()).thenCallRealMethod();
+	}
+
+	@Test
+	void getServiceInstancePlans() {
+		Map<String, String> instancePlans = cut.getServiceInstancePlans();
+		assertEquals(2, instancePlans.size());
+		assertEquals("application", instancePlans.get("xsuaa-application"));
+		assertEquals("broker", instancePlans.get("xsuaa-broker"));
+	}
+
+}
\ No newline at end of file
diff --git a/env/src/test/java/com/sap/cloud/security/config/k8s/K8sEnvironmentTest.java b/env/src/test/java/com/sap/cloud/security/config/k8s/K8sEnvironmentTest.java
new file mode 100644
index 00000000..2dd59c51
--- /dev/null
+++ b/env/src/test/java/com/sap/cloud/security/config/k8s/K8sEnvironmentTest.java
@@ -0,0 +1,167 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import com.sap.cloud.security.config.Environment;
+import com.sap.cloud.security.config.OAuth2ServiceConfiguration;
+import org.apache.commons.io.IOUtils;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.extension.ExtendWith;
+import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
+import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import static com.sap.cloud.security.config.k8s.K8sConstants.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@ExtendWith(SystemStubsExtension.class)
+class K8sEnvironmentTest {
+
+	private static final String K8S_HOST_VALUE = "0.0.0.0";
+	private static final WireMockServer WIREMOCK_SERVER = new WireMockServer(
+			WireMockConfiguration.wireMockConfig().port(1111));
+	private static Environment cut;
+	static String token;
+	static String serviceInstances;
+	static String servicePlans;
+
+	@BeforeAll
+	static void beforeAll(EnvironmentVariables environmentVariables) throws IOException {
+		environmentVariables.set(KUBERNETES_SERVICE_HOST, K8S_HOST_VALUE);
+		String absolutePath = new File("src/test/resources").getAbsolutePath();
+
+		environmentVariables.set(XSUAA_CONFIG_PATH, absolutePath + "/k8s/xsuaa");
+		environmentVariables.set(IAS_CONFIG_PATH, absolutePath + "/k8s/identity");
+		environmentVariables.set(SM_CONFIG_PATH, absolutePath + "/k8s/service-manager");
+
+		token = IOUtils.resourceToString("/xsuaaCCAccessTokenRSA256.txt", StandardCharsets.UTF_8);
+		serviceInstances = IOUtils.resourceToString("/k8s/serviceInstances.json", StandardCharsets.UTF_8);
+		servicePlans = IOUtils.resourceToString("/k8s/servicePlans.json", StandardCharsets.UTF_8);
+
+		WIREMOCK_SERVER.start();
+	}
+
+	@AfterEach
+	void tearDown() {
+		WIREMOCK_SERVER.resetAll();
+	}
+
+	@AfterAll
+	static void afterAll(EnvironmentVariables environmentVariables) throws Exception {
+		environmentVariables.teardown();
+		WIREMOCK_SERVER.stop();
+	}
+
+	@Test
+	void getXsuaaConfiguration() {
+		WIREMOCK_SERVER.stubFor(
+				WireMock.post("/oauth/token").willReturn(WireMock.ok().withHeader("Content-Type", "application/json")
+						.withBody("{\"access_token\": \"" + token + "\",  \"expires_in\": 1799}")));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_plans")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(servicePlans)));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_instances")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(serviceInstances)));
+
+		cut = K8sEnvironment.getInstance();
+		OAuth2ServiceConfiguration config = cut.getXsuaaConfiguration();
+		assertEquals("xsuaaClientId", config.getClientId());
+	}
+
+	@Test
+	void getIasConfiguration() {
+		WIREMOCK_SERVER.stubFor(
+				WireMock.post("/oauth/token").willReturn(WireMock.ok().withHeader("Content-Type", "application/json")
+						.withBody("{\"access_token\": \"" + token + "\",  \"expires_in\": 1799}")));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_plans")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(servicePlans)));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_instances")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(serviceInstances)));
+
+		cut = K8sEnvironment.getInstance();
+		OAuth2ServiceConfiguration config = cut.getIasConfiguration();
+		assertEquals("iasClientId2", config.getClientId());
+		assertEquals("domain1.sap.com", config.getDomains().get(0));
+		assertEquals("domain2.sap.com", config.getDomains().get(1));
+		assertEquals("sec\\\"re?%$@#t\"='`", config.getClientSecret());
+	}
+
+	@Test
+	void getNumberOfXsuaaConfigurations() {
+		WIREMOCK_SERVER.stubFor(
+				WireMock.post("/oauth/token").willReturn(WireMock.ok().withHeader("Content-Type", "application/json")
+						.withBody("{\"access_token\": \"" + token + "\",  \"expires_in\": 1799}")));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_plans")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(servicePlans)));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_instances")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(serviceInstances)));
+
+		cut = K8sEnvironment.getInstance();
+		assertEquals(2, cut.getNumberOfXsuaaConfigurations());
+	}
+
+	@Test
+	void getXsuaaConfigurationForTokenExchange() {
+		WIREMOCK_SERVER.stubFor(
+				WireMock.post("/oauth/token").willReturn(WireMock.ok().withHeader("Content-Type", "application/json")
+						.withBody("{\"access_token\": \"" + token + "\",  \"expires_in\": 1799}")));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_plans")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(servicePlans)));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_instances")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(serviceInstances)));
+
+		cut = K8sEnvironment.getInstance();
+		OAuth2ServiceConfiguration config = cut.getXsuaaConfigurationForTokenExchange();
+		assertEquals("xsuaaBrokerClientId", config.getClientId());
+	}
+
+	@Disabled("Doesn't work with Surefire plugin, can be tested in IDE with test config forkMode=method")
+	@Test
+	void getXsuaaConfiguration_smCallFails() {
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_plans")
+				.willReturn(WireMock.unauthorized()));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_instances")
+				.willReturn(WireMock.unauthorized()));
+
+		cut = K8sEnvironment.getInstance();
+		OAuth2ServiceConfiguration config = cut.getXsuaaConfiguration();
+		assertEquals("xsuaaClientId", config.getClientId());
+		assertEquals(1, cut.getNumberOfXsuaaConfigurations());
+	}
+
+	@Disabled("Doesn't work with Surefire plugin, can be tested in IDE with test config forkMode=method")
+	@Test
+	void getXsuaaConfiguration_smCallFails_noServiceInstances() {
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_instances")
+				.willReturn(WireMock.badRequest()));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_plans")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(servicePlans)));
+
+		cut = K8sEnvironment.getInstance();
+		OAuth2ServiceConfiguration config = cut.getXsuaaConfiguration();
+		assertEquals("xsuaaClientId", config.getClientId());
+		assertEquals(1, cut.getNumberOfXsuaaConfigurations());
+	}
+
+	@Disabled("Doesn't work with Surefire plugin, can be tested in IDE with test config forkMode=method")
+	@Test
+	void getXsuaaConfiguration_smCallFails_noServicePlans() {
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_plans")
+				.willReturn(WireMock.badRequest()));
+		WIREMOCK_SERVER.stubFor(WireMock.get("/v1/service_instances")
+				.willReturn(WireMock.ok().withHeader("Content-Type", "application/json").withBody(serviceInstances)));
+
+		cut = K8sEnvironment.getInstance();
+		OAuth2ServiceConfiguration config = cut.getXsuaaConfiguration();
+		assertEquals("xsuaaClientId", config.getClientId());
+		assertEquals(1, cut.getNumberOfXsuaaConfigurations());
+	}
+}
\ No newline at end of file
diff --git a/env/src/test/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationProviderTest.java b/env/src/test/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationProviderTest.java
new file mode 100644
index 00000000..07965016
--- /dev/null
+++ b/env/src/test/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationProviderTest.java
@@ -0,0 +1,124 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import com.sap.cloud.security.config.OAuth2ServiceConfiguration;
+import com.sap.cloud.security.config.Service;
+import nl.altindag.log.LogCaptor;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mockito;
+import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
+import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.sap.cloud.security.config.k8s.K8sConstants.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(SystemStubsExtension.class)
+class K8sServiceConfigurationProviderTest {
+
+	private static final String ABSOLUTE_PATH = new File("src/test/resources").getAbsolutePath();
+	private static K8sServiceConfigurationProvider cut;
+	private static DefaultServiceManagerService smMock;
+	private static LogCaptor logCaptor;
+
+	@BeforeAll
+	static void beforeAll() {
+		logCaptor = LogCaptor.forClass(K8sServiceConfigurationProvider.class);
+	}
+
+	@AfterEach
+	void tearDown() {
+		logCaptor.clearLogs();
+	}
+
+	@BeforeEach
+	void beforeEach(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(XSUAA_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/xsuaa");
+		environmentVariables.set(IAS_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/identity");
+		environmentVariables.set(SM_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/service-manager");
+		Map<String, String> serviceInstancePlanMap = new HashMap<>();
+		serviceInstancePlanMap.put("xsuaa-application", "application");
+		serviceInstancePlanMap.put("xsuaa-broker", "broker");
+
+		smMock = Mockito.mock(DefaultServiceManagerService.class);
+		when(smMock.getServiceInstancePlans()).thenReturn(serviceInstancePlanMap);
+
+		cut = new K8sServiceConfigurationProvider();
+		cut.setServiceManagerClient(smMock);
+	}
+
+	@Test
+	void getServiceConfigurations() {
+		EnumMap<Service, Map<String, OAuth2ServiceConfiguration>> serviceConfig = cut
+				.getServiceConfigurations();
+		assertThat(serviceConfig).hasSize(2);
+		assertThat(serviceConfig.get(Service.XSUAA)).hasSize(2);
+		assertThat(serviceConfig.get(Service.IAS)).hasSize(2);
+		assertThat(serviceConfig.get(Service.XSUAA).get(Plan.APPLICATION.toString())).isNotNull();
+		assertThat(serviceConfig.get(Service.XSUAA).get(Plan.BROKER.toString())).isNotNull();
+		assertThat(serviceConfig.get(Service.XSUAA).get(Plan.DEFAULT.toString())).isNull();
+	}
+
+	@Test
+	void getServiceConfigurations_noXsuaaPlansAvailable() {
+		when(smMock.getServiceInstancePlans()).thenReturn(Collections.emptyMap());
+		EnumMap<Service, Map<String, OAuth2ServiceConfiguration>> serviceConfig = cut
+				.getServiceConfigurations();
+
+		assertThat(serviceConfig.get(Service.XSUAA)).isNotNull();
+		assertThat(serviceConfig.get(Service.XSUAA)).hasSize(1);
+		assertThat(serviceConfig.get(Service.XSUAA).get(Plan.APPLICATION.toString())).isNotNull();
+		assertThat(logCaptor.getWarnLogs().get(0))
+				.startsWith("No plans or instances were fetched from service manager");
+	}
+
+	@Test
+	void getServiceConfigurations_noSmClient() {
+		cut.setServiceManagerClient(null);
+		EnumMap<Service, Map<String, OAuth2ServiceConfiguration>> serviceConfig = cut.getServiceConfigurations();
+
+		assertThat(serviceConfig.get(Service.XSUAA)).isNotNull();
+		assertThat(serviceConfig.get(Service.XSUAA)).hasSize(1);
+		assertThat(serviceConfig.get(Service.XSUAA).get(Plan.APPLICATION.toString())).isNotNull();
+		assertThat(logCaptor.getWarnLogs().get(0)).startsWith("No service-manager client available");
+	}
+
+	@Test
+	void getServiceConfigurations_noServiceBindingsAvailable(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(XSUAA_CONFIG_PATH, ABSOLUTE_PATH + "/no/binding");
+		environmentVariables.set(IAS_CONFIG_PATH, ABSOLUTE_PATH + "/no/binding");
+		environmentVariables.set(SM_CONFIG_PATH, ABSOLUTE_PATH + "/no/binding");
+
+		cut = new K8sServiceConfigurationProvider();
+
+		EnumMap<Service, Map<String, OAuth2ServiceConfiguration>> serviceConfig = cut.getServiceConfigurations();
+		assertThat(serviceConfig).hasSize(2);
+		assertThat(serviceConfig.get(Service.XSUAA)).isEmpty();
+		assertThat(serviceConfig.get(Service.IAS)).isEmpty();
+	}
+
+	@Test
+	void getServiceConfiguration_singleXsuaa(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(XSUAA_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/xsuaa-single");
+
+		cut = new K8sServiceConfigurationProvider();
+		EnumMap<Service, Map<String, OAuth2ServiceConfiguration>> serviceConfig = cut.getServiceConfigurations();
+		assertThat(serviceConfig.get(Service.XSUAA)).hasSize(1);
+		assertThat(logCaptor.getInfoLogs().get(0)).startsWith("Assigning 'application' plan");
+		assertThat(logCaptor.getWarnLogs()).isEmpty();
+	}
+}
\ No newline at end of file
diff --git a/env/src/test/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationResolverTest.java b/env/src/test/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationResolverTest.java
new file mode 100644
index 00000000..fc173972
--- /dev/null
+++ b/env/src/test/java/com/sap/cloud/security/config/k8s/K8sServiceConfigurationResolverTest.java
@@ -0,0 +1,110 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.config.k8s;
+
+import com.sap.cloud.security.config.OAuth2ServiceConfiguration;
+import com.sap.cloud.security.config.Service;
+import nl.altindag.log.LogCaptor;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
+import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
+
+import java.io.File;
+import java.util.Map;
+
+import static com.sap.cloud.security.config.k8s.K8sConstants.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+@ExtendWith(SystemStubsExtension.class)
+class K8sServiceConfigurationResolverTest {
+
+	private static K8sServiceConfigurationResolver cut;
+	public static final String ABSOLUTE_PATH = new File("src/test/resources").getAbsolutePath();
+	private static LogCaptor logCaptor;
+
+	@BeforeAll
+	static void beforeAll() {
+		logCaptor = LogCaptor.forClass(K8sServiceConfigurationResolver.class);
+	}
+
+	@AfterEach
+	void tearDown() {
+		logCaptor.clearLogs();
+	}
+
+	@Test
+	void loadServiceManagerConfig(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(SM_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/service-manager");
+		cut = new K8sServiceConfigurationResolver();
+
+		assertEquals("smClientId", cut.loadServiceManagerConfig().getClientId());
+	}
+
+	@Test
+	void loadOauth2ServiceConfig(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(XSUAA_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/xsuaa");
+		environmentVariables.set(IAS_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/identity");
+		cut = new K8sServiceConfigurationResolver();
+
+		assertEquals(2, cut.loadOauth2ServiceConfig(Service.XSUAA).size());
+		assertEquals(2, cut.loadOauth2ServiceConfig(Service.IAS).size());
+		assertEquals("xsuaaClientId",
+				cut.loadOauth2ServiceConfig(Service.XSUAA).get("xsuaa-application").getClientId());
+		assertEquals("xsuaaBrokerClientId",
+				cut.loadOauth2ServiceConfig(Service.XSUAA).get("xsuaa-broker").getClientId());
+		assertEquals("iasClientId", cut.loadOauth2ServiceConfig(Service.IAS).get("ias1").getClientId());
+		assertEquals("iasClientId2", cut.loadOauth2ServiceConfig(Service.IAS).get("ias2").getClientId());
+	}
+
+	@Test
+	void loadOAuth2ServiceConfig_noValidXsuaaServiceBinding(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(XSUAA_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/xsuaa-invalid");
+		cut = new K8sServiceConfigurationResolver();
+		Map<String, OAuth2ServiceConfiguration> xsuaaConfig = cut.loadOauth2ServiceConfig(Service.XSUAA);
+
+		assertEquals(1, xsuaaConfig.size());
+		assertThat(logCaptor.getInfoLogs()).contains("Found 3 XSUAA service binding/s");
+		assertEquals("clientId", xsuaaConfig.get("xsuaa-folder-file").getClientId());
+		assertNull(xsuaaConfig.get("xsuaa-folder-file").getClientSecret());
+		assertThat(logCaptor.getWarnLogs()).contains("clientid value is empty");
+		assertDoesNotThrow(() -> cut.loadOauth2ServiceConfig(Service.XSUAA));
+	}
+
+	@Test
+	void loadOAuth2ServiceConfig_noIasServiceBinding(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(IAS_CONFIG_PATH, "/no/path");
+		cut = new K8sServiceConfigurationResolver();
+		Map<String, OAuth2ServiceConfiguration> iasConfig = cut.loadOauth2ServiceConfig(Service.IAS);
+
+		assertEquals(0, iasConfig.size());
+		assertThat(logCaptor.getWarnLogs()).contains("No service bindings for IAS service were found");
+		assertDoesNotThrow(() -> cut.loadOauth2ServiceConfig(Service.IAS));
+	}
+
+	@Test
+	void loadOAuth2ServiceConfig_noXsuaaServiceBinding(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(XSUAA_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/xsuaa-no-bindings");
+		cut = new K8sServiceConfigurationResolver();
+
+		assertDoesNotThrow(() -> cut.loadOauth2ServiceConfig(Service.XSUAA));
+		assertThat(logCaptor.getWarnLogs()).contains("No service bindings for XSUAA service were found");
+		assertEquals(0, cut.loadOauth2ServiceConfig(Service.XSUAA).size());
+	}
+
+	@Test
+	void loadOAuth2ServiceConfig_singleXsuaaServiceBinding(EnvironmentVariables environmentVariables) {
+		environmentVariables.set(XSUAA_CONFIG_PATH, ABSOLUTE_PATH + "/k8s/xsuaa-single");
+		cut = new K8sServiceConfigurationResolver();
+
+		assertDoesNotThrow(() -> cut.loadOauth2ServiceConfig(Service.XSUAA));
+		assertThat(logCaptor.getInfoLogs()).contains("Found 1 XSUAA service binding/s");
+		assertEquals(1, cut.loadOauth2ServiceConfig(Service.XSUAA).size());
+	}
+}
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/identity/ias1/clientid b/env/src/test/resources/k8s/identity/ias1/clientid
new file mode 100644
index 00000000..ad064933
--- /dev/null
+++ b/env/src/test/resources/k8s/identity/ias1/clientid
@@ -0,0 +1,1 @@
+iasClientId
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/identity/ias2/clientid b/env/src/test/resources/k8s/identity/ias2/clientid
new file mode 100644
index 00000000..adbdfa97
--- /dev/null
+++ b/env/src/test/resources/k8s/identity/ias2/clientid
@@ -0,0 +1,1 @@
+iasClientId2
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/identity/ias2/clientsecret b/env/src/test/resources/k8s/identity/ias2/clientsecret
new file mode 100644
index 00000000..edf46358
--- /dev/null
+++ b/env/src/test/resources/k8s/identity/ias2/clientsecret
@@ -0,0 +1,1 @@
+sec\"re?%$@#t"='`
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/identity/ias2/domains b/env/src/test/resources/k8s/identity/ias2/domains
new file mode 100644
index 00000000..f31cb550
--- /dev/null
+++ b/env/src/test/resources/k8s/identity/ias2/domains
@@ -0,0 +1,1 @@
+["domain1.sap.com", "domain2.sap.com"]
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/service-manager/sm/clientid b/env/src/test/resources/k8s/service-manager/sm/clientid
new file mode 100644
index 00000000..7389157a
--- /dev/null
+++ b/env/src/test/resources/k8s/service-manager/sm/clientid
@@ -0,0 +1,1 @@
+smClientId
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/service-manager/sm/clientsecret b/env/src/test/resources/k8s/service-manager/sm/clientsecret
new file mode 100644
index 00000000..7300d932
--- /dev/null
+++ b/env/src/test/resources/k8s/service-manager/sm/clientsecret
@@ -0,0 +1,1 @@
+smClientSecret
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/service-manager/sm/sm_url b/env/src/test/resources/k8s/service-manager/sm/sm_url
new file mode 100644
index 00000000..c7b7e767
--- /dev/null
+++ b/env/src/test/resources/k8s/service-manager/sm/sm_url
@@ -0,0 +1,1 @@
+http://localhost:1111
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/service-manager/sm/url b/env/src/test/resources/k8s/service-manager/sm/url
new file mode 100644
index 00000000..c7b7e767
--- /dev/null
+++ b/env/src/test/resources/k8s/service-manager/sm/url
@@ -0,0 +1,1 @@
+http://localhost:1111
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/service-manager/sm/xsappname b/env/src/test/resources/k8s/service-manager/sm/xsappname
new file mode 100644
index 00000000..ae94e515
--- /dev/null
+++ b/env/src/test/resources/k8s/service-manager/sm/xsappname
@@ -0,0 +1,1 @@
+service-manager
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/serviceInstances.json b/env/src/test/resources/k8s/serviceInstances.json
new file mode 100644
index 00000000..c3077cc0
--- /dev/null
+++ b/env/src/test/resources/k8s/serviceInstances.json
@@ -0,0 +1,92 @@
+{
+  "num_items": 3,
+  "items": [
+    {
+      "id": "1307a163-b5cf-4c2c-8714-13ba5f072012",
+      "ready": true,
+      "name": "xsuaa-application",
+      "service_plan_id": "037e7df6-5843-4174-9cb4-69a1f9a4da7e",
+      "platform_id": "",
+      "context": {
+        "clusterid": "",
+        "instance_name": "xsuaa-application",
+        "namespace": "dev",
+        "platform": "sapcp",
+        "zone_id": "",
+        "global_account_id": "sap",
+        "subdomain": "",
+        "crm_customer_id": "",
+        "origin": "kubernetes",
+        "license_type": "SAPDEV",
+        "subaccount_id": "",
+        "region": ""
+      },
+      "usable": true,
+      "created_at": "2021-07-14T13:58:07.067851Z",
+      "updated_at": "2021-07-14T13:58:07.067851Z",
+      "labels": {
+        "subaccount_id": [
+          ""
+        ]
+      }
+    },
+    {
+      "id": "73643785-56da-4165-b6b3-d13cc571be7f",
+      "ready": true,
+      "name": "xsuaa-broker",
+      "service_plan_id": "bb769fcb-c8b9-4612-beac-18be9743a3b7",
+      "platform_id": "",
+      "context": {
+        "clusterid": "",
+        "instance_name": "xsuaa-broker",
+        "namespace": "dev",
+        "platform": "sapcp",
+        "subdomain": "",
+        "region": "",
+        "crm_customer_id": "",
+        "global_account_id": "sap",
+        "license_type": "SAPDEV",
+        "subaccount_id": "",
+        "origin": "kubernetes",
+        "zone_id": ""
+      },
+      "usable": true,
+      "created_at": "2021-07-28T12:06:34.34308Z",
+      "updated_at": "2021-07-28T12:06:34.34308Z",
+      "labels": {
+        "subaccount_id": [
+          ""
+        ]
+      }
+    },
+    {
+      "id": "d3c68611-c8a0-4c96-ac0c-1edd0ac3d2ef",
+      "ready": true,
+      "name": "service-manager",
+      "service_plan_id": "ca8adb0e-d560-41aa-bf63-12ec2af02035",
+      "platform_id": "",
+      "context": {
+        "clusterid": "",
+        "instance_name": "service-manager",
+        "namespace": "dev",
+        "platform": "sapcp",
+        "zone_id": "",
+        "crm_customer_id": "",
+        "subdomain": "",
+        "region": "",
+        "origin": "kubernetes",
+        "global_account_id": "sap",
+        "license_type": "SAPDEV",
+        "subaccount_id": ""
+      },
+      "usable": true,
+      "created_at": "2021-07-28T15:19:20.17765Z",
+      "updated_at": "2021-07-28T15:19:20.17765Z",
+      "labels": {
+        "subaccount_id": [
+          ""
+        ]
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/servicePlans.json b/env/src/test/resources/k8s/servicePlans.json
new file mode 100644
index 00000000..a1b23f2b
--- /dev/null
+++ b/env/src/test/resources/k8s/servicePlans.json
@@ -0,0 +1,120 @@
+{
+  "num_items": 3,
+  "items": [
+    {
+      "id": "037e7df6-5843-4174-9cb4-69a1f9a4da7e",
+      "ready": true,
+      "name": "application",
+      "description": "Application plan to be used for business applications",
+      "catalog_id": "ThGdx5loQ6XhvcdY6dLlEXcTgQD7641pDKXJfzwYGLg=",
+      "catalog_name": "application",
+      "free": true,
+      "bindable": true,
+      "metadata": {
+        "supportedPlatforms": [
+          "cloudfoundry",
+          "sapcp",
+          "kubernetes"
+        ],
+        "supportedMinOSBVersion": "2.11",
+        "sibling_resolution": {
+          "resolution_property": "siblingIds",
+          "name_paths": [
+            "scopes.#.granted-apps",
+            "scopes.#.grant-as-authority-to-apps",
+            "foreign-scope-references",
+            "authorities",
+            "role-collections.#.role-template-references"
+          ],
+          "value_regexp": "\\$XSSERVICENAME\\((.*)\\)",
+          "enabled": true
+        },
+        "bullets": [
+          "Tenant isolation",
+          "Supports different OAuth flows (Client credentials, authorization code, SAML bearer assertion)",
+          "One OAuth client per service instance"
+        ],
+        "supportedMaxOSBVersion": "2.14"
+      },
+      "service_offering_id": "a3199d59-3fdc-41f5-a258-8ea36ff26762",
+      "created_at": "2019-06-26T13:51:49.854908Z",
+      "updated_at": "2021-08-02T09:32:35.244776Z",
+      "labels": {
+        "complementary": [
+          "true"
+        ]
+      }
+    },
+    {
+      "id": "bb769fcb-c8b9-4612-beac-18be9743a3b7",
+      "ready": true,
+      "name": "broker",
+      "description": "Broker plan to be used by business reuse services / service brokers",
+      "catalog_id": "HWEgt9/jJGFjzT8j+/x9pGivrAuKbUMUK8PgWEx3cLY=",
+      "catalog_name": "broker",
+      "free": true,
+      "bindable": true,
+      "metadata": {
+        "supportedPlatforms": [
+          "cloudfoundry",
+          "sapcp",
+          "kubernetes"
+        ],
+        "supportedMinOSBVersion": "2.11",
+        "sibling_resolution": {
+          "resolution_property": "siblingIds",
+          "name_paths": [
+            "scopes.#.granted-apps",
+            "scopes.#.grant-as-authority-to-apps",
+            "foreign-scope-references",
+            "authorities",
+            "role-collections.#.role-template-references"
+          ],
+          "value_regexp": "\\$XSSERVICENAME\\((.*)\\)",
+          "enabled": true
+        },
+        "bullets": [
+          "Tenant isolation",
+          "Supports different OAuth flows (Client credentials, user token)",
+          "One OAuth client for the reuse service itself + one per instance of the reuse service"
+        ],
+        "supportedMaxOSBVersion": "2.14"
+      },
+      "service_offering_id": "a3199d59-3fdc-41f5-a258-8ea36ff26762",
+      "created_at": "2019-06-26T13:51:49.854908Z",
+      "updated_at": "2021-08-02T09:32:35.190203Z",
+      "labels": {
+        "complementary": [
+          "true"
+        ]
+      }
+    },
+    {
+      "id": "b0fd827c-2391-4619-bfb8-56b8b1dc197b",
+      "ready": true,
+      "name": "application",
+      "description": "Register an application into your Identity Authentication tenant",
+      "catalog_id": "86af6685-7bae-40b8-b564-378284c8fcc9",
+      "catalog_name": "application",
+      "free": true,
+      "bindable": true,
+      "metadata": {
+        "sibling_resolution": {
+          "names_path": "consumed-services.#.service-instance-name",
+          "resolution_property": "siblingIds",
+          "enabled": true
+        },
+        "supportedMinOSBVersion": "2.11",
+        "supportedMaxOSBVersion": "2.15"
+      },
+      "service_offering_id": "b518cc1f-8523-4331-b7a1-d6f196854b05",
+      "created_at": "2020-10-28T11:53:29.219855Z",
+      "updated_at": "2021-08-02T09:25:26.195847Z",
+      "labels": {
+        "commercial_name": [
+          "application"
+        ]
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa-invalid/fileInsteadOfFolder b/env/src/test/resources/k8s/xsuaa-invalid/fileInsteadOfFolder
new file mode 100644
index 00000000..e69de29b
diff --git a/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-folder-file/clientid b/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-folder-file/clientid
new file mode 100644
index 00000000..9b640fd5
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-folder-file/clientid
@@ -0,0 +1,1 @@
+clientId
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-no-file-content/clientid b/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-no-file-content/clientid
new file mode 100644
index 00000000..e69de29b
diff --git a/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-no-file-content/xsappname b/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-no-file-content/xsappname
new file mode 100644
index 00000000..e69de29b
diff --git a/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-wrong-tree-structure/clientid/clientid b/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-wrong-tree-structure/clientid/clientid
new file mode 100644
index 00000000..7a9df4f6
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa-invalid/xsuaa-wrong-tree-structure/clientid/clientid
@@ -0,0 +1,1 @@
+myClientId
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/clientid b/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/clientid
new file mode 100644
index 00000000..1e9e7e0a
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/clientid
@@ -0,0 +1,1 @@
+xsuaaClientId
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/clientsecret b/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/clientsecret
new file mode 100644
index 00000000..6430bd24
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/clientsecret
@@ -0,0 +1,1 @@
+xsuaaSecret
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/url b/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/url
new file mode 100644
index 00000000..d064b73f
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/url
@@ -0,0 +1,1 @@
+https://auth.sap.com
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/xsappname b/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/xsappname
new file mode 100644
index 00000000..1e73b8cc
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa-single/xsuaa-application/xsappname
@@ -0,0 +1,1 @@
+xsuaa-basic
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa/xsuaa-application/clientid b/env/src/test/resources/k8s/xsuaa/xsuaa-application/clientid
new file mode 100644
index 00000000..1e9e7e0a
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa/xsuaa-application/clientid
@@ -0,0 +1,1 @@
+xsuaaClientId
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa/xsuaa-application/clientsecret b/env/src/test/resources/k8s/xsuaa/xsuaa-application/clientsecret
new file mode 100644
index 00000000..6430bd24
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa/xsuaa-application/clientsecret
@@ -0,0 +1,1 @@
+xsuaaSecret
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa/xsuaa-application/url b/env/src/test/resources/k8s/xsuaa/xsuaa-application/url
new file mode 100644
index 00000000..d064b73f
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa/xsuaa-application/url
@@ -0,0 +1,1 @@
+https://auth.sap.com
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa/xsuaa-application/xsappname b/env/src/test/resources/k8s/xsuaa/xsuaa-application/xsappname
new file mode 100644
index 00000000..1e73b8cc
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa/xsuaa-application/xsappname
@@ -0,0 +1,1 @@
+xsuaa-basic
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa/xsuaa-broker/clientid b/env/src/test/resources/k8s/xsuaa/xsuaa-broker/clientid
new file mode 100644
index 00000000..cec4c49b
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa/xsuaa-broker/clientid
@@ -0,0 +1,1 @@
+xsuaaBrokerClientId
\ No newline at end of file
diff --git a/env/src/test/resources/k8s/xsuaa/xsuaa-broker/xsappname b/env/src/test/resources/k8s/xsuaa/xsuaa-broker/xsappname
new file mode 100644
index 00000000..1a624d75
--- /dev/null
+++ b/env/src/test/resources/k8s/xsuaa/xsuaa-broker/xsappname
@@ -0,0 +1,1 @@
+xsuaa-broker
\ No newline at end of file
diff --git a/env/src/test/resources/xsuaaCCAccessTokenRSA256.txt b/env/src/test/resources/xsuaaCCAccessTokenRSA256.txt
new file mode 100644
index 00000000..8a4ca5bc
--- /dev/null
+++ b/env/src/test/resources/xsuaaCCAccessTokenRSA256.txt
@@ -0,0 +1,1 @@
+eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHBzOi8vYXV0aGVudGljYXRpb24uc3RhZ2luZ2F3cy5oYW5hdmxhYi5vbmRlbWFuZC5jb20vdG9rZW5fa2V5cyIsImtpZCI6ImtleS1pZC0xIiwidHlwIjoiSldUIn0.eyJqdGkiOiIyYTZiNDcxODJjZTM0YzgzYTNjNDY0MWI1NTZiOTQ2YyIsImV4dF9hdHRyIjp7ImVuaGFuY2VyIjoiWFNVQUEifSwic3ViIjoic2FwX29zYiIsImF1dGhvcml0aWVzIjpbInVhYS5yZXNvdXJjZSIsIlJPTEVfU0VSVklDRUJST0tFUiJdLCJzY29wZSI6WyJST0xFX1NFUlZJQ0VCUk9LRVIiLCJ1YWEucmVzb3VyY2UiXSwiY2xpZW50X2lkIjoic2FwX29zYiIsImNpZCI6InNhcF9vc2IiLCJhenAiOiJzYXBfb3NiIiwiZ3JhbnRfdHlwZSI6ImNsaWVudF9jcmVkZW50aWFscyIsInJldl9zaWciOiJiMjNhNzJkYyIsImlhdCI6MTU3MjAxNzU2OSwiZXhwIjoxNTcyMDYwNzY5LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvdWFhL29hdXRoL3Rva2VuIiwiemlkIjoidWFhIiwiYXVkIjpbInVhYSIsInNhcF9vc2IiXX0.OLDZiMerzH4gNELQEHCPUy7aD681L-twKYyfRSuNQAvlEeQeMaQm7_ZX3WrQ7HF04PASSocBkebG4PmFcbzX5uRSxoxUPbPB1JFsdbb_MU5o0P-xbYStY_lL0UVcZsSy2QrZwcNgtdTbHXpme2xn3jjW6KdwfO6Zd19fcPpPdstlmp34uUFBGfSkXek5sRDCw3ZklEStYIQG9dYsxEq-AmtEqsgPjVdFWv6_bfe8HqOoNfx1QC31DNNQQiAZBFFuZ3iX7IQWRHMdVjWw5GF7tvxM8al-wt8flaZ6gBvHTGzwGKBlDZYtKMDO57L5SyFCgwedoRdzE2NHIHvvp3CKEw
\ No newline at end of file
diff --git a/samples/spring-security-basic-auth/src/main/java/sample/spring/xsuaa/TestController.java b/samples/spring-security-basic-auth/src/main/java/sample/spring/xsuaa/TestController.java
index b82dc33d..6e718702 100644
--- a/samples/spring-security-basic-auth/src/main/java/sample/spring/xsuaa/TestController.java
+++ b/samples/spring-security-basic-auth/src/main/java/sample/spring/xsuaa/TestController.java
@@ -32,4 +32,9 @@ public class TestController {
 		result.put("scopes", String.valueOf(token.getScopes()));
 		return result;
 	}
+
+	@GetMapping("/health")
+	public String checkHealth(){
+		return "OK";
+	}
 }